Electronic – PIC16F1788 – how can I reliably determine when EUSART byte transmit is complete

picuart

I have an application where I send semi-duplex messages on an RS485 bus.

My slave devices on this bus are normally in receive-mode, listen for commands, and when they get a command they switch to transmit-mode and transmit a response to the master.

The slaves use the EUSART of a PIC16F1788 microcontroller.

I've noticed that the last byte in this response is sometimes corrupt.

I have a theory that this might be because the last byte of the message is not completely transmitted before the slave disables the driver on the RS485 interface chip I'm using, and thus cutting the last byte short.

My code for waiting until the transmit is done is like this:

while (TRMT==0)
{
}
RS485_DRIVER_ENABLE=0;

RS485_DRIVER_ENABLE is a #define mapped to an output pin connected to the transmit enable on the RS485-chip.

Reading the PIC manual:

http://ww1.microchip.com/downloads/en/DeviceDoc/40001675B.pdf

It says:

"The TRMT bit remains clear until all bits have been shifted out of the TSR register."

However, what I'm really interested in is that all bits actually be transmitted, so the above seems to not be exactly the right guarantee I would like.

Should I add a delay of say 2-3 bits after the TRMT is signalled?

Is there any "best practice" for this sort of thing?

Best Answer

I just had a look at the datasheet. The TRMT flag is set when the transmit shift register is empty, but before the stop bit has been sent (figure 28-3 shows it being set halfway through). This means you are probably clobbering the stop bit, which is causing the observed errors. Might be worth confirming this with an oscilloscope if you have one, but it looks like the most obvious explanation.

The simplest solution is just to delay for at least one stop bit time after your TRMT polling loop. Another option is to enable 9-bit mode and make the extra bit another stop bit, though you will then be sending two stop bits between sequential bytes which will slightly reduce data throughput.