news 2026/5/21 13:14:03

stm32的DMA学习笔记 串口空闲中断+dma

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
stm32的DMA学习笔记 串口空闲中断+dma

1.DMA结构框架

2.DMA名称的详细解析

通道:数据的高速通道 ,每个通道可以链接指定的外设,(DMA2)可以将通道链接到内存。

流:理解为货车,DMA的使用单位就是流,使能dma就是以流作为基本单位(让那个货车可以发车)判断优先级,就是判断流的优先级。(可以使用多个流,但是一个流只能绑定一个通道)

FIFO:突发模式的前提条件,将数据寄存起来,当满足突发的数据量后发送。

突发模式:批量的装卸货物,简单理解就是一次性给目标地址发送几个字节的数据,比如一次给目标发送4个字节的数据,如果不使用突发则就是一次发送一个字节。

将它分化成三个部分

  • 第一部分: MSIZE(内存数据宽度):相当于“包裹的大小”。
    • 字节= 小包(8位)
    • 半字= 中包(16位)
    • = 大包(32位)
  • 第二部分:FIFO 容量:STM32 的 DMA FIFO 总容量固定是4 个字(即 16 个字节)
  • 第三部分:MBURST(内存突发):相当于“卸货方式”。
    • INCR4= 一口气卸 4 次货。
    • INCR8= 一口气卸 8 次货。
    • INCR16= 一口气卸 16 次货。
    • 节拍:其实就是字节,四节拍就是四个字节

举例:

1.将MSIZE设置成字节,FIFO级别设置成1/4, MBURST设置成4个节拍突发1次。

分析:单位是字节级别是1/4 16/4=4字节MBURST 突发传输四个字节且只突发一次

总结:一次性传输4个字节到目标源。

2.将MSIZE设置成字节,FIFO级别设置成1/2, MBURST设置成4个节拍突发2次。

分析:单位字节级别1/216/2=8, MBURST突发传输四个字节且突发两次(发送8字节)

总结:分2次突发,发送8个字节到目标源

虽然从宏观上看,这 8 个字节是一起发出去的,但在总线时序上,它们是两个独立的 INCR4 事务

3.编程实战

//在usart中开启空闲中断

USART_ITConfig(USART1, USART_IT_IDLE, ENABLE);

void dma_initconfig(void)
{
DMA_InitTypeDef dma_inittypedef;

// 1. 必须先开启 DMA2 的时钟!(STM32F4中DMA2挂载在AHB1总线上)
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE);

DMA_DeInit(DMA2_Stream1);

while(DMA_GetCmdStatus(DMA2_Stream1) == DISABLE)
{
//等待dma流初始化完成。
}

//选定流通道
dma_inittypedef.DMA_Channel =DMA_Channel_2;
//外设到内存 传输放向
dma_inittypedef.DMA_DIR = DMA_DIR_PeripheralToMemory;
//DMA缓冲区500
dma_inittypedef.DMA_BufferSize = 500;
//单次传输
dma_inittypedef.DMA_Mode =DMA_Mode_Normal;
//DMAL流的优先级 当总线冲突时,高优先级的流会先传输
dma_inittypedef.DMA_Priority = DMA_Priority_Low ;

//外部内存通道地址 内存目标地址
dma_inittypedef.DMA_PeripheralBaseAddr =(uint32_t)&(USART1->DR);
//外设传输单位大小
dma_inittypedef.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
//外设地址不递增
dma_inittypedef.DMA_PeripheralInc =DMA_PeripheralInc_Disable;
//外设端突发传输 一次传输几个传输单元 配合FIFO寄存器
dma_inittypedef.DMA_PeripheralBurst = DMA_PeripheralBurst_Single;

//内存源地址
dma_inittypedef.DMA_Memory0BaseAddr = (uint32_t)buf;
//内存传输单位大小
dma_inittypedef.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
//内存地址递增
dma_inittypedef.DMA_MemoryInc = DMA_MemoryInc_Enable;
//内存端突发传输 一次传输几个传输单元 可以提高传输量 配合FIFO寄存器
dma_inittypedef.DMA_MemoryBurst = DMA_MemoryBurst_Single;

//FIFO配置 不开启
dma_inittypedef.DMA_FIFOMode = DMA_FIFOMode_Disable;
//dma_inittypedef.DMA_FIFOThreshold =

DMA_Init(DMA2_Stream1, &dma_inittypedef);

//开启DMR 开启流1
DMA_Cmd(DMA2_Stream1, ENABLE);
}

extern uint8_t buf[500];

void USART1_IRQHandler(void) {

// 判断是否是串口1触发了空闲中断(即一帧数据接收完毕)

if (USART_GetITStatus(USART1, USART_IT_IDLE) != RESET)

{

// 【第一步】必须先读取 SR 和 DR 寄存器来清除 IDLE 标志位

// 标准库中调用一次 USART_ReceiveData 即可自动完成这个硬件清除流程USART_ReceiveData(USART1);

// 【第二步】暂停当前的 DMA 传输流,防止后续数据继续覆盖 buf 数组DMA_Cmd(DMA2_Stream1, DISABLE);

// 【第三步】计算这一帧到底接收了多少个字节的数据

// 原理:DMA 初始配置的总大小(500) - 当前剩余还没搬运的数量 = 实际已接收数量uint16_t data_len = 500 - DMA_GetCurrDataCounter(DMA2_Stream1);

// 【第四步】在这里处理你刚刚接收到的不定长数据

// 例如:解析协议、打印日志、转发数据等

process_received_data(buf, data_len);

// 【第五步】重新设置 DMA 下一次要搬运的总量(恢复为500)

DMA_SetCurrDataCounter(DMA2_Stream1, 500);

// 【第六步】再次使能 DMA 流,准备接收下一帧数据

DMA_Cmd(DMA2_Stream1, ENABLE); }

}

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/21 13:13:47

前端工程师必看:收藏这份AI工程师转型指南,告别焦虑,拥抱未来!

文章指出,前端工程师面临AI冲击和职业瓶颈,建议转型AI工程师而非止步于全栈。转型关键在于补齐服务端认知,利用AI工具快速实践,从被动工作转向主动发现问题、定义问题、解决问题。文章强调,AI时代最重要的是能调度资源…

作者头像 李华
网站建设 2026/5/21 13:13:47

服务器安全防护终极指南:3分钟部署开源IP拦截系统

服务器安全防护终极指南:3分钟部署开源IP拦截系统 【免费下载链接】IPBan Since 2011, IPBan is the worlds most trusted, free security software to block hackers and botnets. With both Windows and Linux support, IPBan has your dedicated or cloud server…

作者头像 李华
网站建设 2026/5/21 13:13:07

安捷伦E8257D/E8267D信号源不开机、输出不正常故障排查

安捷伦E8257D/E8267D信号源作为射频微波测试领域的常用设备,广泛应用于通信、半导体等行业,长期高负荷运行后,不开机、输出不正常等故障十分常见,给测试工作带来诸多困扰。常见故障一:安捷伦E8257D/E8267D不开机不开机…

作者头像 李华
网站建设 2026/5/21 13:12:39

邦芒支招:5个技巧让你工作效率翻倍

工作中,我们常常陷入“忙而盲”的困境——看似整天忙碌,却没完成多少核心任务,甚至频繁加班仍追不上进度。其实,高效工作从不是“拼时间”,而是“拼方法”,掌握这几个简单易操作的技巧,就能摆脱…

作者头像 李华
网站建设 2026/5/21 13:12:10

Windhawk终极指南:免费开源的Windows模块化定制工具

Windhawk终极指南:免费开源的Windows模块化定制工具 【免费下载链接】windhawk The customization marketplace for Windows programs: https://windhawk.net/ 项目地址: https://gitcode.com/gh_mirrors/wi/windhawk 你是否厌倦了Windows千篇一律的界面&…

作者头像 李华
网站建设 2026/5/21 13:09:19

3分钟掌握在Windows上安装安卓应用的完整指南

3分钟掌握在Windows上安装安卓应用的完整指南 【免费下载链接】APK-Installer An Android Application Installer for Windows 项目地址: https://gitcode.com/GitHub_Trending/ap/APK-Installer 您是否曾想过,在Windows电脑上运行安卓应用就像打开一个普通W…

作者头像 李华