1.将FALSH中的数据传输到SRAM中(存储器到存储器)
用const关键字定义的数据存放到FLASH,而其他普通变量存放到SRAM中。
DMA头文件:
#ifndef _DMA_H #define _DMA_H #include "stm32f10x.h" //DMA宏定义 #define DMA_CLK RCC_AHBPeriph_DMA1 #define DMA DMA1 #define DMA_CHANNEL DMA1_Channel1 //导出接收数组 extern uint8_t receiveData[]; void DMA_Config(void); #endif
DMA c文件:
#include "dma.h" const uint8_t sendData[10]={1,2,3,4,5,6,7,8,9,10}; uint8_t receiveData[10]; void DMA_Config(void) { DMA_InitTypeDef DMA_InitStruct; //开启时钟 RCC_AHBPeriphClockCmd(DMA_CLK,ENABLE); DMA_InitStruct.DMA_PeripheralBaseAddr=(uint32_t)sendData;//外设基地址 这里为发送数组首地址 DMA_InitStruct.DMA_MemoryBaseAddr=(uint32_t)receiveData;//存储器基地址 这里为接收数据首地址 DMA_InitStruct.DMA_DIR=DMA_DIR_PeripheralSRC;//传输方向 这里为外设到存储器 DMA_InitStruct.DMA_BufferSize=10;//传输数量 DMA_InitStruct.DMA_PeripheralInc=DMA_PeripheralInc_Enable;//外设地址是否自增 DMA_InitStruct.DMA_MemoryInc=DMA_MemoryInc_Enable;//存储器地址是否自增 DMA_InitStruct.DMA_PeripheralDataSize=DMA_PeripheralDataSize_Byte;//外设传输数据基本单元 DMA_InitStruct.DMA_MemoryDataSize=DMA_MemoryDataSize_Byte;//存储器传输数据基本单位 DMA_InitStruct.DMA_Mode=DMA_Mode_Normal;//模式 普通模式(一次性) DMA_InitStruct.DMA_Priority=DMA_Priority_Medium;//优先级 DMA_InitStruct.DMA_M2M=DMA_M2M_Enable;//是否存储器到存储器 DMA_Init(DMA_CHANNEL,&DMA_InitStruct);//初始化 DMA_Cmd(DMA_CHANNEL,ENABLE);//使能 }
main 函数:
#include "stm32f10x.h" #include "usart.h" #include "dma.h" int main() { USART_Config(); DMA_Config(); for(uint8_t i=0;i<10;i++) { printf("%d\t",receiveData[i]); } while(1); }
实验效果:
2.将SRAM中的数据传输到USART1的数据寄存器中(存储器到外设)
DMA头文件:
#ifndef _DMA_H #define _DMA_H #include "stm32f10x.h" //DMA宏定义 #define DMA_CLK RCC_AHBPeriph_DMA1 #define DMA DMA1 #define DMA_CHANNEL DMA1_Channel4 //USART TX引脚对应 DMA1通道4 void DMA_Config(void); #endif
USART1的TX请求对应DMA1通道4
DMA c文件:
#include "dma.h" uint8_t sendData[]="Hello World!"; void DMA_Config(void) { DMA_InitTypeDef DMA_InitStruct; //开启时钟 RCC_AHBPeriphClockCmd(DMA_CLK,ENABLE); DMA_InitStruct.DMA_PeripheralBaseAddr=(uint32_t)&USART1->DR;//外设基地址 这里USART1的数据寄存器地址 DMA_InitStruct.DMA_MemoryBaseAddr=(uint32_t)sendData;//存储器基地址 这里为接收数据首地址 DMA_InitStruct.DMA_DIR=DMA_DIR_PeripheralDST;//传输方向 这里为存储器到外设 DMA_InitStruct.DMA_BufferSize=sizeof(sendData)/sizeof(uint8_t);//传输数量 发送数据的大小 DMA_InitStruct.DMA_PeripheralInc=DMA_PeripheralInc_Disable;//外设地址是否自增 DMA_InitStruct.DMA_MemoryInc=DMA_MemoryInc_Enable;//存储器地址是否自增 DMA_InitStruct.DMA_PeripheralDataSize=DMA_PeripheralDataSize_Byte;//外设传输数据基本单元 DMA_InitStruct.DMA_MemoryDataSize=DMA_MemoryDataSize_Byte;//存储器传输数据基本单位 DMA_InitStruct.DMA_Mode=DMA_Mode_Normal;//模式 普通模式(一次性) DMA_InitStruct.DMA_Priority=DMA_Priority_Medium;//优先级 DMA_InitStruct.DMA_M2M=DMA_M2M_Disable;//是否存储器到存储器 由于是从存储器到外设 所以这里失能 DMA_Init(DMA_CHANNEL,&DMA_InitStruct);//初始化 DMA_Cmd(DMA_CHANNEL,ENABLE);//使能 USART_DMACmd(USART1,USART_DMAReq_Tx,ENABLE);//USAER使能DMA发送请求 }
注意:在最后要有 USART_DMACmd(USART1,USART_DMAReq_Tx,ENABLE);因为前面的配置只是把SRAM中的数据传输到了USART1的数据寄存器中,还没有发送出去
实验效果:
当把传输模式改成循环发送模式时 DMA_InitStruct.DMA_Mode=DMA_Mode_Circular;
实验效果:
由于单片机没有间隔的发送数据,所以将导致下次烧写程序烧不进去。
在我开发板上(PZ6806L)解决方法:将BOOT0引脚接3.3v,烧写完成再接地。