I am trying to read from a sensor with PIC 18f4550 at baud rate=38400. With a FIFO Circular buffer, I am able to store data from the sensor to an array.
The sensor will respond to a request command and return a measurement of 15 bytes (the same as the circular buffer I created). I have to grab all 15 bytes and put \r\n at the end to separate each measurement since there is no deliminator.
So I used two pointers, inputpointer and outputpointer to store bytes and transmit byte out. Because 18f4550 only has one hard UART, I use it to read data and send commands to sensor and at the same time use a software UART to output to a laptop via RS232.
I request a new measurement when the buffer is read and sent to serial port.
It works well but I just want to know if there is a better way to avoid FIFO overrun when the head pointer overruns tail pointer, ie when there is a lot of data getting buffered but they cannot get output in time.
Here is the code: 16MHZ PIC 18f4550 mikroC compiler
char dataRx[15];
char unsigned inputpointer=0;
char unsigned outputpointer=0;
// initialize pointers and buffer.
void main() {
ADCON1=0x0F; //turn analog off
UART1_Init(115200); //initialize hardware UART @baudrate=115200, the same setting for the sensor
Soft_UART_Init(&PORTD,7,6,38400,0); //Initialize soft UART to commnuicate with a laptop
Delay_ms(100); //let them stablize
PIE1.RCIE = 1; //enable interrupt source
INTCON.PEIE = 1;
INTCON.GIE = 1;
UART1_Write(0x00); //request a measurement.
UART1_Write(0xE1); //each request is 2 bytes
while(1){
Soft_UART_Write(dataRx[outputpointer]); //output one byte from the buffer to laptop
outputpointer++; //increment output pointer
if(outputpointer==0x0F) //reset pointer if it's at the end of the array
{
outputpointer=0x00;
Soft_UART_Write(0x0D); //if it's at the end, that means the buffer is filled with exactly one measurement and it has been output to the laptop. So I can request another measurement.
Soft_UART_Write(0x0A); //add \r\n
UART1_Write(0x00); //request another measurement
UART1_Write(0xE1);
}
}
void interrupt(void){ //interrupt routine when a byte arrives
dataRx[inputpointer]=UART1_Read(); //put a byte to a buffer
inputpointer++;
if (inputpointer==0x0F){inputpointer=0;} //reset pointer.
}