STM32的DMA应用于UART数据接收讨论

2019-03-23 19:02发布

STM32的UART不带FIFO,通讯速度高时不使用DMA开销太大(LM3S有16级深的FIFO可以7/8满触发中断,带超时功能,亮点啊)。打算用DMA配置成外设到内存的数据传输方式实现数据接收,实现下来确实有难度啊。
具体如下
配置DMA时,必须先指定接收BUF大小,DMA传输中断可选择为传输错误、半传输或传输完成时产生。

关键问题是实现通讯时事先不知道要接收的数据包大小,对端不同类型数据包发送完成时DMA传输进度也会各不相同(和配置的DMA buf深度没有没系),无法保证所有包会产生半传输或传输完成中断。考虑增加一个定时器发送消息提示DMA进度,但高速通讯时,定时器的开销也较大。不知道有没有更好的办法。

应用中需要高传输速度与快速响应。STM32似忽很难实现啊。

实现不行只能放弃使用DMA,直接中断处理了。 此帖出自小平头技术问答
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
17条回答
Li_Lei
1楼-- · 2019-03-23 22:13
/ 你不知道数据包的大小所以无论无何不可能实时响应的,因为你不知道何时结束是吧

可以考虑在发包前先加上包大小然后在启动dma
xg_qing
2楼-- · 2019-03-24 03:46
原帖由 huo_hu 于 2012-10-19 18:31 发表
你不知道数据包的大小所以无论无何不可能实时响应的,因为你不知道何时结束是吧

可以考虑在发包前先加上包大小然后在启动dma
想法不错,但实现也许不行。因为数据包是走协议的,要判断帧标志以及数据帧格式正确性,收到一个数据就认为是包大小抗干扰将会比较差,且一旦有干扰将无法给包定界。
Li_Lei
3楼-- · 2019-03-24 09:02
 精彩回答 2  元偷偷看……
虚V界
4楼-- · 2019-03-24 14:54
既然你是有协议的,那都还好办的啊,例如modbus 地址判断完后有数据长度标识,然后把这个数据长度读入DMA 的长度。再做DMA 的读取。
       还有就是超时定义超时了就直接关闭DMA 读数据好了,一帧的时间不可能无限长的,只要是协议长数据帧一定会分有后继帧,后继帧虚等前一帧数处理完后回应才发后继帧的,所以这里定义一下最长长度帧的超时计时 就好了
xg_qing
5楼-- · 2019-03-24 19:17
原帖由 虚V界 于 2012-10-21 13:35 发表
既然你是有协议的,那都还好办的啊,例如modbus 地址判断完后有数据长度标识,然后把这个数据长度读入DMA 的长度。再做DMA 的读取。
       还有就是超时定义超时了就直接关闭DMA 读数据好了,一帧的时间不可能无限 ...
目前使用包格式类似Modbus,帧标志+源地址+目标地址+功能码+数据区字节数+数据区+CRC16。数据区最大长度为250个字节。
大部分情况下每包数据在0~40个字节之间,只有文件读写时会达到最大值250,只数据区接收时使用DMA可能改善不大啊。

包超时的想法很妙呀!你的想法是在接收数据区长度时启动DMA,同时启动超时定时器吗?呵呵,高手,这个办法确实有效解决了数据接收时的CPU开销。协议前段处理CPU开销看起来很验省下来了。STM32确实有些美中不足啊。

TI的M3 UART做得比较好就是有一个16级深的FIFO,我可以选择在接收端满了7/8产生时产生中断,同时也不必担心对端数据已经发送完成接收FIFO还没满不能产生中断的情况,因为可以选择接收超时中断(32个位时间没数据就认为接收超时)。这样对端包发送完最多32个位时间内就可以得到处理,收到14个字节才需CPU中断处理一次,CPU开销降低了很多。
使用STM32真的感觉很难兼顾低CPU开销与快速处理, 呵呵,STM32才开始用,也许是我菜没找到完美的方法吧。
xg_qing
6楼-- · 2019-03-24 21:16
 精彩回答 2  元偷偷看……

一周热门 更多>