Probaste desactivando el WDT al menos para hacer las pruebas?, tambien probaste la rutina de interrupcion solamente ?
Para que hacer una funcion asi?
decodificar_trama(pos,temp[pos])
y llamarla asi:
for(pos=0;pos<=br-1;pos++){decodificar_trama(pos,temp[pos]);}
Cuando directamente podes poner
for(pos=0;pos<br;pos++){brr[pos]=temp[pos];}
---------------------
Tu rutina de interrupcion me parece que esta mal, hay varias cosas que no me convencen
void RDA_isr(void){
RESTART_WDT();
OUTPUT_BIT(LED2,LON);
br++;
if(br==1){
dato=temp[0];
if(dato!=0x7E){
temp[0]=0;
br=0;
recep=0;
}
}
if(br==3){
tam_tram=temp[2];
tamano=tam_tram+3;
}
if(br<tamano){recep=0;}
else if(br==tamano){recep=1;}
}
Nunca pero NUNCA resetea br, el unico momento que resetea br es cuando el primer dato que llega es distinto a 0x7E, a partir de ahi cuando se cumple eso, br sigue y sigue y sigue y sigue incrementandose.
Hasta el punto de poder llegar hasta 255, haciendo temp[255] lo cual no es valido y recien ahi llegar a 0 Si es que en tu main se tarda mas de la cuenta.
PD: Veo que en tu main reseteas br, eso no lo podes hacer, por que si viene otra trama estarias dejandola pasar por ese "delay" hasta que se hacen todas las funciones del main y encima se procesan los datos.
if(br<tamano){recep=0;}
else if(br==tamano){recep=1;}
Reemplazar eso por un:
if(br==tamano){recep=1; copiar_datos(); br=0;}
Ahi cuando se termina de recibir deberias copiar tus datos al otro array ( asi tener los datos listos ) activar el flag como lo hiciste, para saber que hay datos a ver, y volver a poner a 0 br. Asi prepararse para la llegada de nuevos datos
el flag de recep te debe indicar si hay datos listos para "tratar",
Si no me entendiste te doy un ejemplo, imaginate la rutina de interrupcion como un cartero, Comienzan a llegar cartas(cada byte) de un envio(trama) (el sabe cuantas deben llegar) y solo te avisa cuando estan todas las cartas ahi de ese envio.
Mientras sigue recibiendo las cartas del otro envio (sabiendo que pertenece a otra trama).
Vos cuando estan te aviza que estan listas vas y retiras todo el pedido (trama).
Aca puede ocurrir que al seguir juntando cartas llegue a haber 2 pedidos enteros para vos y vos no pasate a buscarlo, pero solo tiene lugar para uno.. Vos le diras a ese cartero que debe hacer, si tirar el ultimo pedido completo, o dejar de recibir cartas, o hacerle espacio para 2 o mas.
Dejando de lado las analogias, otra cosa mas, hay muchas variables y operaciones sin sentido que quitandolas quedo algo como esto:
void RDA_isr(void){
RESTART_WDT();
OUTPUT_BIT(LED2,LON);
br++;
if(br==1 && temp[0]!=0x7E) br=0; //Compruebo que sea inicio de trama, no hago temp[0]=0, total en la proxima interrupcion se va a borrar al ser br=0.
if(br==3) tamano=temp[2] + 3; // Obtengo el largo de la trama +3 por el br++,
if(br==tamano) // Llego al final de la trama?, comienzo nuevamente
{
if(!recep){for(pos=0;pos<br;pos++){brr[pos]=temp[pos];}} //Paso los datos al array que se va a usar
else {while(1);} // Aca entraria si hubiera un error, en el que llego una segunda trama por completo y todavia no se proceso la primera. Si queda atorado aca quiere decir que eso ocurrio. Se puede reemplazar por otro codigo, como un
// led o algo por el estilo que te avise cuando eso ocurra. O directamente descartar la nueva trama que llego hasta que se termine de procesar la que ya habiamos copiado.
recep=1; // Esto deberia ponerse a 0 en el programa principal, cuando se termina de tratar los datos
br=0;
}
}
El codigo SUPONE que el tamaño de la trama JAMAS sea menor a 3 datos.
temp[] = buffer de datos para la llegada
brr[] = array que usas para mantener toda la trama una ves llegada y es lo que usas para "tratar" la trama.
Siguiendo con tu main:
if(recep==1){
RESTART_WDT();
for(pos=0;pos<=br-1;pos++){decodificar_trama(pos,temp[pos]);} //Esto no tiene sentido aca
for(pos=0;pos<=32;pos++){temp[pos]=0;} // Esto tampoco tiene sentido, ya que la nueva trama lo va a sobreescribir
temp2=recepcion_datos(); // Estas 2 funciones realmente no se que hacen, pero tampoco le veo mucho sentido trabajar con un byte de info cuando tenes un ARRAY de informacion
ejecucion(temp2); // Imagino que aca realmente manejas el array
br=0; // Esta es una variable de la interrupcion, no de aca
temp2=0; // No tiene sentido ya que primero se asigna un valor a temp2 y luego se usa, asi que no importa el valor que tenga se va a sobreescribir
tam_tram=0; // Tampoco tiene sentido, esto lo sacas de brr[2]
recep=0; // Lo unico que vale xD
Deberia ser asi:
if(recep==1){
RESTART_WDT();
temp2=recepcion_datos();
ejecucion(temp2);
recep=0;
}
Y creo que directamente podrias haber realizado una sola funcion para esas 2, aunque no se realmente que hacen cada una.