Hoy he estado peleando con una comunicación RS485 y he tenido que utilizar un recurso que jamás había usado y me ha venido como anillo al dedo.
Supongo que muchos de vosotros ya lo conoceréis, pero lo voy a escribir por si es de utilidad a alguien que tenga el mismo problema que yo.
El RS485, además de las señales TX y RX, requiere de una señal más que indica en cada momento si estamos transmitiendo o recibiendo, para lo que se utiliza un pin adicional del PIC. En mi caso este pin va conectado a dos pines del MAX485 indicando con un 1 que estamos transmitiendo y con un 0 que estamos recibiendo.
El estado habitual de mi circuito es "escuchando", y sólo se pone esa señal a 1 cuando trasmite, volviendo a 0 una vez finalizada la comunicación.
Y aquí aparece el problema. Tras un printf en CCS, el programa descarga sobre la USART la labor de envío de los bytes, y continúa su ejecución, por lo que si bajamos la señal a 0 justo detrás del printf lo normal es que cortemos la transmisión antes de que haya terminado.
Pues bien, para esperar a que la transmisión termine he utilizado un bit de la USART llamado TRMT, en el registro TXSTA (estoy trabajando con un 18F). Este bit permanece a 0 mientras haya una transmisión pendiente.
Mi código por tanto tiene estas definiciones al principio:
#define TXSTA 0xFAC
#bit TRMT = TXSTA.1
Y luego, cuando transmito me limito a lo siguiente:
RS485_emite();
printf ("Hola mundo");
while (!TRMT);
RS485_recibe();
Bueno, pues como veis es una chorradita, pero me ha hecho perder toda la mañana, así que se ha merecido al menos este post.
(*) Las funciones RS485_emite y RS485_recibe se limitan a poner a 1 y a 0 el pin que antes describí.