stm32寄存器版学习笔记08 DMA

  DMA(Direct Memory Access),直接存储器访问。DMA传输方式无需CPU直接控制传输,通过硬件为RAM与I/O设备开辟一条直接传送数据的通路,使CPU效率大大提高。stm32f103有2个DMA控制器,DMA1有7个通道,DMA2有5个通道,专门用来管理来自外设对存储器的访问请求,还有一个仲裁器来协调各个DMA请求的优先权。

1.DMA各通道请求

  从外设产生的DMA请求通过逻辑"或"输入到DMA控制器,这就意味着同时只能有一个请求有效。

  例如,串口1发送的DMA,就要用到DMA1的通道4。

2.DMA1通道4(串口1发送)配置步骤

①设置外设地址

  设置外设地址通过DMA1_CPAR4来设置,在这个寄存器里面写入&USART1_DR的值。该地址将作为DMA传输的目标地址。

  DMA通道x外设地址寄存器(DMA_CPARx)(x = 1…7)

  Eg:DMA_CHx->CPAR=cpar; //DMA1 外设地址

     DMA_CHx->CPAR=&USART1_DR;

②设置存储器地址

  设置存储器地址通过DMA1_CMAR4来设置,假设要把数组SendBuf作为存储器,在该寄存器写入&SendBuf的值。该地址将作为DMA传输的源地址

  Eg:DMA_CHx->CMAR=(u32)cmar; //DMA1,存储器地址

③设置传输数据量

  写入此次要传输的数据量,也就是SendBuf的大小。该寄存器在DMA启动后自减,每次新的DMA传输都重新向该寄存器写入要传输的数据量。

  DMA通道x传输数量寄存器(DMA_CNDTRx)(x = 1…7)

  Eg:DMA_CHx->CNDTR=cndtr;     //DMA1,传输数据量

④设置通道4的配置信息

  若有多个通道,则要设置优先级,编号越小优先级越高。

  DMA通道x配置寄存器(DMA_CCRx)(x = 1…7)

⑤使能DMA1通道4,启动传输

  DMAx_CCRx 最低位开启DMA传输。注意要设置USART1的使能DMA传输位,通过USART1->CR3的第七位设置,这样就可以启动一次USART1的DMA传输了。

3.DMA中断状态显示及清除

  DMA中断状态寄存器(DMA_ISR)

  DMA中断标志清除寄存器(DMA_IFCR)

  Eg:if(DMA1->ISR&(1<<13))//等待通道4传输完成
     {
       DMA1->IFCR|=1<<13;//清除通道4传输完成标志
       break;
     }

4.DMA1通道4(串口1发送)应用

 1 u16 DMA1_MEM_LEN;//保存DMA每次数据传送的长度
 2 //DMA1的各通道配置
 3 //这里的传输形式是固定的,这点要根据不同的情况来修改
 4 //从存储器->外设模式/8位数据宽度/存储器增量模式
 5 //DMA_CHx:DMA通道CHx
 6 //cpar:外设地址
 7 //cmar:存储器地址
 8 //cndtr:数据传输量
 9 void MYDMA_Config(DMA_Channel_TypeDef*DMA_CHx,u32 cpar,u32 cmar,u16 cndtr)
10 {
11     RCC->AHBENR|=1<<0;            //开启DMA1时钟
12     delay_ms(5);                //等待DMA时钟稳定
13     DMA_CHx->CPAR=cpar;          //DMA1 外设地址
14     DMA_CHx->CMAR=(u32)cmar;     //DMA1,存储器地址
15     DMA1_MEM_LEN=cndtr;          //保存DMA传输数据量
16     DMA_CHx->CNDTR=cndtr;        //DMA1,传输数据量
17     DMA_CHx->CCR=0X00000000;    //复位
18     DMA_CHx->CCR|=1<<4;          //从存储器读
19     DMA_CHx->CCR|=0<<5;          //普通模式
20     DMA_CHx->CCR|=0<<6;         //外设地址非增量模式
21     DMA_CHx->CCR|=1<<7;          //存储器增量模式
22     DMA_CHx->CCR|=0<<8;          //外设数据宽度为8位
23     DMA_CHx->CCR|=0<<10;         //存储器数据宽度8位
24     DMA_CHx->CCR|=1<<12;         //中等优先级
25     DMA_CHx->CCR|=0<<14;         //非存储器到存储器模式
26 }
27 //开启一次DMA传输
28 void MYDMA_Enable(DMA_Channel_TypeDef*DMA_CHx)
29 {
30     DMA_CHx->CCR&=~(1<<0);       //关闭DMA传输
31     DMA_CHx->CNDTR=DMA1_MEM_LEN; //DMA1,传输数据量
32     DMA_CHx->CCR|=1<<0;          //开启DMA传输
33 }      

DMA.c

 1 const u8 TEXT_TO_SEND[]={"STM32 DMA USART1"};
 2 #define TEXT_LENTH  sizeof(TEXT_TO_SEND)-1            //TEXT_TO_SEND字符串长度(不包含结束符)
 3 u8 SendBuff[(TEXT_LENTH+2)*100];
 4
 5 int main(void)
 6 {
 7     u16 i;
 8     u8 t=0;
 9     float pro=0;            //进度
10      Stm32_Clock_Init(9);    //系统时钟设置
11     uart_init(72,9600);         //串口初始化为9600
12     delay_init(72);                //延时初始化
13     LED_Init();                  //初始化与LED连接的硬件接口
14     LCD_Init();                   //初始化LCD
15     KEY_Init();                //按键初始化
16      MYDMA_Config(DMA1_Channel4,(u32)&USART1->DR,(u32)SendBuff,(TEXT_LENTH+2)*100);//DMA1通道4,外设为串口1,存储器为SendBuff,长(TEXT_LENTH+2)*100.
17      POINT_COLOR=RED;//设置字体为红色
18     //显示提示信息
19     for(i=0;i<(TEXT_LENTH+2)*100;i++)//填充ASCII字符集数据
20     {
21         if(t>=TEXT_LENTH)//加入换行符
22         {
23             SendBuff[i++]=0x0d;
24             SendBuff[i]=0x0a;
25             t=0;
26         }else SendBuff[i]=TEXT_TO_SEND[t++];//复制TEXT_TO_SEND语句
27     }
28     POINT_COLOR=BLUE;//设置字体为蓝色
29     i=0;
30     while(1)
31     {
32         t=KEY_Scan(0);
33         if(t==KEY0_PRES)//KEY0按下
34         {
35             LCD_ShowString(60,150,200,16,16,"Start Transimit....");
36             LCD_ShowString(60,170,200,16,16,"   %");//显示百分号
37             printf("\r\nDMA DATA:\r\n ");
38             USART1->CR3=1<<7;           //使能串口1的DMA发送
39             MYDMA_Enable(DMA1_Channel4);//开始一次DMA传输!
40             //等待DMA传输完成,此时我们来做另外一些事,点灯
41             //实际应用中,传输数据期间,可以执行另外的任务
42             while(1)
43             {
44                 if(DMA1->ISR&(1<<13))//等待通道4传输完成
45                 {
46                     DMA1->IFCR|=1<<13;//清除通道4传输完成标志
47                     break;
48                 }
49                 pro=DMA1_Channel4->CNDTR;//得到当前还剩余多少个数据
50                 pro=1-pro/((TEXT_LENTH+2)*100);//得到百分比
51                 pro*=100;      //扩大100倍
52                 LCD_ShowNum(60,170,pro,3,16);
53             }
54             LCD_ShowNum(60,170,100,3,16);//显示100%
55             LCD_ShowString(60,150,200,16,16,"Transimit Finished!");//提示传送完成
56         }
57         i++;
58         delay_ms(10);
59         if(i==20)
60         {
61             LED0=!LED0;//提示系统正在运行
62             i=0;
63         }
64     }
65 }

main.c

时间: 2025-01-01 21:08:40

stm32寄存器版学习笔记08 DMA的相关文章

stm32寄存器版学习笔记06 输入捕获(ETR脉冲计数)

STM32外部脉冲ETR引脚:TIM1-->PA12;TIMER2-->PA0:TIMER3-->PD2;TIMER4-->PE0… 1.TIM2 PA0计数 配置步骤 ①开启TIM2时钟,配置PA0输入 APB1外设复位寄存器 (RCC_APB1RSTR) APB2外设时钟使能寄存器(RCC_APB2ENR) 置1开启.清0关闭. Eg:RCC->APB1ENR|=1<<0; //使能TIM2时钟  RCC->APB2ENR|=1<<2;  

stm32寄存器版学习笔记07 ADC

STM32F103RCT有3个ADC,12位主逼近型模拟数字转换器,有18个通道,可测量16个外部和2个内部信号源.各通道的A/D转换可以单次.连续.扫描或间断模式执行. 1.通道选择 stm32把ADC转换分成2个通道组:规则通道组相当于正常运行的程序:注入通道组相当于中断.程序初始化阶段设置好不同的转换组,系统运行中不用变更循环转换的配置,从而达到任务互不干扰和快速切换. 有16个多路通道.可以把转换组织成两组:规则组和注入组.在任意多个通道上以任意顺序进行的一系列转换构成成组转换.例如,可

stm32寄存器版学习笔记05 PWM

STM32除TIM6和TIM7外都可以产生PWM输出.高级定时器TIM1和TIM8可以同时产生7路PWM,通用定时器可以产生4路PWM输出. 1.TIM1 CH1输出PWM配置步骤 ①开启TIM1时钟,配置PA8为复用输出 APB2外设时钟使能寄存器(RCC_APB2ENR) APB1外设复位寄存器 (RCC_APB1RSTR) 置1开启.清0关闭. Eg:RCC->APB2ENR|=1<<11; //使能TIM1时钟 配置I/O口: 参见stm32寄存器版学习笔记01 GPIO口的配置

stm32寄存器版学习笔记01 GPIO口的配置(LED、按键)

STM32的I/O口可以由软件配置成如下8种模式:输入浮空.输入上拉.输入下拉.模拟输入.开漏输出.推挽输出.推挽式复用功能及开漏复用功能.每个I/O口由7个寄存器来控制:配置模式的端口配置寄存器CRL和CRH(模式.速度):数据寄存器IDR和ODR:置位/复位寄存器BSRR:复位寄存器BRR:锁存寄存器LCKR. I/O口模式: GPIO的8种模式 通用输出 推挽输出(Puch-Pull) 可以输出高.低电平,连接数字器件   开漏输出(Open-Drain) 开漏引脚不连接外部的上拉电阻时,

stm32寄存器版学习笔记10 SPI

SPI(Serial Peripheral Interface),串行外围设备接口.SPI是一种高速的.全双工.同步的通信总线. SPI接口一般使用4条线通信: MISO 主设备数据输入,从设备数据输出 MOSI 主设备数据输出,从设备数据输入 SCLK 时钟信号,有主设备产生 CS 从设备片选信号,有主设备控制 SPI模块为了和外设进行数据交换,根据外设工作要求,其输出串行同步时钟极性和相位可以进行配置.SPI_CR寄存器的CPOL(时钟极性)位,控制在没有数据传输时时钟的空闲状态电平,此位对

stm32寄存器版学习笔记09 IIC

I²C(Inter-Integrated Circuit)总线是一种两线式串行总线,用于连接微控制器及其外设,是由数据线SDA和时钟SCL构成的串行总线,可发送和接收数据. IIC总线在传送数据过程中共有3种类型信号,分别是开始信号.结束信号和应答信号.   SCL SDA 开始信号 高电平 由高电平向低电平跳变,开始传送数据 结束信号 高电平 由低电平向高电平跳变,结束传送数据 应答信号 接收数据的IC在接收到8bit数据后向发送数据的IC发出特定的低电平脉冲,表示已经收到数据:CPU向受控单

C++Primer第5版学习笔记(三)

C++Primer第5版学习笔记(三) 第四/五章的重难点内容 你可以点击这里回顾第三章内容 因为第五章的内容比较少,因此和第四章的笔记内容合并.   第四章是和表达式有关的知识,表达式是C++的基础设施,本章由三部分组成:         1.表达式概念基础,包括表达式的基本概念,左值和右值的概念,优先级结合律,求值顺序.  2.各种运算符,主要包括算数\关系\逻辑\赋值\递增递减\成员访问\条件\位运算\sizeof\逗号运算符 这10种运算符.  3.类型转换,包括隐式和显式两种转换的规则

C++Primer第5版学习笔记(一)

C++Primer第5版学习笔记(一) 第一.二章的重难点内容 本篇文章主要记录了我在学习C++Primer(第5版,中文版)中遇到的重难点及其分析.因为第一.二章比较简单,因此这里合并这两章我遇到的问题.        第一章 开始 这一章在第一部分之前,是一个helloworld式的章节,包含基本的函数,io流以及类的介绍. 知识点1:P19,1.5,文件重定向 可以在windows下的cmd中或者mac,linux系统的终端窗口中用输入命令的形式执行程序并使它从一个文件中读入数据,再把标准

C++ GUI Qt4学习笔记08

C++ GUI Qt4学习笔记08 qtc++signal图形引擎文档 [html] view plaincopy 本章介绍Qt的二维图形引擎,Qt的二维图形引擎是基于QPainter类的.<span style="color:#ff0000;">QPainter既可以绘制几何图形(点.线.矩形等),也可以绘制像素映射.图像和文字.此外QPainter还支持一些高级特性,例如反走样.像素混合.渐变填充和矢量路径等.QPainter也支持线性变换,例如平移.旋转.错切和缩放.