我们知道的串口收发都是:接收一个数据,触发中断,然后把数据发回来。这种处理方式是没有缓冲的,当数量太大的时候,亦或者当数据接收太快的时候,我们来不及处理已经收到的数据,那么,当再次收到数据的时候,就会将之前还未处理的数据覆盖掉。那么就会出现丢包的现象了,对我们的程序是一个致命的创伤;于是就自己写了个缓冲区,代价就是消耗一部分内存空间,时间-空间本来就是一对矛盾体,想减少串口通信中数据丢失问题只能牺牲部分空间,来减少数据通信过程中的丢失问题。
环形缓冲区队列(FIFO)的软件实现:
把主机和从机的(TX/RX)看成对象实例,相互独立的,都包含in,out,buf[]三个属性。
即对应软件数据结构如下:
typedef struct {
u8 in; //数据接收索引号
u8 out; //数据发送索引号
char buf[256]; //数据缓冲区队列
} comCycle_t;
typedef struct {
comCycle_t tx; //发送端
comCycle_t rx; //接收端
} tComBuf_t;
typedef enum {
COM1 = 0,
COM2,
COM3,
...
} COM_DEF;
extern tComBuf_t comBuf[3];
以STM32串口2为例:
void USART2_IRQHandler(void)
{
if((USART2->SR & USART_SR_RXNE) != 0) //接收时RX.in++
{
comBuf[COM2].rx.buf[comBuf[COM2].rx.in++] = (u8)(USART2->DR);
}
if((USART2->SR & USART_SR_TXE) != 0) //发送时TX.out++
{
if(comBuf[COM2].tx.in != comBuf[COM2].tx.out)