码迷,mamicode.com
首页 > 其他好文 > 详细

stm32寄存器版学习笔记08 DMA

时间:2016-07-14 02:35:26      阅读:344      评论:0      收藏:0      [点我收藏+]

标签:

  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

 

stm32寄存器版学习笔记08 DMA

标签:

原文地址:http://www.cnblogs.com/kuotian/p/5668707.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!