STM32 USART使用DMA设置
2024-10-22 来源:cnblogs
1、外设时钟初始化
首先初始化需要用到的外围设备设备的时钟,需要初始化的始终有USART RX DMA使用的DMA1、USART1、USART1使用的GPIO、AFIO(如果USART的管脚需要Remap则需要打开否则不用);
/* DMA clock enable (USART RX using dma1) */
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
/* USART clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
/* Enable GPIO clock */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE);
2、初始化需要用到的外设
初始化USART使用到的AFIO和GPIO,AFIO设置USART管脚的映射,GPIO设置管脚的输入、输出状态,USART1默认(USART1_REMAP = 0)使用PA9、10作为收发管脚,而在实际硬件连接中使用了PB6、7作为收发管脚,这就需要将USART1_REMAP置为为1来实现,RX管脚需要设置为'Input floating'模式,TX管脚需要设置为'Alternate function push-pul'模式;
GPIO_InitTypeDef GPIO_InitStructure;
/* Enable the USART Pins Software Remapping, using PB6.7 as TX RX*/
GPIO_PinRemapConfig(GPIO_Remap_USART1, ENABLE);
/* Configure USARTy Rx as input floating */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
GPIO_Init(USART_GPIO, &GPIO_InitStructure);
/* Configure USART Tx as alternate function push-pull */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(USART_GPIO, &GPIO_InitStructure);
3、USART接收数据DMA配置
在第一步的RCC初始化中已经使能了DMA1的时钟,在接下来的过程中就需要配置DMA,使其USART1在接收数据的时候使用DMA。STM32 DMA的配置十分容易,主要有一下选项:
传输两端(内存和外设)的起始地址;
传输的数据的长度,以及是否会循环滚动(传输完指定长度的数据,又自动滚回到起点坚可以实现环形FIFO);
传输方向,外设到内存或内存到外设或内存到内存;
传输两端(内存和外设)的地址在每次传输后是否自增;
传输两端(内存和外设)地址的数据宽度(决定每次怎样复制和写入数据);
设置传输使用的优先级,以及在何时会产生中断(传输出错、传输一半、传输完成);
/* Usart rx dma receive buffer, this address must be 256 aligned */
#define USART_RX_BUF_SIZE 256
U8 __attribute__((aligned(256)))usart_rx_buf[USART_RX_BUF_SIZE];
DMA_InitTypeDef DMA_InitStructure;
memset(usart_rx_buf, 0, USART_RX_BUF_SIZE);
/* Usart1 rx using dma1 channel 6 */
DMA_DeInit(DMA1_Channel5);
/* Periph addr is usart rx data register address */
DMA_InitStructure.DMA_PeripheralBaseAddr = 0x40013804;
DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)usart_rx_buf;
DMA_InitStructure.DMA_BufferSize = USART_RX_BUF_SIZE;
/* Usart rx data reg need not increment, rx buffer nned */
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;
/* Once transfer one byte and using cycle mode */
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;
/* Using highest priority, transfer direction is perihp to memory(USART to memory) */
DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel5, &DMA_InitStructure);
4、USART通讯参数设置,时能串口和DMA
经过以上几步的设置已经完成系统时钟和各种外设以及DMA的初始化工作,最后设置串口的通讯参数,并使能串口即可通讯了。
USART_InitTypeDef USART_InitStructure;
/* Usart init,38400,8bit data bit,1 stop bit, No Parity and flow control, rx tx enable */
USART_InitStructure.USART_BaudRate = 38400;
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(USAR1T, &USART_InitStructure);
/* Enable USART DMA RX request */
USART_DMACmd(USART1, USART_DMAReq_Rx, ENABLE);
/* Enable USART1 RX DMA channel */
DMA_Cmd(DMA1_Channel5, ENABLE);
/* Enable USART */
USART_Cmd(USART, ENABLE);
下一篇:stm32中断解释