干货 | STM32串口DMA收发机制
扫描二维码
随时随地手机看文章
1 前言
直接存储器访问(Direct Memory Access),简称DMA。DMA是CPU一个用于数据从一个地址空间到另一地址空间“搬运”(拷贝)的组件,数据拷贝过程不需CPU干预,数据拷贝结束则通知CPU处理。因此,大量数据拷贝时,使用DMA可以释放CPU资源。DMA数据拷贝过程,典型的有:
- 内存—>内存,内存间拷贝
- 外设—>内存,如uart、spi、i2c等总线接收数据过程
- 内存—>外设,如uart、spi、i2c等总线发送数据过程
2 串口有必要使用DMA吗
串口(uart)是一种低速的串行异步通信,适用于低速通信场景,通常使用的波特率小于或等于115200bps。对于小于或者等于115200bps波特率的,而且数据量不大的通信场景,一般没必要使用DMA,或者说使用DMA并未能充分发挥出DMA的作用。
- 对于发送,使用循环发送,可能阻塞线程,需要消耗大量CPU资源“搬运”数据,浪费CPU
- 对于发送,使用中断发送,不会阻塞线程,但需浪费大量中断资源,CPU频繁响应中断;以115200bps波特率,1s传输11520字节,大约69us需响应一次中断,如波特率再提高,将消耗更多CPU资源
- 对于接收,如仍采用传统的中断模式接收,同样会因为频繁中断导致消耗大量CPU资源
3 实现方式
4 STM32串口使用DMA
关于STM32串口使用DMA,不乏一些开发板例程及网络上一些博主的使用教程。使用步骤、流程、配置基本大同小异,正确性也没什么毛病,但都是一些基本的Demo例子,作为学习过程没问题;实际项目使用缺乏严谨性,数据量大时可能导致数据异常。
- STM32F030C8T6
- UART1/UART2
- DMA1 Channel2—Channel5
- ST标准库
- 主频48MHz(外部12MHz晶振)
5 串口DMA接收
5.1 基本流程
5.2 相关配置
关键步骤
"半满中断",即是数据搬运到buf大小的一半时,可以产生一个中断信号。基于这个机制,我们可以实现双缓存功能,只需将buf空间开辟大一点即可。
【1】第一步,DMA将数据搬运完成buf的前一半时,产生“半满中断”,CPU来拷贝buf前半部分数据 【2】第二步,DMA继续将数据搬运到buf的后半部分,与CPU拷贝buf前半部数据不会冲突 【3】第三步,buf后半部分数据搬运完成,触发“溢满中断”,CPU来拷贝buf后半部分数据 【4】执行完第三步,DMA返回执行第一步,一直循环
UART2 DMA模式接收配置代码如下,与其他外设使用DMA的配置基本一致,留意关键配置:
-
串口接收,DMA通道工作模式设为连续模式
-
使能DMA通道接收buf半满中断、溢满(传输完成)中断
-
启动DMA通道前清空相关状态标识,防止首次传输错乱数据
void bsp_uart2_dmarx_config(uint8_t *mem_addr, uint32_t mem_size)
{
DMA_InitTypeDef DMA_InitStructure;
DMA_DeInit(DMA1_Channel5);
DMA_Cmd(DMA1_Channel5, DISABLE);
DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)