STM32F103 UCOSIII UART串口空闲DMA接收
以及 实际产品中的应用方式(标准库3.5版本)
1. 修订记录
日期 | 修订版本 | 描述 | 修订人 |
---|---|---|---|
2021-5-4 | v1 | 原理和产品应用讲解 | 微信: pingdanv3314 |
有完整的产品上用的代码,会上传到CSDN下载中,请朋友们自己下载,这里主要是从框架整体上做讲解,
不会挨个讲代码,没啥意义;
2. 实际产品中应用的交互协议-JSON格式
2.1、协议举例-其中一个命令
大部分情况下,1个数据包的长度都小于1024字节,在本地局域网中都可以直接1次性发送完成
比如常用的有人的 以太网,WIFI等模组–这个时候使用DMA空闲中断接收串口数据包优势就非常明显了
不用做断帧判断,只需要做数据包的格式 和 完整性判断,这个非常方便写代码,不容易出错;
命令协议距离:
主轴运动 绝对脉冲数
请求参数
参数 | 类型 | 描述 |
---|---|---|
cmd | Int | 命令代码 |
action_id | Int | 唯一序号 |
plusCntX | Int | |
plusCntY | Int |
应答
参数 | 类型 | 描述 |
---|---|---|
action_id | Int | 唯一序号 |
status | String | “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是空闲的,也可能导致处理速度跟不上节奏;
5、下载代码地址:
请搜索:
stm32f103 标准库-uart串口 dma 空闲接收中断 以及 实际APP应用场景
或者
加wv :pingdanv3314 索取
6、欢迎联系沟通交流
weixin : pingdanv3314