为什么需要缓冲区
很多单片机串口只有一个字节的缓存,如果遇到单片机串口中断没有及时处理寄存器的值,就会导致数据被覆盖,从而导致数据的丢失。为了防止丢失,我们应该定义一个缓冲区来保存数据,一有数据就往里面保存,需要的时候再去读取。
代码实现
下面的代码使用51单片机实现:
#define BUFFER_MAX 100 //缓冲区大小typedef struct _buffer{ unsigned char head_pos; //缓冲区头部位置 unsigned char tail_pos; //缓冲区尾部位置 unsigned char buffer[BUFFER_MAX]; //缓冲区数组 }uart_buffer;uart_buffer datas;unsigned char uart_read(void){ unsigned char ch; if(datas.head_pos==datas.tail_pos) //如果头尾位置相同表示缓冲区为空 { return 0xFF; } else { ch = datas.buffer[datas.head_pos]; //如果缓冲区非空则取头节点值并偏移头节点 datas.head_pos++; //读取一个字节,移动一个位置 if(datas.head_pos>=BUFFER_MAX) datas.head_pos=0; //位置回到数组头部 } return ch;}//这个函数在中断中使用void uart_receive(const unsigned char _buf){ datas.buffer[buffer.tail_pos]=_buf; //从尾部追加 datas.tail_pos++; if(datas.tail_pos>=BUFFER_MAX) //是否超过最大缓存 datas.tail_pos=0; //大于数组最大长度置零 形成环形队列 if(datas.tail_pos==datas.head_pos) //如果尾部节点追到头部节点 则修改头节点偏移位置丢弃早期数据 { datas.head_pos++; if(datas.head_pos>=BUFFER_MAX) buffer.head_pos=0; }}
中断函数
void uart1(void) interrupt 4{ if(RI) { uart_receive(SBUF); RI=0; }}
主函数
void main(){ unsigned char data ; data = uart_read();}
如果缓冲区满的话,后面的数据会覆盖最前面的数据,如果末尾追上头部,会导致数据还没被读就被覆盖了,所以缓冲区的大小要根据自己的项目需求来进行定义,防止数据未读就被覆盖了。
喜欢这篇文章,欢迎点赞,分享,关注!
声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!