This example creates a 16 byte buffer for receiving characters using an interrupt service. I don't show the ISR, just a routine called from it (or embedded in it)
I'm posting it here to save time in future. Feel free to post suggestions, improvements, or bugs!
- Code: Select all
volatile char comin_wptr; //write pointer. Is changed inside an interrupt
char comin_rptr; //read pointer
char comin_buf[16]; //input data buffer
#define BUFFER_MASK 0x0f //mask to force pointers to wrap after 16
void com_init(void)
{
comin_wptr=0;
comin_rptr=0;
//code here to set baud rate, enable serial port, and enable receive interrupts
}
//call from USART RX interrupt (or embed inside the ISR)
void comin_put (char dat)
{
if (((comin_rptr - comin_wptr) & BUFFER_MASK) != 1) //test if the write pointer is about to hit the read ppinter
{ //here if there is room in the buffer
comin_buf[comin_wptr++]=dat; //add character to buffer, and bump write pointer
comin_wptr &= BUFFER_MASK; //force pointer to wrap
} else
{ //buffer is full
//add code here to drop hardware handshaking, or set a flag saying "buffer overflow"
}
}
//fetch the next character from the buffer. Return zero if buffer empty
char comin_get(void)
{
char temp; //temp scratch
if (comin_wptr == comin_rptr)
return 0; //if we are called when there is nothing ready
temp = comin_buf[comin_rptr++]; //fetch character from buffer, and bump read pointer
comin_rptr &= BUFFER_MASK; //force pointer to wrap at 16
return temp; //return the value we read from the buffer
}
//return 0 (false) if buffer empty, or 1 (true) if there is some data in the buffer
bit comin_ready(void)
{
if ((comin_wptr == comin_rptr)
return 0; //buffer is empty
return 1; //buffer contains data
}