历史上的今天
今天是:2024年12月21日(星期六)
2018年12月21日 | STM32之DMA讲解及配置过程,附带代码说明
2018-12-21 来源:eefocus
DMA涉及概念讲解:
①:DMA即Direct Memory Access(直接存储器存取),是STM32特有的外设。大容量STM32产品集成了两个DMA,分别是DMA1和DMA2,。其中DMA1有7个通道,DMA2有5个通道,具体每个通道连接的外设可以参考STM32芯片的数据手册。
②:通过DMA可以将数据在两个不同的地址之间进行传递,如存储器到外设寄存器,外设寄存器到存储器,也可以从存储器到存储器之间。
③:当两个数据在不同的地址之间传递时,需要在程序配置中确定每次传输的字节数,确定是字节、半字还是字。
④:DMA的每个通道优先级是可变的。以DMA1为例,它有7个通道,可以配置每个通道的优先级为很高、高、中,低四种中的一种。若两个通道的优先级一样,当两个通道同时有DMA请求时,通道号小的优先级则高。
⑤:DMA每次传输的数据量是可变的,DMA中有一个专门的寄存器用于存储这个数据量值。这个寄存器是32位的,但高16位全部保留为0,实际上起作用的是低16位,所以每次传输的最大数据量值是65536。
⑥:⑤中所示,比如设置数据量值为100,若DMA传输设置为循环模式,则100个数据传输完成后,将自动进行下一轮传输。若设置成非循环模式,则需要先关闭DMA,再设置数据量值,再开启DMA,才能进行下一轮传输。
⑦:DMA在传输过程中,常用的有3种标志位--传输完成一半、传输全部完成,传输过程发生错误。可以在程序中设置开启对应标志位的中断,当标志位到来时,会执行中断服务程序。也可不开启相应标志位的中断。
⑧:确定好要传输的外设和存储器地址之后,需要在程序中设置传输方向,即传输方向是从外设到寄存器,还是从寄存器到外设。
⑨:DMA一般用来在外设和存储器之间进行数据传输,所以还要设置外设地址及存储器地址是否递增。例如定义一个数组,char data[100],外设地址为&UART->TX,若将数组中的100个数据传输到UART->TX中,则存储器地址需要每次递增,而外设地址不需要递增。
DMA配置过程:
①:确定传输数据的外设和寄存器地址
②:确定传输方向
③:确定每次传输的数据量值
④:确定传输数据的字节数
⑤:配置通道优先级
⑥:确定传输是循环模式还是非循环模式
⑦:如若需要开启中断,则开启响应位中断
注意:DMA也可以从存储器到存储器,但存储器到存储器过程只能为非循环模式。
程序讲解:
例:程序实现功能是将存储器中的数据传输到串口的发送寄存器TX,每次传输的数据量是100,非循环模式传输。
void MYDMA_Config(DMA_Channel_TypeDef* DMA_CHx, u32 cpar, u32 cmar, u16 cndtr)
{
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); //开启时钟
DMA_DeInit(DMA_CHx); //初始化通道,设置为默认配置
DMA1_MEM_LEN=cndtr;
DMA_InitStructure.DMA_PeripheralBaseAddr = cpar;//外设地址
DMA_InitStructure.DMA_MemoryBaseAddr = cmar;//存储器地址
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;//传输方向,从内存到外设
DMA_InitStructure.DMA_BufferSize = cndtr;//每次循环传输的数据量值
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//外设地址不变
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;//内存地址每次加1
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;//字节传输
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;//字节传输
DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;//非循环模式
DMA_InitStructure.DMA_Priority = DMA_Priority_Medium;//设置优先级--中
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;//不是内存到内存
DMA_Init(DMA_CHx, &DMA_InitStructure);//初始化DMA配置过程
}
//开启一次传输
void MYDMA_Enable(DMA_Channel_TypeDef*DMA_CHx)
{
DMA_Cmd(DMA_CHx, DISABLE ); //关闭DMA
DMA_SetCurrDataCounter(DMA_CHx,DMA1_MEM_LEN);//重新确定每次循环要传输的数据量值
DMA_Cmd(DMA_CHx, ENABLE); //再次开启DMA
}
int main()
{
u8 SendBuff[100]; //存储器数据
MYDMA_Config(DMA1_Channel4, (u32)&USART1->DR, (u32)SendBuff, 100);//调用函数
MYDMA_Enable(DMA1_Channel4); //开启一次传输
}
史海拾趣
|
我按照图1的电路接法,然后根据DS18B20的数据手册时序图编写代码,但总是85℃。。。请遇到过这种情况的电子爱好者指导一下: /***********ds18b20子程序*************************/ /******************************ds1820程序****************** ...… 查看全部问答> |
|
板子(数字)上电始会有一个大的过冲,大概有0.60A(12V上电,通过电源芯片转为3.3V输出供电),而且持续几秒,才会降到0.09A。 板上差不多只有一些SRAM,SDRAM,68013还是RS232电平转换芯片,电源块测过没问题,但是一旦连上后端电路,再上电就会 ...… 查看全部问答> |
|
请教大家一个问题: 我在wince下的edit控件中输入汉字、数字、字母,并保存在临时文件中。当我再次打开对话框,把临时文件中的东东全部放回edit控件时,数字和字母能正确显示,但是汉字只显示问号“?”!请问这是什么原因? 下面是代码 当edit ...… 查看全部问答> |
|
时间:2007年03月31日下午1:00-5:00 地点:上海电力学院平凉路校区小礼堂(暂定) 路线:上海市杨浦区平凉路2103号 近隆昌路 专题1 基于ARM的嵌入式开发(13:30-14:30) 专题2 Windows CE揭秘(14:40-15:40) 专题3 嵌入式Linux系统平台构建 ...… 查看全部问答> |
|
最easy的一个问题,VxWorks下怎么控制评估板上的LED ? VxWorks + ARM7 4510 的评估板, 在ADS下裸机编程调试通过了的一个LED闪灯程序。 把它加入到一个在VxWorks下已经可以运行的程序里面去后。(当然相应的头文件都加上了的) 编译下载,不能闪灯 ...… 查看全部问答> |
|
本帖最后由 guaiguaidou 于 2015-7-27 10:48 编辑 最近学习特权同学的《深入浅出玩转FPGA》一书,想对里面的一个实验进行功能仿真(在书的p60) 但一直都得不到理想情况,请问这个是什么原因? 这是verilog代码: module handshack ( ...… 查看全部问答> |




