STM32
直播中

h1654155598.0450

12年用户 668经验值
私信 关注
[问答]

stm32是怎样使用环形缓冲区形式去接收数据的

STM32是怎样使用环形缓冲区形式去接收数据的?如何去实现其代码呢?

回帖(1)

戚來麒

2021-12-7 10:34:07
/*========================ringbuff.H========================================*/
#ifndef __RingBuff__H
#define USER_RINGBUFF 1 //使用环形缓冲区形式接收数据
#if USER_RINGBUFF
/**如果使用环形缓冲形式接收串口数据***/
#define RINGBUFF_LEN 200 /*最好是2^N,此时就可以进行用取模运算
#define FLASE 1
#define TRUE 0
#define TIMEOUT 3
typedef struct
{
u16 Head; //消费者模型,从队头删除
u16 Tail; //生产者模型,从队尾添加
u16 Lenght; //接收数据的长度为ringBuff.Lenght=Ring_Buff.Tail-Ring_Buff.Head
u8 Ring_Buff[RINGBUFF_LEN];
}RingBuff_t;
typedef struct
{
bool bTimeoutCountEn;
bool bTimeout;
u16 Timeoutcount;
u16 Timelimt; //一般为几个字符传送的时间
}Timeout_t;
void RingBuff_Init(void);
u8 Write_RingBuff(u8 data);
u8 Read_RingBuff(u8 *rData);
#endif //end of USER_RINGBUFF
#endif //end of __RingBuff__H
/*========================ringbuff.c========================================*/
#include "ringbuff.h"
RingBuff_t ringBuff;//创建一个ringBuff的缓冲区
Timeout_t RcvTimeout={0,0,0,TIMEOUT};
void RingBuff_Init(void)
{
//初始化相关信息
ringBuff.Head = 0;
ringBuff.Tail = 0;
ringBuff.Lenght = 0;
}
/**
*
*
*
* 说明:被接收中断函数调用
*/
u8 Write_RingBuff(u8 data)
{
#if 0
//if((ringBuff.Tail -ringBuff.Head)== RINGBUFF_LEN) //判断缓冲区是否已满
if(ringBuff.Lenght== RINGBUFF_LEN)
{
return FLASE;
}
ringBuff.Ring_Buff[(ringBuff.Tail++)&(MRINGBUFF_LEN-1)] = data //前提.Tail和.Head数据类型是unsigned int,且MRINGBUFF_LEN是2的词幂,ringBuff.Lenght=Ring_Buff.Tail-Ring_Buff.Head
#else
if(ringBuff.Lenght >= RINGBUFF_LEN) //判断缓冲区是否已满
{
return FLASE;
}
ringBuff.Ring_Buff[ringBuff.Tail]=data;
ringBuff.Tail = (ringBuff.Tail+1)%RINGBUFF_LEN;//防止越界非法访问
#endif
ringBuff.Lenght++;
return TRUE;
}
/**
*
*
*
* 说明:原则上不用做接收完成的判断,当缓冲区读都不可读时会有提醒
*/
u8 Read_RingBuff(u8 *rData)
{
#if 0
//if((ringBuff.Tail -ringBuff.Head)== 0) //判断缓冲区是否已空
if(ringBuff.Lenght==0)
{
return FLASE;
}
*rData =ringBuff.Ring_Buff[(ringBuff.Head++)&(MRINGBUFF_LEN-1)]; //前提.Tail和.Head数据类型是unsigned int,且MRINGBUFF_LEN是2的词幂,ringBuff.Lenght=Ring_Buff.Tail-Ring_Buff.Head
#else
if(ringBuff.Lenght == 0)//判断非空
{
return FLASE;
}
*rData = ringBuff.Ring_Buff[ringBuff.Head];//先进先出FIFO,从缓冲区头出
ringBuff.Head = (ringBuff.Head+1)%RINGBUFF_LEN;//防止越界非法访问
#endif
ringBuff.Lenght--;
return TRUE;
}
void USART1_IRQHandler(void)
{
if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //接收中断
{
USART_ClearITPendingBit(USART1,USART_IT_RXNE); //清楚标志位
Write_RingBuff(USART_ReceiveData(USART1)); //读取接收到的数据
RcvTimeout.bTimeoutCountEn =1;
RcvTimeout.Timeoutcount=0;
}
}
void TIM3_IRQHandler(void)
{
if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET) //检查指定的TIM中断发生与否:TIM 中断源
{
TIM_ClearITPendingBit(TIM3, TIM_IT_Update );
if(RcvTimeout.bTimeoutCountEn)
{
if(++RcvTimeout.Timeoutcount == RcvTimeout.Timelimt)
{
RcvTimeout.bTimeoutCountEn=0;
RcvTimeout.Timeoutcount=0;
RcvTimeout.bTimeout=1; //接收完成判断
}
}
}
}
举报

更多回帖

发帖
×
20
完善资料,
赚取积分