Yo creo que te estas haciendo mucho problema. Ademas de tener un delay en tu rutina de interrupcion...
Primero definiria el mensaje a enviar. Si o si yo definiria un comienzo de trama, si es de tamaño fijo no incluiria un valor de tamaño , si es de valor variable si, o sino otro valor de fin de trama.
Ej: Trama FIJA 2 datos, al esclavo 2
0xFF 0x02 0x50 0x06
Comienzo de trama - Esclavo - Datos
Trama variable al esclavo 4
0xFF 0x04 0x05 0x87 0x56 0xFF 0x89 0x32
Comienzo de trama - Esclavo - Largo - Datos
Realizaria una maquina de estados como hiciste vos. Yo lo haria como el codigo que puse a continuacion, entonces que siga escuchando siempre, no me importaria eso, mientras escuche no hay problema ya que si no es del receptor este lo va a quitar o no dar importancia al valor que llegue.
#define ESPERA 0
#define ESCLAVO 1
#define RECIBIENDO 2
#define MALRECEPTOR 3
#int_rda
void serial_isr() {
dato_rx
=getc(); // almaceno el dato switch(estado) {
case ESPERA:
if(dato_rx==0xFF) { estado=ESCLAVO; j=0;}
break;
case ESCLAVO:
if(dato_rx==0x02)
{
estado=RECIBIENDO;
}
else
{
estado=MALRECEPTOR;
}
break;
case RECIBIENDO:
vector_a_guardar[j]=dato_rx;
j++;
if(j==2) {estado=ESPERA; dato_listo=1;} // Bandera para saber cuando se actualizo por completo el dato que llego.
break;
case MALRECEPTOR:
j++;
if(j==2) {estado=ESPERA;}
break;
default:
estado=ESPERA;
break;
}
}
Si es variable la cantidad de datos, entonces agregas un nuevo estado, en el que el 3er dato se le asigne a una variable, y esa variable es luego la que se compara con j
#define ESPERA 0
#define ESCLAVO 1
#define LARGO 2
#define LARGO_MAL 3
#define RECIBIENDO 4
#define MALRECEPTOR 5
#int_rda
void serial_isr() {
dato_rx
=getc(); // almaceno el dato switch(estado) {
case ESPERA:
if(dato_rx==0xFF) { estado=ESCLAVO; j=0;}
break;
case ESCLAVO:
if(dato_rx==0x02)
{
estado=LARGO;
}
else
{
estado=LARGO_MAL;
}
break;
case LARGO:
largo_dato=dato_rx;
estado=RECIBIENDO;
break;
case LARGO_MAL:
largo_dato=dato_rx;
estado=MALRECEPTOR;
break;
case RECIBIENDO:
vector_a_guardar[j]=dato_rx;
j++;
if(j==largo_dato) {estado=ESPERA; dato_listo=1;}
break;
case MALRECEPTOR:
j++;
if(j==largo_dato) {estado=ESPERA;}
break;
default:
estado=ESPERA;
break;
}
}
(Podria haberme ahorrado un estado si le ponia una bandera para indicar que no era dirigido a ese receptor, pero por simplicidad lo deje asi nomas.)
Por supuesto, esto tiene un problema, es que si en algun momento el maestro se cae a la mitad del mensaje, deberia enviar al menos un varios caracteres basura hasta que los esclavos salgan al estado ESPERA. Lo podrias hacer al comienzo del programa. asi limpiar a los esclavos, por ejemplo si tu mensajes tienen 5 datos, enviar al menos 6 o 7 datos con 0x00 y se limpiaria. Podria haberme olvidado del tema de la cantidad de datos y volver a preguntar si hay un 0xFF, pero esto evitaria que pueda mandar un 0xFF como dato. Tambien se podria implementar una funcion de timeout que si al no recibir datos durante un tiempo(desde detectado el primer dato 0xFF) que reinicie los estados a ESPERA.
La comunicacion del esclavo AL maestro podria ser:
0xFF 0x00 datos
el 0x00 sea del maestro.
eso tampoco afectaria a los esclavos, ya que la direccion es otra.