串口环形缓冲区学习

说明&感谢

  • 互联网是个开放的世界, 感谢无数开源和分享者, 本次学习主要参考了杰杰的分享, 经了解杰杰现在大学尚未毕业, 而本人工作8年了, 闻道有先后术业有专攻,再次感谢!
  • 参考链接: 杰杰CSDN

环形缓冲区作用

串口数据接收, 如果数据量过大, 很可能来不及处理这些数据, 因此需要把接收的数据存放到一个位置缓存, 待空闲时间处理, 防止接收的数据丢失; 环形缓冲区越大, 那么可以缓存的数据就越多, 这样就是以空间换时间的做法.

编程步骤

  1. UART初始化, 打开串口发送和接收;
  2. UART中断优先级配置NVIC;
  3. 环形缓冲区定义
  4. 环形缓冲区数据接收: 在串口中断中读取收到的数据到环形缓冲;
  5. 环形缓冲区数据发送: 在主程序中把环形缓冲区的数据发送给串口;

代码&分析

#define RINGBUFF_LEN    200     //定义最大接收字节数
#define FLASE   1
#define TRUE    0
  • 结构体定义, 定义了头位置, 尾位置, 和头尾之间间隔数(lenght)
typedef struct
{
    uint16_t heard;
    uint16_t tail;
    uint16_t lenght;    //这个长度指头到尾的长度
    uint8_t  ring_buffer[RINGBUFF_LEN]; //环形缓冲区数组
}RingBufferStruct;
  • 每写一个数据到缓冲区, 尾的位置+1, 即第一次写数据到数组ring_buffer[0], 那么下一次数据写到ring_buffer[1]; 且和头的间隔lenght增加1;
uint8_t write_ring_buffer(uint8_t data)
{
    if(RingBuffer.lenght >= RINGBUFF_LEN) //判断缓冲区是否已满
    {
        return FLASE;
    }
    RingBuffer.ring_buffer[RingBuffer.tail] = data;
    RingBuffer.tail = (RingBuffer.tail + 1) % RINGBUFF_LEN; //防止越界非法访问
    RingBuffer.lenght++;
    return TRUE;
}
  • 每读一个数据, 则头+1; 即第一次读ring_buffer[0], 下一次读数据就是ring_buffer[1]; 且和尾的间隔lenght减1;
uint8_t read_ring_buffer(uint8_t *rData)
{
    if(RingBuffer.lenght == 0)//判断非空
    {
        return FLASE;
    }
    *rData = RingBuffer.ring_buffer[RingBuffer.heard];//先进先出FIFO,从缓冲区头出
    RingBuffer.heard = (RingBuffer.heard + 1) % RINGBUFF_LEN; //防止越界非法访问
    RingBuffer.lenght--;
    return TRUE;
}
  • 串口接收中断中, 把接收的数据写到环形缓冲区;
void USART1_IRQHandler(void)
{
    if(USART_GetFlagStatus(DEBUG_UART, USART_FLAG_RXNE))
    {
        USART_ClearFlag(DEBUG_UART,USART_FLAG_RXNE);//清除中断标志
        write_ring_buffer(USART_ReceiveData(DEBUG_UART));//读取接收到的数据
    }
}
  • 主程序中, 把环形缓冲区的数据读出来, 发送到串口, 打印出来
uint8_t data;
if(0==read_ring_buffer((uint8_t*) &data))
 {
       USART_SendData(DEBUG_UART,data);
 }

实验现象

如果单次发送的数据大于环形缓冲区的大小, 还是会有丢数据的可能;
在这里插入图片描述

源代码

MCU型号: STM32F103VET6
开发板: 野火指南者
平台: keil V5.27.0.0
源代码

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值