STM32微控制器之直接内存访问DMA的使用方法

直接内存访问(Direct Memory Access,DMA)是微控制器的一个外设,它的主要功能是用来搬运数据,而不需要占用CPU,即在传输数据的时候,CPU可以干其他的事情。

STM32F103微控制器的两个DMA控制器有12个通道(DMA1有7个通道,DMA2有5个通道),每个通道专门用来管理来自于一个或多个外设对存储器访问的请求。还有一个仲裁器来协调各个DMA请求的优先权。

仿真软件:Proteus 8.11 SP0,仿真STM32F103R6微处理器的DMA:内存到外设USART1,代码如下:

一、DMA配置

uint8_t buf[BUF_SIZE] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ\r\n";

void DMA1_Config(void)
{
	DMA_InitTypeDef DMA_InitStructure;
	
	// Enable DMA1 clock
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
	
	// DMA1 channel4 configuration
	DMA_DeInit(DMA1_Channel4);
	DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&USART1->DR;
	DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)buf;
	DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;
	DMA_InitStructure.DMA_BufferSize = BUF_SIZE;
	DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
	DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
	DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
	DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
	DMA_InitStructure.DMA_Priority = DMA_Priority_High;
	DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
	DMA_Init(DMA1_Channel4, &DMA_InitStructure);
	
	// Enable DMA1 Channel4 transfer
	DMA_Cmd(DMA1_Channel4, ENABLE);
}

二、USART配置

void USART1_Config(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	USART_InitTypeDef USART_InitStructure;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
	
	// Configure USART1 Tx as alternate function push-pull
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	// Configure USART1 Rx as input floating
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	
	// Configure USART1
	USART_InitStructure.USART_BaudRate = 9600;
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;
	USART_InitStructure.USART_StopBits = USART_StopBits_1;
	USART_InitStructure.USART_Parity = USART_Parity_No;
	USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;
	USART_Init(USART1, &USART_InitStructure);
	
	// Enable the USART1
	USART_Cmd(USART1, ENABLE);
}

// Retargets the C library printf function to the USART1
int fputc(int ch, FILE *f)
{
	// Place your implementation of fputc here
	// e.g. write a character to the USART1
	USART_SendData(USART1, (uint8_t)ch);
	
	// Loop until the end of transmission
	while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET)
	{
		__asm("nop");
	}
	
	return ch;
}

三、主函数

extern uint8_t buf[BUF_SIZE];

int main(void)
{
	USART1_Config();
	DMA1_Config();
	
	printf("Demo Test:\r\n");
	
	USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE);
	
	while(1)
	{
		__asm("nop");
	}
}

Leave a Reply

Your email address will not be published. Required fields are marked *