搜索
bottom↓
回复: 39

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

  [复制链接]

出0入0汤圆

发表于 2014-8-28 15:58:57 | 显示全部楼层 |阅读模式
本帖最后由 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)
*/

阿莫论坛20周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入0汤圆

发表于 2014-8-28 16:07:17 | 显示全部楼层
之前用的256Byte的环形缓冲,遭遇重载出错,也能恢复正常工作。

出0入0汤圆

 楼主| 发表于 2014-8-28 16:15:58 | 显示全部楼层
styleno1 发表于 2014-8-28 16:07
之前用的256Byte的环形缓冲,遭遇重载出错,也能恢复正常工作。

是啊,重载出错时,当前的数据就会丢失一条
用我这种方法,就不会重载出错,这样,就不会丢失数据

出0入0汤圆

发表于 2014-8-28 16:35:09 | 显示全部楼层
嗯    不错    可以试试

出0入0汤圆

发表于 2014-8-28 16:44:56 | 显示全部楼层
mark环形队列

出0入0汤圆

发表于 2014-8-28 18:30:32 | 显示全部楼层
赞一个     很好的想法    学习啦

出0入0汤圆

发表于 2014-8-28 19:14:46 来自手机 | 显示全部楼层
需要mark一下环形列队。

出0入0汤圆

发表于 2014-8-28 20:18:59 | 显示全部楼层
谢谢    参考一下  

出0入0汤圆

发表于 2014-9-2 13:41:55 | 显示全部楼层
另一种很好的思路,学习了!

出0入0汤圆

发表于 2014-9-2 13:55:21 来自手机 | 显示全部楼层
多谢分享

出0入0汤圆

发表于 2014-9-2 14:09:03 | 显示全部楼层
回去我也参看一下 很不错的想法哦

出0入0汤圆

发表于 2014-12-12 14:31:09 | 显示全部楼层
好思想 好方法 谢谢分享 用到CAN转串中 不错

出0入0汤圆

发表于 2014-12-13 11:38:19 | 显示全部楼层
mark!!!!!!!!!!!!!!!!!!!!!!!!!!!DMA 串口 接收

出0入0汤圆

发表于 2014-12-13 15:46:44 | 显示全部楼层
mark,正在做,谢谢

出0入0汤圆

发表于 2014-12-13 17:47:49 | 显示全部楼层
mark,很好的想法,顶一个

出0入0汤圆

发表于 2015-3-18 16:12:11 | 显示全部楼层
在F407上, 测试DMA循环列队接收串口1数据,非常好的方法! 谢谢!

出0入0汤圆

发表于 2015-3-18 16:19:42 | 显示全部楼层
值得学习一下

出0入0汤圆

发表于 2015-3-18 18:22:59 | 显示全部楼层
学习一下

出0入0汤圆

 楼主| 发表于 2015-3-24 14:21:36 | 显示全部楼层
cen5010bao 发表于 2015-3-18 16:12
在F407上, 测试DMA循环列队接收串口1数据,非常好的方法! 谢谢!

我在STM32F103VCT6上 四个串口的DMA 都用 也很好用

出0入4汤圆

发表于 2016-6-17 14:12:40 | 显示全部楼层
在接收讲得非常好!

不知道楼主在发送是怎么处理的(也采用DMA):
比如前面已经有包数据DMA正在发送中, 此时数据处理中又需要发送一包(可以直接加在上一包的末尾,然后DMA一起发送出去)?
还是一定要等到上一包发送完,DMA空闲下来,才能再装下一包发送

出0入0汤圆

 楼主| 发表于 2016-6-21 15:53:29 | 显示全部楼层
tarzar 发表于 2016-6-17 14:12
在接收讲得非常好!

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


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

出0入4汤圆

发表于 2016-6-22 08:20:55 | 显示全部楼层
gagaguojia 发表于 2016-6-21 15:53
我跑的ucos系统,我是先准备几个缓冲区 比如准备3个缓冲区,每次发送的时候循环用不同的缓冲区,我只管把 ...

明白了,谢谢!

出0入0汤圆

发表于 2016-12-14 13:35:02 | 显示全部楼层
MAKE,为这个烦恼啊,参考下,谢谢

出0入0汤圆

发表于 2016-12-14 15:08:51 | 显示全部楼层
能贴个完整代码来测试测试么

出0入4汤圆

发表于 2016-12-14 20:59:30 | 显示全部楼层
主循环处理不靠谱的 还是再加一个定时中断去取数据,数据拿到缓冲区,再让主循环处理。 保证DMA循环队列不会被冲垮

出0入0汤圆

 楼主| 发表于 2016-12-26 16:28:18 | 显示全部楼层
acmilannast 发表于 2016-12-14 20:59
主循环处理不靠谱的 还是再加一个定时中断去取数据,数据拿到缓冲区,再让主循环处理。 保证DMA循环队列不 ...

靠谱,根据实际需求自己设置队列的大小,这个方法我已经在gps产品上应用了,一直没什么问题,不用定时器那么麻烦!

出0入0汤圆

发表于 2016-12-26 16:43:04 | 显示全部楼层
串口DMA,记号一下

出0入4汤圆

发表于 2016-12-26 17:10:27 | 显示全部楼层
gagaguojia 发表于 2016-12-26 16:28
靠谱,根据实际需求自己设置队列的大小,这个方法我已经在gps产品上应用了,一直没什么问题,不用定时器 ...

你坐的功能单一 应该没问题,实时性有保证,任务稍微复杂一点的话就不可靠了。

出0入0汤圆

发表于 2016-12-28 13:58:42 | 显示全部楼层
mark一下,谢谢分享

出0入0汤圆

发表于 2016-12-28 20:09:50 | 显示全部楼层

mark!!DMA 串口 接收

出0入0汤圆

 楼主| 发表于 2017-1-10 09:28:02 | 显示全部楼层
acmilannast 发表于 2016-12-26 17:10
你坐的功能单一 应该没问题,实时性有保证,任务稍微复杂一点的话就不可靠了。 ...

任务稍微复杂一点的话就不可靠了?------能具体说一下什么情况下不可靠?不要一句话带过。我给公司写的GPS+gprs+mqqt+ucosiii的代码都成新产品了,2016年11月份又出了2000台左右,到现在还没出问题,如果你预见到了有bug,请指点一二,谢谢

出0入4汤圆

发表于 2017-1-10 12:08:21 | 显示全部楼层
gagaguojia 发表于 2017-1-10 09:28
任务稍微复杂一点的话就不可靠了?------能具体说一下什么情况下不可靠?不要一句话带过。我给公司写的GP ...

已经上操作系统了,数据处理的实时性已经有保证了。不存在问题。我说的是前后台系统,在主程序读取数据 实时性是得不到保证的,可能存在风险。

出0入0汤圆

发表于 2017-1-12 16:18:53 | 显示全部楼层
不错,学习一下

出0入0汤圆

发表于 2017-1-12 16:20:40 | 显示全部楼层
Mark,谢谢分享~

出0入0汤圆

发表于 2017-1-24 13:12:05 | 显示全部楼层
acmilannast 发表于 2017-1-10 12:08
已经上操作系统了,数据处理的实时性已经有保证了。不存在问题。我说的是前后台系统,在主程序读取数据  ...

数据处理是对数据的解析,处理以及之后的业务逻辑?还是读写缓存?主程序读取数据指的是什么?

出0入0汤圆

发表于 2017-1-24 13:13:45 | 显示全部楼层
楼主有stm32通过dma读写spi的方案吗?

出0入0汤圆

 楼主| 发表于 2017-1-24 16:01:12 | 显示全部楼层
lincoln310 发表于 2017-1-24 13:13
楼主有stm32通过dma读写spi的方案吗?

spi我还没用dma搞过,抱歉

出0入0汤圆

发表于 2017-3-13 15:35:12 | 显示全部楼层
不错,标记一下,stm32 dma 环形队列。

出0入0汤圆

发表于 2018-5-2 17:30:42 | 显示全部楼层
还有这个说法-//1、DMA循环计数值是递减的 当计数值为1以后,下一个值不是0,而是USART1MAXSIZE,学习了

出0入0汤圆

 楼主| 发表于 2018-5-3 09:52:51 | 显示全部楼层
shuen729 发表于 2018-5-2 17:30
还有这个说法-//1、DMA循环计数值是递减的 当计数值为1以后,下一个值不是0,而是USART1MAXSIZE,学习了 ...

恩,一定要注意
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-3-29 20:09

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表