STM32
直播中

abdkjshd

8年用户 1144经验值
擅长:可编程逻辑
私信 关注
[问答]

怎样去解决STM32F103 DMA串口空闲接收卡顿的问题呢

DMA串口空闲接收的原理是什么?

怎样去解决STM32F103 DMA串口空闲接收卡顿的问题呢?

回帖(1)

刘欢

2021-12-8 15:03:06
STM32F103 UCOSIII UART串口空闲DMA接收

以及 实际产品中的应用方式(标准库3.5版本)

1. 修订记录

2. 实际产品中应用的交互协议-JSON格式

2.1、协议举例-其中一个命令

大部分情况下,1个数据包的长度都小于1024字节,在本地局域网中都可以直接1次性发送完成
比如常用的有人的 以太网,WIFI等模组–这个时候使用DMA空闲中断接收串口数据包优势就非常明显了
不用做断帧判断,只需要做数据包的格式 和 完整性判断,这个非常方便写代码,不容易出错;
命令协议距离:
主轴运动 绝对脉冲数
请求参数

[tr]参数类型描述[/tr]
cmdInt命令代码
action_idInt唯一序号



plusCntXInt
plusCntYInt
应答

[tr]参数类型描述[/tr]
action_idInt唯一序号
statusString“0”=成功,或其他错误描述信息
示例

请求:
{   "cmd":5,   "action_id ":1234,      "plusCntX":300,   "plusCntY":400} 应答:
{         "action_id ":1234,    "status":"0"}
3、DMA串口空闲接收原理

原理讲解:
当串口初始化完成后,串口就保持为接收状态,之后有数据来就开始接收数据,一旦没有数据停止发送的时间超过了固定的时间
(这个时间一般是 一个字节的传输时间,所以不同的比特率对应不同的时间,如果实际应用中,中途间隔比较大,就需要使用硬件定时器的方式,来加大这个时间:在空闲中断中启动定时器,并且将已经接收的字节搬运到缓冲区中)
,就会触发串口的空闲中断,注意不是DMA的,此时DMA还是正常接收的,然后再空闲中断中 赶紧把 DMA停止,搬运接收到的数据 到 自定义的缓冲区中,此时就完成了一次一包数据的接收;
所以:串口的空闲中断 和 DMA 是同时分开执行的,并不是空闲中断发生了DMA就停止了,所以之后应用层要赶紧把数据取出来,不然数据就可能被 新的数据覆盖;
DMA通道的选择: 请看STM32中文参考手册的DMA章节










根据上面的指示,在初始化代码中选择就行;
粘贴部分代码:
串口3配置初始化,串口空闲中断 和 对应DMA通道初始化:















对应的串口空闲中断代码:





这里一旦触发了中断,就重启了DMA接收,此时一旦立即有新数据发送过来的化,之前接收的数据肯定被覆盖了,所有需要根究自己的产品的交互速度 设计是否是共享内存,还是消息队列的,因为STM32F103的内存毕竟就这么点;
如果对端连续发送数据命令过来,那么中途的指令肯定会被丢掉很多,要注意整个系统的设计结构;
APP中的主程序就一直等待信号量的通知,然后将数据拷贝出来:





4、DMA启动的通道太多也会出问题,会阻塞卡顿

STM32F103的我没有使用到很多个DMA都启动的场景,,但是在STM32H743上就使用了很多的DMA通道,而且数据的收发非常快,且频繁,此时就可能出现DMA频繁仲裁,就可能导致卡顿
因为DMA都是要和内存SRAM打交道的,如果DMA非常频繁,就可能出现总线冲突,就需要冲裁了,这个时候就可能导致卡顿阻塞;所以DMA也不是万能的,也不可能完全解放CPU





这个系统由 14个DMA通道
主串口-和FPAG交互的串口 是 200字节,921600,2.5MS一次400HZ的速度接收的 ,速度非常快,光发送时间就占用了1.7MS左右
然后需要根据设置的 转发参数,同步的将接收的这个高频数据,转发到其他串口 和 SD卡保存;
此时对于内存的操作就非常繁忙了,哪怕CPU是空闲的,也可能导致处理速度跟不上节奏;
举报

更多回帖

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