历史上的今天
今天是:2025年03月04日(星期二)
2020年03月04日 | 【菜鸟入门】stm32 之 DMA
2020-03-04 来源:eefocus
DMA是个好东西,他可以帮助CPU分担好多工作,减轻CPU的工作压力,我们可以一边传输数据,一边干别的事情,很不错!
今天可谓是配置的好艰辛啊,看电视把我看蒙了,好多注意事项都木有看见,浪费了我好多时间。
好吧,开始进入主题!
时钟配置我就不用罗嗦了!大家自己去RCC里面的AHBENR找:
RCC->AHBENR |= 1<<0;//DAM1 Clock Enable
主要来看看DMAx的控制寄存器CCR



这个寄存器看着很容易理解,今天对控制寄存器有了新的认识,一般的寄存器可能要在控制寄存器的某一位关闭或者打开才能修改,而控制寄存器基本上可以在任意时刻进行修改,所以,在配置控制寄存器的时候我们没必要考虑那么多!
我今天准备把一个字符串通过DMA与USART1建立一个通道,把数据发送出去!
所以我们不从外设读数据,我们需要Read From Register,如果我们从ADC里面读数据我们就可以把这位置0
dma->CCR |= 1<<4; //Read from register
我们可以采用循环发送,也可以不循环发送,如果是ADC的话,那就用循环发送
dma->CCR &= ~(1<<5); //normal mode
因为USART1的地址不进行偏移或者改变
dma->CCR &= ~(1<<6); //Device Address non-Rise
在一个字符串中我们要不断寻址去发送该为地址上的数据
dma->CCR |= 1<<7; //Memary Address Rise
所有设备和存储都按8bit进行存储和读取
dma->CCR &= ~(3<<8); //Device 8 Bit Data
dma->CCR &= ~(3<<10); //Memary 8 Bit
在设置两位或两位以上的数据是一定要把其全部清空在进行设置,这样方便一点
dma->CCR &= ~(3<<12); //clear 12:13
dma->CCR |= 1<<12; //Set Priority level
14bit的配置我不用说了,大家看一下就肯定知道了
dma->CCR &= ~(1<<14); //non M2M mode
DMA还有这么几个寄存器
DMA_CNDTR :要发送的数据个数
DM_CPAR:外设地址寄存器
DM_CMAR:存储器地址寄存器
这3个寄存器必须在DMA_CCRx的EN=0时才能进行修改!我今天就在这个地方沦陷了,后来看了李想老师的视频,他的感觉他的配置有问题,但是还是。。。
可能我们的板子不一样吧,反正我他那几个配置违背了EN=0时才能修改的原则
dma->CCR &= ~(1<<0);
dma->CPAR = cpar;
dma->CMAR = cmar;
dma->CNDTR = cndtr;
dma->CCR |= 1<<0;
还有其他规则,大家可以看看!DMA还是相对比较简单的,不过是建立在你细心的基础上!
另外我们要用到USART1的发送,所以我们也要去打开USART1里面的dma功能
在USART1的控制寄存器里面有这么两个配置:

我们要什么功能就选什么功能了!
这里我选USART1->CR3 |= 1<<7;
好了,那几天就这样,下面附上我的代码
/* dma.c */
#include #include "stdio.h" #include "usart.h" #include "init.h" void dma1_init(DMA_Channel_TypeDef * dma) { RCC->AHBENR |= 1<<0;//DAM1 Clock Enable dma->CCR |= 1<<4; //Read from register dma->CCR &= ~(1<<5); //normal mode dma->CCR &= ~(1<<6); //Device Address non-Rise dma->CCR |= 1<<7; //Memary Address Rise dma->CCR &= ~(3<<8); //Device 8 Bit Data dma->CCR &= ~(3<<10); //Memary 8 Bit dma->CCR &= ~(3<<12); //clear 12:13 dma->CCR |= 1<<12; //Set Priority level dma->CCR &= ~(1<<14); //non M2M mode USART1->CR3 |= 1<<7; } void dma1_enable(DMA_Channel_TypeDef * dma,u32 cpar,u32 cmar,u32 cndtr) { #ifdef __DEBUG char buff[255]; #endif dma->CCR &= ~(1<<0); dma->CPAR = cpar; dma->CMAR = cmar; dma->CNDTR = cndtr; dma->CCR |= 1<<0; #ifdef __DEBUG sprintf(buff,"Initialize (u32)dma,(u32)cpar,(u32)cmar,cndtr); rs232_send_str(buff,strlen(buff)); sprintf(buff,"Initialize.....ndma:0x%08xnCPAR:0x%08xnCMAR:0x%08xnCNDTR:0x%08xn", (u32)dma,dma->CPAR,dma->CMAR,dma->CNDTR); rs232_send_str(buff,strlen(buff)); #endif } 主函数: #include #include "init.h" #include "usart.h" #include "dma.h" #include "stdio.h" int main() { char str[512]; rs232_init(CPU_72M,9600); RCC->APB2ENR |= 1<<4; GPIOC->CRH = 0x33333333; GPIOC->ODR |= 0xff00; sprintf(str,"This is a DMA1 Channel4 Test!n"); dma1_init(DMA1_Channel4); while(1) { delay_ms(1000); dma1_enable(DMA1_Channel4,(u32)&USART1->DR,(u32)str,strlen(str)); while(1) { if(DMA1->ISR&(1<<13)) break; delay_ms(1000); } DMA1->IFCR |= 1<<13; } } 效果图: PS:最近在研究库,感觉库挺好用的,所以关于寄存器配置的进度比较慢!
,
史海拾趣
|
是一个16*16的繁体点阵字库,目前只发现pudn这个沙比网站有: http://www.pudn.com/downloads94/sourcecode/others/detail372553.html 希望有账号的大大能帮我下一份 字库就传到eeworld上的资源共享上吧,这样也算是造福大家.....顺便再鄙视一下 ...… 查看全部问答> |
|
DDK可以编译成两种版本。一个Free另外一个好象是Checked版本 有什么不同。 有时候我用Checked编译通过 Free不能通过编译 晕。 还有 VC里面不能 _asm mov ebp,esp 不能修改ebp的值吗?… 查看全部问答> |
|
我用的是神州stm32103系列的芯片,用开发板提供的程序i2c读写的读写函数放在液晶显示初始化ili9320的初始化程序下面就不能运行,我跟踪了程序,是在i2c读写函数的checkevent这里出现死循环, 导致程序没有办法继续往下执行,求指点,很急。 ...… 查看全部问答> |
|
本帖最后由 paulhyde 于 2014-9-15 03:48 编辑 2012TI杯山东省大学生电子设计竞赛 基本仪器和主要元器件清单 1、基本仪器清单 数字电桥 直流稳压电源 量角器 米尺 四位半数字万用表 0~200℃温度计 秒表 20MHz双路普通示波 ...… 查看全部问答> |
|
本帖最后由 王项电子 于 2014-5-4 19:26 编辑 先上图,用launchpad小板做的, 最小的平衡车了,和手掌做下对比 第一次作板,让大家见笑了。 又重新画了个板子,第一次的有的问题。 做的不好,请大神批评。 … 查看全部问答> |




