打印
[其他ST产品]

STM32---UART使用DMA数据传输

[复制链接]
512|31
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
尽快回复过|  楼主 | 2023-9-30 23:27 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

当预先不知道要接收的数据时,如何使用 DMA 在 UART 上读取数据的信息。
在STM32中,通常有以下几种模式:

  • 轮询模式
    程序必须轮询状态位以检查是否已收到新字符并以足够快的速度读取它以获得所有字节



使用特权

评论回复
沙发
尽快回复过|  楼主 | 2023-9-30 23:27 | 只看该作者
优点
很容易实现,但在真正项目中的应用很少

使用特权

评论回复
板凳
尽快回复过|  楼主 | 2023-9-30 23:27 | 只看该作者
缺点
在突发数据中很容易错过接收到的字符
仅适用于低波特率
应用程序必须非常快速地检查是否收到新的数据

使用特权

评论回复
地板
尽快回复过|  楼主 | 2023-9-30 23:28 | 只看该作者
中断模式(无DMA):
UART触发中断,CPU跳转到服务程序处理数据接收

使用特权

评论回复
5
尽快回复过|  楼主 | 2023-9-30 23:28 | 只看该作者
优点
目前程序中最常用的方法
在低速率下工作良好,115200 波特

使用特权

评论回复
6
尽快回复过|  楼主 | 2023-9-30 23:28 | 只看该作者
缺点
为每个接收到的字符执行中断服务程序
可能会在具有许多中断的高性能 MCU 中停止其他任务
一次接收突发数据时可能会停止操作系统

使用特权

评论回复
7
尽快回复过|  楼主 | 2023-9-30 23:28 | 只看该作者
DMA 模式:
DMA 用于在硬件级别将数据从 USART RX 数据寄存器传输到用户存储器。 除了在必要时由应用程序处理接收到的数据,此时不需要应用程序交互

使用特权

评论回复
8
尽快回复过|  楼主 | 2023-9-30 23:28 | 只看该作者
优点
i.从 USART 外设到内存的传输是在硬件完成的,无需 CPU干涉
ii.可以很容易地与操作系统一起工作
iii.针对最高波特率 > 1Mbps 和低功耗应用进行了优化
vi.在大量数据突发的情况下,增加数据缓冲区大小可以改进功能

使用特权

评论回复
9
尽快回复过|  楼主 | 2023-9-30 23:28 | 只看该作者
缺点
i.DMA 硬件必须事先知道要传输的字节数
ii.如果通信失败,DMA 可能不会通知应用程序所有传输的字节

本文仅关注接收未知数据长度的 DMA 模式。

使用特权

评论回复
10
尽快回复过|  楼主 | 2023-9-30 23:28 | 只看该作者
STM32中的DMA
在STM32中DMA有norma和circular两种模式,每种模式在数据进行传输时需要告知传输数据的大小

Normal mode:
DMA 开始传输数据,当它传输完成后就会停止。下一次开始需要手动处理。
Circular mode:
DMA从传输开始,当它传输完成后会自动按照相同配置重新传输,周而复始直至被控制停止或传输发生错误。

使用特权

评论回复
11
尽快回复过|  楼主 | 2023-9-30 23:28 | 只看该作者
在这两种mode中有两种中断模式:

达到半传输(Half-Transfer complete (HT) interrupt):DMA 数据传输达到一半时 HTIF 标志位被置 1,如果使能 HTIE 中断控制位将产生达到半传输中断;

使用特权

评论回复
12
尽快回复过|  楼主 | 2023-9-30 23:29 | 只看该作者
传输完成(Transfer-Complete (TC) interrupt):DMA 数据传输完成时 TCIF 标志位被置 1,如果使能 TCIE 中断控制位将产生传输完成中断;

使用特权

评论回复
13
尽快回复过|  楼主 | 2023-9-30 23:29 | 只看该作者
我们通过 DMA 收到有关 HT 或 TC 事件的通知。 想象一下假设要接收 20 个字节,但它仅接收 14 个会发生什么呢:

程序会等待数据到达20个时才会处理
如果设置了HT中断,则会知道目前至少已经接受到了10个数据,不会告知剩下的4个数据。

使用特权

评论回复
14
尽快回复过|  楼主 | 2023-9-30 23:29 | 只看该作者
我们必须解决这种情况!

使用特权

评论回复
15
尽快回复过|  楼主 | 2023-9-30 23:29 | 只看该作者
U(S)ART
大多数 STM32 系列U(S)ART都有带空闲(IDLE )检测。 如果没有IDLE检测,其中一些具有可编程延迟的接收器超时功能。 如果这甚至不可用,则应用程序可以仅使用带有 DMA 的轮询模式,示例如下。

使用特权

评论回复
16
尽快回复过|  楼主 | 2023-9-30 23:29 | 只看该作者
IDLE模式或接收超时中断,可用于判断数据有么有接收完整。

使用特权

评论回复
17
尽快回复过|  楼主 | 2023-9-30 23:29 | 只看该作者
假设我们以 115200 波特接收了 10 个字节。 115200 波特的每个字节在 UART 线上大约需要 10us,总共 100us。
IDLE中断将在检测到 RX 线上的 1 个字符不活动时通知应用程序,这意味着在最后一个字符后 10us 之后。
应用程序可以对此事件做出反应并相应地处理数据。

使用特权

评论回复
18
尽快回复过|  楼主 | 2023-9-30 23:29 | 只看该作者
DMA+U(S)ART
还是上述例子,程序等待接收20个字节,但实际只接收到了14个数据,如何解决这一问题。

使用特权

评论回复
19
尽快回复过|  楼主 | 2023-9-30 23:29 | 只看该作者
解决方案
将 DMA 置于循环模式以避免 DMA 传输完成后还得手动配置。

申请一块大的内存,足够装下最大长度数据包

如果波特是11500,突发最大数据长度100,要保证可以装下这100个数据。
最好将接收缓冲区设置为至少 100 字节,除非可以确保处理方法比数据突发更快
在 115200 波特时,100 字节也就用1ms 时间就传输完成了

使用特权

评论回复
20
尽快回复过|  楼主 | 2023-9-30 23:29 | 只看该作者
DMA HT/TC + U(S)ART IDEl
本节描述了可能的 4 种可能情况和另外一种情况,解释了应用程序需要 HT/TC 事件的原因

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

36

主题

517

帖子

0

粉丝