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);