OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 4111|回复: 5

STM32F103 DMA接收通信实例(3个串口)

[复制链接]

32

主题

236

帖子

0

精华

高级会员

Rank: 4

积分
993
金钱
993
注册时间
2017-8-11
在线时间
137 小时
发表于 2021-2-20 16:23:09 | 显示全部楼层 |阅读模式
分享基于STM32F103ZET6战舰V3的  DMA串口通信实例(包含串口1,串口2和 串口3)
注释很清楚了,下面分享一下DMA的说明

DMA接收简单点来说就是:串口接收到的数据自动缓存到一个数组里,不用MCU去中断干预。
可以理解为拿快递过程: 快递(串口数据)自动放到快递箱(数组缓存)里,短信通知你取快递(MCU接收到标志位)
后续就是主函数里对数据缓存区循环处理





接收数据的流程:
串口接收DMA在初始化的时候就处于开启状态,一直等待数据的到来,在软件上无需做任何事情,只要在初始化配置的时候设置好配置就可以了。
判断数据数据接收完成:
这里判断接收完成是通过串口空闲中断的方式实现,即当串口数据流停止后,就会产生IDLE中断。这个中断里面做如下几件事:
1. 关闭串口接收DMA通道,2点原因:a.防止后面又有数据接收到,产生干扰。b.便于DMA的重新配置赋值,下面第4点。
2. 置位接收完成标志位
3. 处理接收buffer中数据
4. 重新设置DMA下次要接收的数据字节数,注意,这里是给DMA寄存器重新设置接收的计数值,这个数量只能大于或者等于可能接收的字节数,否则当DMA接收计数器递减到0的时候,又会重载这个计数值,重新循环递减计数,所以接收缓冲区的数据则会被覆盖丢失。
5. 开启DMA通道,等待下一次的数据接收,注意,对DMA的相关寄存器配置写入,如第4条的写入计数值,必须要在关闭DMA的条件进行,否则操作无效。
说明一下,STM32的IDLE的中断在串口无数据接收的情况下,是不会一直产生的,产生的条件是这样的,当清除IDLE标志位后,必须有接收到第一个数据后,才开始触发,一断接收的数据断流,没有接收到数据,即产生IDLE中断。IDLE位不会再次被置高直到RXNE位被置起(即又检测到一次空闲总线)。RXNE接收中断可以不用开启,减少进中断的次数。






当MCU通过USART接收外部发来的数据时,在进行第①②③步的时候,主程序可以不用管,DMA直接将接收到的数据写入缓存RxBuffer,程序此时也不会进入接收中断,当数据接收完成之后产生接收空闲中断,在中断服务函数中将接收完成标志位置1,计算出接收缓存中的数据长度,清除中断位,失能DMA防止在处理数据时候接收数据。主程序中检测到接收完成标志被置1,进入数据处理程序,现将接收完成标志位置0,重新设置DMA下次要接收的数据字节数,使能DMA进入接收数据状态。






DMA串口通讯.zip

9.78 MB, 下载次数: 226

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

32

主题

236

帖子

0

精华

高级会员

Rank: 4

积分
993
金钱
993
注册时间
2017-8-11
在线时间
137 小时
 楼主| 发表于 2021-2-20 16:25:29 | 显示全部楼层
实测没有问题的,主函数说明一下吧,判断缓存区,假设首位为0x01, 发送数据 1 2 3 4 5 6
若不是,接收什么就回发什么

后续会参照这个模板,把Modbus 主站的功能也加上去,用DMA去取代定时器
回复 支持 反对

使用道具 举报

31

主题

2183

帖子

0

精华

资深版主

Rank: 8Rank: 8

积分
14424
金钱
14424
注册时间
2018-8-3
在线时间
1157 小时
发表于 2021-2-20 19:00:24 | 显示全部楼层
谢谢分享  赞
回复 支持 反对

使用道具 举报

2

主题

685

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3448
金钱
3448
注册时间
2017-7-4
在线时间
869 小时
发表于 2021-2-21 10:51:46 | 显示全部楼层
1、进入空闲中断后,“关闭串口接收DMA通道,再去配置DMA”,这个不合理,如果有连续数据过来,那数据就丢失了(低波特率可能不会);
2、DMA接收应使用连续模式,加上溢满/半满中断接收,可以避免你提到的“防止后面又有数据接收到,产生干扰”;接收方无法知道发送方数据大小,仅靠空闲中断接收是不可靠的。
参考这个帖子:http://www.openedv.com/forum.php?mod=viewthread&tid=317086&extra=
回复 支持 反对

使用道具 举报

32

主题

236

帖子

0

精华

高级会员

Rank: 4

积分
993
金钱
993
注册时间
2017-8-11
在线时间
137 小时
 楼主| 发表于 2021-2-22 16:44:19 | 显示全部楼层
Acuity 发表于 2021-2-21 10:51
1、进入空闲中断后,“关闭串口接收DMA通道,再去配置DMA”,这个不合理,如果有连续数据过来,那数据就丢 ...

DEMO我去看了,也下载过验证过,的确在高波特率的时候能用,特别适合于做高速透传的情况,不过我这里是打算用在MODBUS,因为协议的性质,数据量不会太大,诸如半溢满溢满中断这些,可能有点显得杀鸡用牛刀了,对于刚接触的小白,可能比较难上手理解吧。
你的东西是好东西,不过从这种应用来说,大道至简,越简单代码越具有维护性吧
谢谢分享
回复 支持 反对

使用道具 举报

2

主题

685

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3448
金钱
3448
注册时间
2017-7-4
在线时间
869 小时
发表于 2021-2-23 12:21:16 | 显示全部楼层
笨鸟想飞 发表于 2021-2-22 16:44
DEMO我去看了,也下载过验证过,的确在高波特率的时候能用,特别适合于做高速透传的情况,不过我这里是打 ...

回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-10 00:05

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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