stm32上DMA的学习笔记
来源:互联网 发布:新理念网络测试答案 编辑:程序博客网 时间:2024/05/29 16:41
第一个问题:DMA是什么?
DMA,Directmemory access,顾名思义,不通过CPU,直接访问内存,实现内存和外围模块之间数据的高速传输,且它是一个独立的模块,类似于ADC、PWM的存在。主要功能就是将所有外设映射的寄存器“连接”起来。
第二个问题,这样做有什么好处呢?
既然不涉及CPU的参与,那么CPU就可以有更多时间来处理其他问题,大大提高了CPU的运行效率。
在一般的STM32上,有两个DMA(DMA1和DMA2),分别有7个和5个通道。每个通道专门用来管理一个或多个外设对储存器的访问请求,即开辟了一条RAM和I/O设备的“直通车”
DMA的操作也是很简单的,你需要做的,就是提供一个载有传送数据的buff地址、I/O的地址以及传送数据的大小,即可完成简单的DMA实验,在这一切配置好以后,CPU就可以完全不用管I/O设备和RAM之间的“勾当”了。
DMA一共有 6个寄存器:
1、 DMA_ISR,从名字就可以看出来,这个寄存器,是掌管中断开关的寄存器,例如当传送完成以后,我们需要查询TCIFx这个位来关闭DMA,要注意的是,这个寄存器是只读的。
2、 DMA_IFCR,这个寄存器,是用来给楼上扫战场的,因为楼上具有只读这一特性,所以,我们需要一个“清道夫”来清除DMA_ISR的对应位。也就是话说,在DMA_ISR被置位后,我们必须通过想该寄存器对应的位写入来清除。
3、 DMA_CCRx,这个寄存器掌管通道的配置,你到底要用几通道?买通我再说!
4、 DMA_CNDTRx,这个寄存器掌管第X通道每次传输的数据量,范围为0~65535,值得一提的是,这个值会随着传输的进行而减少,这样我们就可以计算出数据剩余量了。
5、 DMA_CPARx,这个寄存器掌管外设(I/O设备)的地址。(我要给你东西,总要知道你在哪里不是?)
6、 DMA_CMARx,这里存放了储存器的地址。(淘宝卖家给你寄东西,也要填上它自己的名字不是?)
OK!有了这些寄存器,我想你应该知道如何使用DMA了。下面,有一些细节,你可能要注意一下。
这张图上写明了不同外设所对应的通道,就是说,不是任意外设都是使用任意DMA的,毕竟,我们国家也是要讲一夫一妻制度的不是?
看!这个就是DMA的配置函数,没骗你吧,你所需要提供的,就只有通道号,I/O地址和BUFFER地址以及数据量大小提供出来就行了,这个就不用多说了吧。
有了上面的工作,现在,你需要的,只需要调用DMACmd函数来使能DMA,紧跟着来一记MYDMA_Enable(),OK,大功告成,以后你每次调用MYDMA_Enable(),DMA就完成一次传送,就是这么简单。
最后,附上一个可以运行的STM32代码,实现的功能为,按下key1以后,LCD显示。
int main(void)
{
u16 i;
u8 t=0;
u8 j,mask=0;
uint16_t pro=0;//½ø¶È
float a;
uint8_t LogoStr[] = "PressKEY1:";
uint8_t Logoma[] ="Transimit...";
SZ_STM32_LEDInit(LED1);
SZ_STM32_LEDInit(LED2);
SZ_STM32_LEDInit(LED3);
SZ_STM32_LEDInit(LED4);
SZ_STM32_SysTickInit(1000);
SZ_STM32_KEYInit(KEY1,BUTTON_MODE_GPIO);
NVIC_Configuration();
SZ_STM32_COMInit(COM2, 2400);
SZ_STM32_LCDInit();
MYDMA_Config(DMA1_Channel7,(u32)&USART2->DR,(u32)SendBuff,5168);
j=sizeof(TEXT_TO_SEND);
for(i=0;i<5168;i++)
{
if(t>=j)//¼ÓÈë»»Ðзû
{
if(mask)
{
SendBuff[i]=0x0a;
t=0;
}else
{
SendBuff[i]=0x0d;
mask++;
}
}
else
{
mask=0;
SendBuff[i]=TEXT_TO_SEND[t];
t++;
}
}
while(1)
{
if(SZ_STM32_KEYGetState(KEY1) == 0)
{
USART_DMACmd(USART2,USART_DMAReq_Tx,ENABLE);
MYDMA_Enable(DMA1_Channel7);//¿ªÊ¼Ò»´ÎDMA´«Ê䣡
while(1)
{
if(DMA_GetFlagStatus(DMA1_FLAG_TC7)!=RESET) //ÅжÏͨµÀ7´«ÊäÍê³É
{
DMA_ClearFlag(DMA1_FLAG_TC7); break;
}
pro=DMA_GetCurrDataCounter(DMA1_Channel7); LCD_DisplayStringLine(LCD_LINE_1, (uint8_t *)LogoStr);
LCD_DisplayStringLine(LCD_LINE_2,(uint8_t *)Logoma);
a= 1-(float)pro/5168;
a*=100;
pro=a;
LCD_DisplayChar(LINE(3),LCD_Currentfonts->Width * 1, (0x30 + (pro/10)%10));
LCD_DisplayChar(LINE(3),LCD_Currentfonts->Width * 2, (0x30 + (pro%10)));
LCD_DisplayChar(LINE(3),LCD_Currentfonts->Width * 3, '%');
}
LCD_DisplayChar(LINE(3),LCD_Currentfonts->Width * 0, (0x30 + 1));
LCD_DisplayChar(LINE(3),LCD_Currentfonts->Width * 1, (0x30 + 0));
LCD_DisplayChar(LINE(3),LCD_Currentfonts->Width * 2, (0x30 + 0));
}
}
}
- stm32上DMA的学习笔记
- STM32-DMA学习笔记
- STM32学习笔记之ADC--DMA方式
- STM32 使用DMA处理ADC 学习笔记!!
- stm32学习笔记——DMA
- STM32学习笔记之DMA使用
- stm32寄存器版学习笔记08 DMA
- stm32学习笔记 F1系列DMA
- STM32笔记---DMA(USART)的演示
- STM32之DMA的配置笔记
- STM32 DMA笔记(转贴)
- STM32 DMA学习
- STM32 DMA学习
- 学习Stm32--DMA
- stm32学习之DMA
- STM32的DMA中断
- STM32 DMA的特性
- STM32笔记(三)ADC、DMA、USART的综合练习
- 程序员之路(高手的经验之谈)
- View机制深入学习(一)
- 黑马程序员_java环境配置
- 黑马程序员——File类
- 黑马程序员——java基础——面向对象
- stm32上DMA的学习笔记
- 一阶逻辑 备忘
- HUD 2051 Bitset
- Longest Common Substring最长公共子字符串
- Android实战简易教程-第五十八枪(AlarmManager类用法研究小实例)
- Shader 学习历程(一)——第一个shader
- 使用RecyclerView实现带Header和Footer的GridView
- leetcode刷题,总结,记录,备忘 77
- ios下使用AFNetworking通过Nginx服务器实现大文件上传