【嵌入式】STM32之DMA实现FLash向内部SRAM数据传输

  • Post author:
  • Post category:其他


本篇文章基于战舰V3的STMF103ZET6开发板,在原示例代码中修改一小部分代码。下面是代码逻辑分析以及演示效果

  1. 外设(内部Flash)向内部SRAM进行数据传输
  2. 验证是否传输正确
  3. 如果传输正确则连接在PB5的LED灯亮一会然后熄灭

涉及到的东西比较少,唯独注意的是文中的extern,#ifndef等语法,如果不明白可以去补习下C语言。

dma.h

#ifndef _DMA_H
#define _DMA_H
#include "stdint.h"
//state DMA channel
#define DMA_CHANNEL DMA1_Channel6
//state DMA clock
#define DMA_CLOCK RCC_AHBPeriph_DMA1
//transfer finish flag
#define DMA_FLAG_TC DMA1_FLAG_TC6
//send data size
#define DMA_BUFFER_SIZE 32

//define DMA configuration method
void Config_DMA(void);
//compare peripheral address with inner
uint8_t BufferComp(uint32_t*,uint32_t*,uint16_t);
#endif

dma.c

#include "dma.h"
#include "stm32f10x.h"
//state peripheral data source
const uint32_t Flash_Const_Buffer[DMA_BUFFER_SIZE] = {
	0x01020304,0x05060708,0x090A0B0C,0x0D0E0F10,
	0x11121314,0x15161718,0x191A1B1C,0x1D1E1F20,
	0x21222324,0x25262728,0x292A2B2C,0x2D2E2F30,
	0x31323334,0x35363738,0x393A3B3C,0x3D3E3F40,
	0x41424344,0x45464748,0x494A4B4C,0x4D4E4F50,
	0x51525354,0x55565758,0x595A5B5C,0x5D5E5F60,
	0x61626364,0x65666768,0x696A6B6C,0x6D6E6F70,
	0x71727374,0x75767778,0x797A7B7C,0x7D7E7F80
};
//state SRAM receive array
uint32_t SRAM_BUFFER[DMA_BUFFER_SIZE];


//implements DMA configuration method
void Config_DMA(void){
	//declare DMA_InitTypeDef structure
	DMA_InitTypeDef DMAInitStructrue;
	//enable DMA clock
	RCC_AHBPeriphClockCmd(DMA_CLOCK,ENABLE);
	//DMA source address
	DMAInitStructrue.DMA_PeripheralBaseAddr  = (uint32_t)Flash_Const_Buffer;
	//DMA target address
	DMAInitStructrue.DMA_MemoryBaseAddr = (uint32_t)SRAM_BUFFER;
	//DMA transfer direction,periph Flash-->>>inner SRAM
	DMAInitStructrue.DMA_DIR = DMA_DIR_PeripheralSRC;
	//transfer data size
	DMAInitStructrue.DMA_BufferSize = DMA_BUFFER_SIZE;
	//peripheral address increase
	DMAInitStructrue.DMA_PeripheralInc=DMA_PeripheralInc_Enable;
	//inner address increase
	DMAInitStructrue.DMA_MemoryInc= DMA_MemoryInc_Enable;
	//peripheral data unit
	DMAInitStructrue.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Word;
	//inner data unit
	DMAInitStructrue.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;
	//DMA mode:onetime or always
	DMAInitStructrue.DMA_Mode = DMA_Mode_Normal;
	//DMA priority:high
	DMAInitStructrue.DMA_Priority = DMA_Priority_High;
	//enable M2M(Memorory to Memorory)
	DMAInitStructrue.DMA_M2M =DMA_M2M_Enable;
	//DMA channel
	DMA_Init(DMA_CHANNEL,&DMAInitStructrue);
	//enable DMA finished
	DMA_Cmd(DMA_CHANNEL,ENABLE);
}

//implements DMA compare method
uint8_t BufferComp(uint32_t* PeripheralAddr,uint32_t* InnerAddr,uint16_t BufferSize){
	uint8_t val;
	while(BufferSize>0){
		if(*PeripheralAddr!=*InnerAddr){
			return 0;
		}
		PeripheralAddr++;
		InnerAddr++;
		BufferSize--;
	}
return 1;
}

main.c

#include "stm32f10x.h"
#include "stdint.h"
#include "stdio.h"
#include "delay.h"
#include "dma.h"
extern uint32_t SRAM_BUFFER[DMA_BUFFER_SIZE];
extern const uint32_t Flash_Const_Buffer[DMA_BUFFER_SIZE];
int main(void){
	//the ValueCompStatus
	uint8_t CompareValue;
	//GPIO_InitTypeDef
	GPIO_InitTypeDef GPIO_InitStructure;
	//gpio config
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOE,ENABLE);
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	
	delay(0xFFFFFF);

	//using dma config method
	Config_DMA();
	//waiting DMA transfer finished
	while(DMA_GetFlagStatus(DMA_FLAG_TC)==RESET){}
	//transfer finished
		//compare peripheral address with inner address
		CompareValue = BufferComp(( uint32_t*)Flash_Const_Buffer,SRAM_BUFFER,DMA_BUFFER_SIZE);
		//if ture ,open green led, error open red led.
		if(CompareValue==0){
			//transfer abnormal GPIOE.5
				GPIO_Init(GPIOE,&GPIO_InitStructure);
	      GPIOE->BRR=GPIO_Pin_5;
		}else{
			//transfer normal GPIOB.5
				GPIO_Init(GPIOB,&GPIO_InitStructure);
	      GPIOB->BRR=GPIO_Pin_5;
				delay(0xFFFFFF);
			  GPIOB->BSRR=GPIO_Pin_5;
		}
		while(1);
return 0;
}



版权声明:本文为qq_21004057原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。