微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > stm32 DMA数据搬运 操作寄存器+库函数

stm32 DMA数据搬运 操作寄存器+库函数

时间:11-09 来源:互联网 点击:

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传输    }

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top