打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
51单片机串口通信 环形缓冲区队列(FIFO)

51单片机串口通信 环形缓冲区队列

最近在做毕业设计刚好涉及到51单片机,简单的研究一下发现51单片机串口只有一个字节的缓存,如果遇到单片机串口中断没有及时处理SBUF的值或者串口中断长时间未退出很容易照成数据丢失,于是就自己写了个缓冲区,代价就是消耗一部分内存空间,时间-空间本来就是一对矛盾体,想减少串口通信中数据丢失问题只能牺牲部分空间,来减少数据通信过程中的丢失问题。

  1. 核心代码如下所示:
/**    用途:     小内存环形缓冲区(FIFO模式)    作者: 南栀<kellygod95@gmail.com>*/#define BUFFER_MAX  16      //缓冲区大小typedef struct _circle_buffer{    unsigned char head_pos;             //缓冲区头部位置    unsigned char tail_pos;             //缓冲区尾部位置       unsigned char circle_buffer[BUFFER_MAX];    //缓冲区数组 }circle_buffer;circle_buffer buffer;void bufferPop(unsigned char* _buf){    if(buffer.head_pos==buffer.tail_pos)        //如果头尾接触表示缓冲区为空        *_buf=0xFF;    else    {        *_buf=buffer.circle_buffer[buffer.head_pos];    //如果缓冲区非空则取头节点值并偏移头节点        if(++buffer.head_pos>=BUFFER_MAX)            buffer.head_pos=0;    }}void bufferPush(const unsigned char _buf){       buffer.circle_buffer[buffer.tail_pos]=_buf; //从尾部追加    if(++buffer.tail_pos>=BUFFER_MAX)           //尾节点偏移        buffer.tail_pos=0;                      //大于数组最大长度 制零 形成环形队列        if(buffer.tail_pos==buffer.head_pos)    //如果尾部节点追到头部节点 则修改头节点偏移位置丢弃早期数据        if(++buffer.head_pos>=BUFFER_MAX)            buffer.head_pos=0;}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36

考虑到看到此博文的人可能有很多小白并不知道如何使用,在此简单的说一下,假设你已经能进行简单的串口发送接收了,然后串口中断部分可以这样写

void serial1(void) interrupt 4{    if(RI)    {        bufferPush(SBUF);        RI=0;           }    if(TI)    {        TI=0;    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

在主程序中我们只需要调用函数就行了如:

void main(){    unsigned char dat ;//读取缓冲区一个字符,如果dat=0xff表示缓冲区为空,所以接收的字符不能有0xff。    bufferPop(&dat);}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

bufferPop函数中没调用一次,便从缓冲区取出一个字符,头部指针就会进行偏移,具体看源码并不是很复杂 只是一个数组类型的环形FIFO缓冲区。

有一点要注意的是,如果缓冲区满的话,后面的数据会覆盖最前面的数据。

你可以把缓冲区设置大些,就可以尽可能的减少数据覆盖问题,但是带来的额外问题就是51或者其他系列的单片机RAM是非常小的,并不像PC中缓冲区动不动就1024KB。所以缓冲区设置多大,根据自己需求调整就行了。

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
干货|高质量代码是怎么写出来的?串口环形队列
环形缓冲区的实现原理(ring buffer)
linux内核数据结构之kfifo
Linux内核中的循环缓冲区
理解 Memory barrier(内存屏障) | Name5566
STM32串口DMA方式接收数据。类似环形FIFO。超省CPU资源!
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服