I'm trying to read in some serial data from a MODBus master and so far have managed to get my PIC to receive data using the functions created from MCC, however when the master sends too much data I can't read it out of the UART fast enough to make room for the new data coming in.
I'm quite new to this and fairly sure I'm going over things there's obvious answers for but I'm at a loss.
Currently my test program looks like:
printf("Initalised\r\n\n");
int Counter = 0;
// Set RS485 to receive.
RXMode();
while(1)
{
if(EUSART1_is_rx_ready()){
Counter++;
printf("Triggered: %i \r\n\n", Counter);
while(EUSART1_is_rx_ready()){
// While there's something to read out
rxData = EUSART1_Read();
printf("eusart1RxCount: %d \r\nData: 0x%02x \r\n\n", eusart1RxCount, rxData);
}
}
}
Sending: 0x11 0x10 0x00 0x01 0x00 0x02 0x04 0x00 0x0A 0x01 0x02 0xC6 0xF0 Produces the following output:
Initalised
Triggered: 1
eusart1RxCount: 5
Data: 0x11
eusart1RxCount: 11
Data: 0x01
eusart1RxCount: 10
Data: 0x02
eusart1RxCount: 9
Data: 0xc6
eusart1RxCount: 8
Data: 0xf0
eusart1RxCount: 7
Data: 0x02
eusart1RxCount: 6
Data: 0x04
eusart1RxCount: 5
Data: 0x00
eusart1RxCount: 4
Data: 0x0a
eusart1RxCount: 3
Data: 0x01
eusart1RxCount: 2
Data: 0x02
eusart1RxCount: 1
Data: 0xc6
eusart1RxCount: 0
Data: 0xf0
The first byte is correct, but then by the time it goes to read the 2nd byte it's actually reading the 10th byte sent, and the 3rd byte is reading the 11th byte sent....etc.
Hopefully someone can help! I've spent all day on this. Any advice is greatly appreciated, I feel like I'm on a steep learing curve here.
The MCC generated USART driver code internally buffers the received data in a 8B (typically) ring-buffer; defined by EUSART2_RX_BUFFER_SIZE
in eusart1.c
. What you are finding is that the buffered data is being overwritten, before the application loop can read it out of the buffer with EUSART1_Read()
.
Generally, on detecting buffered RX data, EUSART1_is_rx_ready
, you should read all the buffered data by repeating EUSART1_Read
. With all the trace printing between each character read, the application isn't giving much bandwidth to processing the inbound data. This approach isn't scalable.
If the trace prints are required, then the USART RX buffer size should be increased to avoid the ring-buffer wrapping around before the data can be processed. This can be done by changing the value of EUSART2_RX_BUFFER_SIZE
.
It is good practice to read all buffered data to a local buffer at one go, and then process it, e.g. print the locally buffered USART RX content out.