STM32F4串口1使用DMA收发数据
一、什么是DMA?
直接存储器访问(DMA)用于在外设与存储器之间以及存储器与存储器与存储器之间提供数据传输。它无需CPU参与而自动移动数据,即DMA就是一个数据搬运工。
二、怎么使用DMA?
既然DMA是一个数据搬运工,那么根据数据传输三要素,必须知道数据的源、目的和长度。在STM32F4中还需要设置数据传输方向等其它项,具体参考代码。
三、STM32F4的DMA简介
STM32F4有2个DMA,每个DMA控制器有8个数据流,每个数据流有多达8个通道,但是仅DMA2数据流能够执行存储器到存储器之间的数据传输。其中DMA2的请求映射如下:
从图中可以看出串口1的接收和发送分别位于数据流2的通道4和数据流7的通道4。
四、代码解析
函数的功能很简单,就是将串口接收到的数据然后发送出去。
1.main函数
int main(void)
{
/* 时钟初始化 */
Stm32f4xxClockInit();
/* 串口1初始化 */
UART1Init();
/* 使用DMA发送数据初始化 */
DMA_Use_USART1_Tx_Init();
/* 使用DMA接收数据初始化 */
DMA_Use_USART1_Rx_Init();
/* 打开总中断 */
__enable_irq();
for(;;)
{
if(tUART1_Rx.dwUART1RxLen && UART1_Use_DMA_Tx_Flag == 0)
{
Use_DMA_tx(tUART1_Rx.UART1RxBuf, tUART1_Rx.dwUART1RxLen);
tUART1_Rx.dwUART1RxLen = 0;
}
}
}
2.串口1初始化
串口的初始化注意中断的配置,要使用DMA接收数据,必须使能IDLE中断,因为在数据的传输三要素中,使用DMA接收数据不知道数据的长度,故必须使能IDLE中断来判断该次数据是否接收完成。
/* 库版本: V1.8.0
* 串口1初始化
* 使用PA9和PA10
*/
static void UART1Init(void)
{
USART_DeInit(USART1);
/* 1.使能PA口时钟 */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
/* 2.使能串口1时钟 */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
/* 3.管脚映射 */
GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_USART1); /* GPIOA9复用为USART1 */
GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_USART1); /* GPIOA10复用为USART1 */
/* 4.配置串口1的PA9和PA10管脚 */
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOA, &GPIO_InitS