打印

转帖~ stm32f103应用DMA接收串口1数据的一点心得 采用循环列队

[复制链接]
4046|8
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
gigadevice|  楼主 | 2015-3-24 17:11 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
首先 DMA接收 采用循环模式接收 应用循环列队接收不定长的数据
#define USART1MAXSIZE 1024
g_usartRxForTemp[USART1MAXSIZE];//接收处理缓存
DMA_InitStructrue.DMA_MemoryBaseAddr = (uint32_t)(g_usartRxForTemp); //接收的都放在这里 这是接收大缓存
DMA_InitStructrue.DMA_BufferSize = (uint32_t)USART1MAXSIZE;//要接收的长度 在这里一般设个大点的值 保证接收的数据不会因为处理不及时,使得尾指针超过头指针
DMA_InitStructrue.DMA_Mode = DMA_Mode_Circular;//循环接收        
//其他设置在此略

//1、DMA循环计数值是递减的 当计数值为1以后,下一个值不是0,而是USART1MAXSIZE
//2、判断尾指针的位置  CurrDataCount = DMA_GetCurrDataCounter(DMA1_Channel5);
                                       usartRear=USART1MAXSIZE-CurrDataCount;
//3、队列其他函数
///////////////////////////////////////////////////////////////////////////

//判队空
u8 EmptyQueueForReceive(void)//判队空 1==队空
{  
          if(usartFront!=usartRear)
          {
                    return 0;//
           }
           else
           {
                    return 1;//
           }
}


//出队
u8 deQueueForReceive(void)
{   
             u8 temp;
             temp=*(g_usartRxForTemp+usartFront); //在这里要先出队再指针++ 因为入队是DMA自己完成的,它是一个先入队,再尾指针++的 我们得配合DMA这个特性
        usartFront=(usartFront+1)%USART1MAXSIZE
         return temp;  
}
/*
这样,
【入队】就不用管了,DMA自动完成,当接收到USART1MAXSIZE个数据后,DMA自动就帮咱们将尾指针指向初始了----队列循环
【出队】用u8 deQueueForReceive(void)出队(在出队之前别忘了判队空u8 EmptyQueueForReceive(void))
【注意】采用这样的方式,数据处理效率要跟的上, 保证接收的数据不会因为处理不及时,使得尾指针超过头指针,
避免出现这种情况的方法有2个:
<1>USART1MAXSIZE 加大他的值  1024---3000----5000等
<2>程序上做优化,使得数据处理函数(就是包含出队的函数),在总程序的大循环里比较经常的会调用,比如50ms调用一次,每次处理一条数据(20个字节左右的数据) 这样一般就没问题(USART1MAXSIZE=1024)

相关帖子

沙发
gigadevice|  楼主 | 2015-3-24 17:12 | 只看该作者
新人贴  木有人来暖贴吗?

使用特权

评论回复
板凳
玉杰天| | 2015-3-24 17:18 | 只看该作者
我来给你暖被窝!~~

使用特权

评论回复
地板
bltong| | 2015-3-24 22:22 | 只看该作者
爆楼主菊花。。。

使用特权

评论回复
5
zxcscm| | 2015-3-27 13:50 | 只看该作者
可以举一反三,搞ADC,SPI或其他DMA了

使用特权

评论回复
6
北海326| | 2016-1-26 16:27 | 只看该作者
我一般的做法是中断接收。在中断函数里面将数据放入缓冲区,主程序里分析数据。

使用特权

评论回复
7
逍遥李| | 2016-5-14 23:50 | 只看该作者
北海326 发表于 2016-1-26 16:27
我一般的做法是中断接收。在中断函数里面将数据放入缓冲区,主程序里分析数据。 ...

中断接收需要事先知道数据长度,而这个一般不知道

使用特权

评论回复
8
tongshezheng| | 2016-8-3 17:44 | 只看该作者
学了了,谢谢。

使用特权

评论回复
9
raw120| | 2020-2-19 17:56 | 只看该作者
大佬,那这样用循环队列的话,就不需要在串口中断里算获取结束到的长度了么?

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

2

主题

26

帖子

1

粉丝