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

2019-12-18 18:50发布

本帖最后由 gagaguojia 于 2014-8-28 16:01 编辑

首先 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)
*/
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
39条回答
tarzar
1楼-- · 2019-12-21 07:45
在接收讲得非常好!

不知道楼主在发送是怎么处理的(也采用DMA):
比如前面已经有包数据DMA正在发送中, 此时数据处理中又需要发送一包(可以直接加在上一包的末尾,然后DMA一起发送出去)?
还是一定要等到上一包发送完,DMA空闲下来,才能再装下一包发送
gagaguojia
2楼-- · 2019-12-21 08:51
tarzar 发表于 2016-6-17 14:12
在接收讲得非常好!

不知道楼主在发送是怎么处理的(也采用DMA):


我跑的ucos系统,我是先准备几个缓冲区 比如准备3个缓冲区,每次发送的时候循环用不同的缓冲区,我只管把要发送的数写进缓冲区即可,然后等上一次dma发送完后,再发这次的,由于跑系统,所以等待上一次dma处理完的时间不浪费 可以干别的事情
至于采用几个缓冲区 缓冲区多大 要根据实际情况自己来设置
tarzar
3楼-- · 2019-12-21 09:52
gagaguojia 发表于 2016-6-21 15:53
我跑的ucos系统,我是先准备几个缓冲区 比如准备3个缓冲区,每次发送的时候循环用不同的缓冲区,我只管把 ...

明白了,谢谢!
lihaimeng@163
4楼-- · 2019-12-21 12:17
 精彩回答 2  元偷偷看……
shijianzhou
5楼-- · 2019-12-21 17:48
能贴个完整代码来测试测试么
acmilannast
6楼-- · 2019-12-21 22:25
主循环处理不靠谱的 还是再加一个定时中断去取数据,数据拿到缓冲区,再让主循环处理。 保证DMA循环队列不会被冲垮

一周热门 更多>