文章目录
- 前言
- 一、使用开发板烧录dma代码不生效问题
- 二、一个工程同时使用uart2、uart3借助dma来传递
- 1.并行。
- 2.DMA "同时工作"的本质
- 3.总线访问的具体含义
- 4.实际效果
- 5.最佳实践
- 5.1 总线传输机制:
- 6.DMA传输中断的问题
- 总结
前言
记录一些使用stm32f4 dma过程中的疑问和一些问题
一、使用开发板烧录dma代码不生效问题
参考正点原子的实验18进行的测试。原版是dma2 uart1
我想改为dma1 uart2
用的新版的stlink(可以供电。。)
同时连接电源、stlink,typec-usb线
我发现烧录程序后,打开串口调试助手没有用(即没有显示信息)
一开始是有的,后期没了,特别是改完dma1 uart2之后一直以为自己没改对。。。
我把stlink拔掉然后重新上下点就开始哐哐收数据了。。。。
在此记录一下
二、一个工程同时使用uart2、uart3借助dma来传递
新手的问题:同时使用dma来传递uart2、uart3会不会导致只节省一半的时间(比如使用uart2发送数据不占用CPU时间了,但是uart3还得等地啊uart2这边发送完之后在重新弄这个过程。)
1.并行。
DMA1 资源分配(STM32F4)
- UART2 TX: DMA1 Stream6(通道4)
- UART3 TX: DMA1 Stream3(通道4)
同时传输时的行为:
-
并行传输能力:
- DMA1 有8个独立的数据流(Stream0-7)
- 不同流可以同时工作(如 UART2 TX 用 Stream6,UART3 TX 用 Stream3)
- 实际总线访问由 DMA 仲裁器调度(基于优先级)
-
冲突场景:
-
如果两个外设使用同一个流(如 UART2 TX 和 UART3 TX 都尝试用 Stream6)
-
如果同时访问相同内存区域(需确保源/目标地址不重叠)
-
2.DMA "同时工作"的本质
-
逻辑层面的并行:
-
不同DMA流可以独立配置和启动
-
它们可以同时处于激活状态
-
从程序员角度看,它们"同时工作"
-
-
物理层面的仲裁:
-
所有DMA流共享相同的总线资源(AHB总线矩阵)
-
当多个流同时请求总线访问时,仲裁器决定访问顺序
-
实际数据传输是分时复用总线资源的
-
3.总线访问的具体含义
-
总线类型:
-
AHB总线:连接CPU、DMA、内存控制器
-
APB总线:连接低速外设(如UART)
-
DMA需要在AHB总线上读取内存,在APB总线上写入外设
-
-
访问过程示例:
// UART2 TX传输(Stream6)
DMA1_Stream6->M0AR = (uint32_t)tx_buf; // 内存地址
DMA1_Stream6->PAR = (uint32_t)&USART2->DR; // 外设地址
每次传输需要:1.通过AHB总线从内存读取数据2.通过APB总线将数据写入UART数据寄存器
4.实际效果
-
对于UART这种慢速外设(115200bps ≈ 11.5KB/s)
-
DMA传输速度(STM32F4 @168MHz > 100MB/s)
-
即使有仲裁,多个UART的DMA传输在人类时间尺度上看起来是同时的
对于UART DMA传输,即使有总线仲裁,不同流的传输在实际应用中可以认为是并行工作的,因为仲裁产生的延迟远小于UART传输一个字节的时间(87μs@115200bps)。
5.最佳实践
-
优先级配置:
对实时性要求高的外设设高优先级 -
避免总线拥塞:
-
将DMA源/目标缓冲区放在不同内存块
SRAM1/SRAM2分开使用
-
使用内存对齐访问
__attribute__((aligned(4))) uint8_t buf1[256]; __attribute__((aligned(4))) uint8_t buf2[256];
-
5.1 总线传输机制:
-
STM32的总线系统(AHB/APB)以32位字为基本传输单位
-
每次总线访问至少传输4字节
-
非对齐访问会导致多次总线事务
6.DMA传输中断的问题
DMA_SxCR_TCIE 中断表示:DMA控制器已经将数据从内存传输到UART的数据寄存器(DR),而不是UART已经将数据完全发送出去。
详细过程分解
-
DMA传输完成:
-
DMA将最后一个字节写入USARTx->DR寄存器
-
DMA控制器设置传输完成标志(TCIF)
-
触发DMA传输完成中断
-
-
UART发送过程:
-
UART将数据从DR寄存器转移到发送移位寄存器
-
UART按波特率将数据逐位发送到TX引脚
-这个物理发送过程需要时间(例如115200bps下,1字节约需87μs)
-
总结
xxx