历史上的今天
今天是:2025年12月19日(星期五)
2022年12月19日 | STM32 DMA简述
2022-12-19 来源:zhihu
STM32 DMA简述
**DMA (Direct Memory Access) ** 直接内存存储器,在做数据传输时能够大大减轻CPU的负担。
DMA的作用
DMA提供了一个关于数据的高数传输通道,这个通道不占用CPU的资源。换句话说,通过DMA通道,你在传输大规模数据的时候CPU同时也能够去干其他事。
你可以控制DMA通道的接入口,灵活配置传输的数据源和目的地。以下几个是常用的DMA传输路径:
从外设到内存
从内存A区域传到内存B区域
从一个外设传输到另一个外设
从内存传输数据到外设
....
DMA流程分析
在stm32中,DMA是以类似外设的形式添加到内核之外的,下面我们来看具体的框图:

从上图我们可以看到,DMA通过系统总线连接到了APB1和APB2总线,也连接到了SRAM,Flash和Cortex内核。
我们发现,DMA是独立在内核之外的,其系统总线连接了所有模块,而且这个连接过程并没有经过内核。这也印证了前文所说的,在使用DMA通道传输数据时,并不占用CPU资源。
再仔细观察上图,图中除了总线之外,还有标有DMA请求字样的黑色箭头。外设需要向DMA发送请求,并应答通过后才能够启动传输。具体过程如下:
①在发生一个事件后,外设发送一个请求信号到DMA控制器。DMA控制器根据通道的优先权处理请求。
②当DMA控制器开始访问外设的时候,DMA控制器立即发送给外设一个应答信号。
③当外设从DMA控制器得到应答信号时,外设立即释放它的请求。
④在释放请求后,DMA控制器撤销应答信号。
DMA配置
在我们想要使用DMA的时候,我们该怎么启用他呢?我们通过一个配置函数来实现,在函数内部设置DMA传输的各种参数,最后使能它。代码如下:
void USARTx_DMA_Config(void)
{
DMA_InitTypeDef DMA_InitStructure;
// 开启DMA时钟
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
// 设置DMA源地址:串口数据寄存器地址*/
DMA_InitStructure.DMA_PeripheralBaseAddr = USART_DR_ADDRESS;
// 内存地址(要传输的变量的指针)
DMA_InitStructure.DMA_MemoryBaseAddr = (u32)SendBuff;
// 方向:从内存到外设
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
// 传输大小
DMA_InitStructure.DMA_BufferSize = SENDBUFF_SIZE;
// 外设地址不增
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
// 内存地址自增
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
// 外设数据单位
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
// 内存数据单位
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
// DMA模式,一次或者循环模式
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal ;
//DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
// 优先级:中
DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;
// 禁止内存到内存的传输
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
// 配置DMA通道
DMA_Init(USART_TX_DMA_CHANNEL, &DMA_InitStructure);
// 使能DMA
DMA_Cmd (USART_TX_DMA_CHANNEL,ENABLE);
}
这是一个将串口和DMA连接起来的配置代码,传输方向为从内存到外设。当然想要实现完整的功能,还需要其他代码,你可以参考机械工业出版社出的那本STM32库开发实战指南。
上一篇:STM32端口输入输出模式配置
史海拾趣
|
我的DS1302在LCD上不能正常显示,很多地方出现问号。 温度值正常显示,但是年月日,时间都显示问号。 5,6,7引脚都加了10K的上拉电阻还是不能解决。程序用ISIS仿真没有问题。 换过一块1302还是这样,不知道是芯片问题?还是晶振没有起振? 另 ...… 查看全部问答> |
|
求SectorEditor源代码或者原理 各位大虾,本人已经忙活了一周.至今没有找到在VISTA下写扇区的方法. 偶然发现SectorEditor可以做到,谁有代码的给我来一份 ! 邮箱: [email=liu ...… 查看全部问答> |
|
有史以来最花时间的芯片:ST7芯片ICP编程支持固件开发完成上个星期有ST代理商提出需要手持机支持ST7一款FLASH芯片。粗看资料后,时序并不难对付,即应允开发。感谢该代理商很快的寄来了样片。本以为2天即可搞定,不料竟花了4天时间,总计达30 ...… 查看全部问答> |
|
mx29lv128的16M的flash,板子上电可以从flash引导系统,但是在系统中用reset指令之后系统就没反应了,系统起来之后flash起始部分内容为FF,但是奇怪的是断电重启,系统依然能够从flash启动,有人知道这是为什么吗?… 查看全部问答> |
|
我今天在做一个RAM块的读写时遇到一个很奇怪的问题,我用的芯片是xilinx的spartan-3E 对RAM写操作的代码 always@(posedge write_clk or negedge rst_n) if(!rst_n) write_addr <= 0; else if(write_allow) write ...… 查看全部问答> |




