stm32 DMA数据搬运 操作寄存器+库函数
0:不执行外设地址增量操作 1:执行外设地址增量操作
CIRC:循环模式 (Circular mode) 该位由软件设置和清除。 0:不执行循环操作 1:执行循环操作
DIR:数据传输方向 (Data transfer direction) 该位由软件设置和清除。 0:从外设读 1:从存储器读
TEIE:允许传输错误中断 (Transfer error interrupt enable) 该位由软件设置和清除。 0:禁止TE中断 0:允许TE中断
HTIE:允许半传输中断 (Half transfer interrupt enable) 该位由软件设置和清除。 0:禁止HT中断 0:允许HT中断
TCIE:允许传输完成中断 (Transfer complete interrupt enable) 该位由软件设置和清除。 0:禁止TC中断 0:允许TC中断
EN:通道开启 (Channel enable) 该位由软件设置和清除。 0:通道不工作 1:通道开启
DMA通道x传输数量寄存器(DMA_CNDTRx)(x = 1…7)
低16位有效。这个寄存器控制通道每次传输的数据量,数据传输数量为0至65535。该寄存器会随着传输的进行而递减,为0表示已经发送完成。
DMA外设地址寄存器(DMA_CPARx)
32位寄存器。外设数据寄存器的基地址,作为数据传输的源或目标。
DMA存储地址寄存器(DMA_CMARx)
存储器地址[31:0],存储器地址作为数据传输的源或目标。
代码如下: (system.h 和stm32f10x_it.h等相关代码参照stm32 直接操作寄存器开发环境配置)
User/main.c
#include#include "system.h"#include "usart.h" #include "dma.h"#include "tim.h" #include "string.h"#define LED1 PAout(4)#define LED2 PAout(5)#define LED3 PAout(6)void Gpio_Init(void);//数据源uc32 SRC_Const_Buffer[32] ={ 0x01020304,0x05060708,0x090A0B0C,0x0D0E0F10,0x21314,0x15161718,0x191A1B1C,0x1D1E1F20,0x21324,0x25262728,0x292A2B2C,0x2D2E2F30,0x31324,0x35363738,0x393A3B3C,0x3D3E3F40,0x41424344,0x45464748,0x494A4B4C,0x4D4E4F50,0x51525354,0x65758,0x595A5B5C,0x5D5E5F60,0x61626364,0x65768,0x696A6B6C,0x6D6E6F70,0x71727374,0x75768,0x797A7B7C,0x7D7E7F80};//目标位置u32 DST_Buffer[32];int main(void){ u8 i=0;u16 StartTime=0,CPUSpendTime=0,DMASpendTime=0;;Rcc_Init(9); //系统时钟设置Usart1_Init(72,9600);Tim_Init(TIM_2,65535,71); //初始化TIM2定时器,设定重装值和分频值,计时时间为1us/次Dma_Init(DMA1_Channel1,(u32)SRC_Const_Buffer,(u32)DST_Buffer); //初始化DMA,外设地址示例 &USART1->DRNvic_Init(1,0,DMA1_Channel1_IRQChannel,4); //设置抢占优先级为0,响应优先级为0,中断分组为4Gpio_Init();StartTime = TIM2->CNT;while(i<32) //CPU搬运{DST_Buffer[i]=SRC_Const_Buffer[i];i++;}CPUSpendTime = TIM2->CNT - StartTime;printf("\r\n the CPU spend : %dus! \r\n",CPUSpendTime);if(strncmp((const char *)SRC_Const_Buffer,(const char *)DST_Buffer,32) ==0) //验证传输效果,判断两数组是否相同{printf("\r\n CPU Transmit Success! \r\n");}else{printf("\r\n CPU Transmit Fail! \r\n");}i=0;while(i<32) //清空目标数组,准备DMA搬运{DST_Buffer[i]=0;i++;} StartTime = TIM2->CNT;Dma_Enable(DMA1_Channel1,32);//DMA搬运while( DMA1_Channel1 -> CNDTR != 0); //等待传输完成DMASpendTime= TIM2->CNT - StartTime;printf("\r\n the DMA spend : %dus! \r\n",DMASpendTime);if(strncmp((const char *)SRC_Const_Buffer,(const char *)DST_Buffer,32) ==0) //验证传输效果,判断两数组是否相同{printf("\r\n DMA Transmit Success! \r\n");}else{printf("\r\n DMA Transmit Fail! \r\n");} while(1); }void Gpio_Init(void){RCC->APB2ENR=1<2; //使能PORTA时钟 GPIOA->CRL&=0x0FFFF; // PA0~3设置为浮空输入,PA4~7设置为推挽输出GPIOA->CRL=0x34; //USART1 串口I/O设置GPIOA -> CRH&=0xFFFFF00F; //设置USART1 的Tx(PA.9)为第二功能推挽,50MHz;Rx(PA.10)为浮空输入GPIOA -> CRH=0x008B0; }
User/stm32f10x_it.c
#include "stm32f10x_it.h"#include "system.h"#include "stdio.h"#define LED1 PAout(4)#define LED2 PAout(5)#define LED3 PAout(6)#define LED4 PAout(7)void DMAChannel1_IRQHandler(void) //和启动文件有关,STM32F10x.s中 和 STM32F10x_md.s DMA中断接口函数不同{if( DMA1 ->ISR & (1<1)) //传输完成中断{LED1 = 1;DMA1->IFCR = 1<1; //清除传输完成中断}if( DMA1 ->ISR & (1<2)) //半传输完成中断{DMA1 ->IFCR = 1<2; //清除半传输完成中断}if( DMA1 ->ISR & (1<3)) //传输错误中断{LED4 =1 ;DMA1 ->IFCR = 1<3; //清除传输错误中断}DMA1 ->IFCR = 1<0; //清除此通道的中断}
Library/src/dma.c
#include#include "system.h"#include "dma.h"//DMA通道初始化函数//传输方向:存储器 -> 存储器模式 ,32位数据模式,存储器增量模式//参数说明:// DMA_CHx :选择DMA控制器通道,DMA1有1-7,DMA2有1-4// P_Adress :外设地址// M_Adress :存储器地址void Dma_Init(DMA_Channel_TypeDef * DMA_CHx,u32 P_Address ,u32 M_Address){RCC->AHBENR = 1<0;DMA_CHx -> CCR &= 0xFFFF0; //复位 DMA_CHx -> CCR = 1<1; //允许传输完成中断//DMA_CHx -> CCR = 1<2; //允许半传输中断DMA_CHx -> CCR = 1<3; //允许传输错误中断 读写一个保留的地址区域,将会产生DMA传输错误 //设定数据传输方向DMA_CHx -> CCR = 0<4; //设定数据传输方向 0:从外设读 1:从存储器读DMA_CHx -> CCR = 0<5; //0:不执行循环操作 1:执行循环操作 //设定地址增量DMA_CHx -> CCR = 1<6; //0:不执行外设地址增量操作 1:执行外设地址增量操作DMA_CHx -> CCR = 1<7; //0:不执行存储器地址增量操作 1:执行存储器地址增量操作 //设定外设数据宽度 SDMA_CHx -> CCR = 0<8; //外设数据宽度,由[9:8]两位控制DMA_CHx -> CCR = 1<9; //00:8位 01:16位 10:32位 11:保留 //设定存储数据宽度DMA_CHx -> CCR = 0<10; //存储器数据宽度,由[11:10]两位控制DMA_CHx -> CCR = 1<11; //00:8位 01:16位 10:32位 11:保留 //设定为中等优先级DMA_CHx -> CCR = 1<12; //通道优先级,由[13:12]两位控制DMA_CHx -> CCR = 1<13; //00:低 01:中 10:高 11:最高 DMA_CHx -> CCR = 1<14; //0:非存储器到存储器模式; 1:启动存储器到存储器模式。 //必须配置好通道后配置地址DMA_CHx -> CPAR = (u32)P_Address; //设定外设寄存器地址DMA_CHx -> CMAR = (u32)M_Address; //设定数据存储器地址}//DMA通道使能//参数说明:// DMA_CHx :选择DMA控制器通道,DMA1有1-7,DMA2有1-4// Number :数据传输量void Dma_Enable(DMA_Channel_TypeDef * DMA_CHx,u16 Number){DMA_CHx -> CCR &= ~(1<0); //关闭上一次DMA传输DMA_CHx -> CNDTR = Number; //数据传输量DMA_CHx -> CCR = 1<0; //开始DMA传输 }
stm32DMA数据搬运操作寄存器库函 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)