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;

}

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

void serial1(void) interrupt 4
{
    if(RI)
    {
        bufferPush(SBUF);
        RI=0;       
    }
    if(TI)
    {
        TI=0;
    }
}

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

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

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

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

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

  • 21
    点赞
  • 84
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
STM32进阶之串口环形缓冲区实现FIFO。 在STM32中,串口通信是一种常见的通信方式。为了提高串口通信的效率,我们可以使用环形缓冲区来实现FIFO(先进先出)的数据存储与读取。 串口环形缓冲区的实现主要包括一个接收缓冲区和一个发送缓冲区。为了避免数据覆盖和数据丢失,接收缓冲区和发送缓冲区的大小应根据实际需求进行合理设置。 在接收数据时,当有新的数据到达时,将数据存储到接收缓冲区的当前位置,并将接收缓冲区的指针移动到下一个位置。如果接收缓冲区已满,则将指针重新指向缓冲区的起始位置。 在发送数据时,将要发送的数据存储到发送缓冲区的当前位置,并将发送缓冲区的指针移动到下一个位置。如果发送缓冲区已满,则等待缓冲区有空位继续发送数据。 通过使用环形缓冲区实现串口FIFO机制,我们可以在数据发送过程中实现异步操作,提高了系统的响应速度和数据处理的能力。 需要注意的是,当接收缓冲区或发送缓冲区满时,应该有相应的处理机制,例如中断或轮询方式来检测缓冲区的状态,并对缓冲区进行相应的处理,以免数据丢失或覆盖。 总之,串口环形缓冲区的实现可以提高串口通信的效率,实现FIFO机制。通过合理设置缓冲区的大小和相应的处理机制,我们可以实现稳定可靠的数据传输。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值