STM32F103 UART中断接收 DMA发送

以USART3为例,
(1)首先在【stm32f1xx_hal_conf.h】中使能DMA模块,工程增加stm32f1xx_hal_dma.c。
(2)main.c中头部增加以下声明

UART_HandleTypeDef huart3; DMA_HandleTypeDef hdma1_uart3;

(3)main.c中增加USART的初始化
/* USART3 init function */ static void MX_USART3_UART_Init(void) { huart3.Instance = USART3; huart3.Init.BaudRate = 115200; huart3.Init.WordLength = UART_WORDLENGTH_8B; huart3.Init.StopBits = UART_STOPBITS_1; huart3.Init.Parity = UART_PARITY_NONE; huart3.Init.Mode = UART_MODE_TX_RX; huart3.Init.HwFlowCtl = UART_HWCONTROL_NONE; huart3.Init.OverSampling = UART_OVERSAMPLING_16; if (HAL_UART_Init(&huart3) != HAL_OK) { Error_Handler(); } }

(4)stm32f1xx_hal_msp.c增加
externUART_HandleTypeDef huart3; extern DMA_HandleTypeDef hdma1_uart3; ......................void HAL_UART_MspInit(UART_HandleTypeDef* huart) { GPIO_InitTypeDef GPIO_InitStruct; if (huart->Instance == USART3) { /* USER CODE BEGIN USART3_MspInit 0 *//* USER CODE END USART3_MspInit 0 */ /* Peripheral clock enable */ __HAL_RCC_USART3_CLK_ENABLE(); __HAL_RCC_DMA1_CLK_ENABLE(); /**USART3 GPIO Configuration PB10------> USART3_TX PB11------> USART3_RX */ GPIO_InitStruct.Pin = GPIO_PIN_10; GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); GPIO_InitStruct.Pin = GPIO_PIN_11; GPIO_InitStruct.Mode = GPIO_MODE_INPUT; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); hdma1_uart3.Instance = DMA1_Channel2; hdma1_uart3.Init.Direction = DMA_MEMORY_TO_PERIPH; hdma1_uart3.Init.PeriphInc = DMA_PINC_DISABLE; hdma1_uart3.Init.MemInc = DMA_MINC_ENABLE; hdma1_uart3.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; hdma1_uart3.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; hdma1_uart3.Init.Mode = DMA_NORMAL; hdma1_uart3.Init.Priority = DMA_PRIORITY_LOW; HAL_DMA_DeInit(&hdma1_uart3); HAL_DMA_Init(&hdma1_uart3); __HAL_LINKDMA(huart, hdmatx, hdma1_uart3); HAL_NVIC_SetPriority(DMA1_Channel2_IRQn, 2, 0); HAL_NVIC_EnableIRQ(DMA1_Channel2_IRQn); /* Peripheral interrupt init */ HAL_NVIC_SetPriority(USART3_IRQn, USART_IRQn_PP, 0); HAL_NVIC_EnableIRQ(USART3_IRQn); __HAL_UART_ENABLE_IT(&huart3, USART_IT_RXNE); //使能串口3读数据寄存器非空中断RXNE /* USER CODE BEGIN USART3_MspInit 1 *//* USER CODE END USART3_MspInit 1 */ }}void HAL_UART_MspDeInit(UART_HandleTypeDef* huart) { if (huart->Instance == USART3) { /* USER CODE BEGIN USART3_MspDeInit 0 *//* USER CODE END USART3_MspDeInit 0 */ /* Peripheral clock disable */ __HAL_RCC_USART3_CLK_DISABLE(); __HAL_RCC_DMA1_CLK_DISABLE(); /**USART3 GPIO Configuration PB10------> USART3_TX PB11------> USART3_RX */ HAL_GPIO_DeInit(GPIOB, GPIO_PIN_10 | GPIO_PIN_11); HAL_DMA_DeInit(&hdma1_uart3); /* Peripheral interrupt DeInit*/ HAL_NVIC_DisableIRQ(USART3_IRQn); HAL_NVIC_DisableIRQ(DMA1_Channel2_IRQn); __HAL_UART_DISABLE_IT(&huart3, USART_IT_RXNE); /* USER CODE BEGIN USART3_MspDeInit 1 *//* USER CODE END USART3_MspDeInit 1 */ }}

(5)stm32f1xx_it.c增加
extern UART_HandleTypeDef huart3; extern DMA_HandleTypeDef hdma1_uart3; ............................./****************************************************** 函数名称:USART3_Own_IRQHandler 函数描述:USART3中断服务自定义代码部分 输入参数:pLinuxClass:传入LINUX_OBJECT 返回值:无 ******************************************************/ void USART3_Own_IRQHandler(LINUX_CLASS *pLinuxClass) { unsigned charucValue; // 使用了DMA发送,一定要加UART_FLAG_RXNE判断,否则成功回复一次后,会一直进下面这段,不知道原因 if ((__HAL_UART_GET_IT_SOURCE(&huart3, UART_IT_RXNE) != RESET) && (__HAL_UART_GET_FLAG(&huart3, UART_FLAG_RXNE)!= RESET))// 接收中断 { pLinuxClass->Rx_FROM_linux[pLinuxClass->Rx_FROM_linux_Counter] = (uint8_t)(huart3.Instance->DR & 0x00FF); pLinuxClass->Rx_FROM_linux_Counter++; if (pLinuxClass->Rx_FROM_linux_Counter >= RX_LINUX_MAX) { pLinuxClass->Rx_FROM_linux_Counter = 0; }pLinuxClass->RX_BYTE_TimeoutCounter_Lock = 0; // 接收数据字节间超时计时器开启 pLinuxClass->RX_BYTE_TimeoutCounter = 0; __HAL_UART_CLEAR_FLAG(&huart3, UART_FLAG_RXNE ); } if ((__HAL_UART_GET_IT_SOURCE(&huart3, UART_IT_TC) != RESET) && (__HAL_UART_GET_FLAG(&huart3, UART_FLAG_TC)!= RESET)) { huart3.State = HAL_UART_STATE_BUSY_RX; __HAL_UART_CLEAR_FLAG(&huart3, UART_FLAG_TC ); WRITE_485UN; // 485通讯方式 } // 溢出-如果发生溢出需要先读SR,再读DR寄存器 则可清除不断入中断的问题 if (__HAL_UART_GET_FLAG(&huart3,USART_FLAG_ORE) != RESET) { __HAL_UART_CLEAR_FLAG(&huart3,USART_FLAG_ORE); // read SRucValue = https://www.it610.com/article/(uint8_t)( huart3.Instance->DR & (uint8_t)0x00FF); // read DR } (void)ucValue; }void USART3_IRQHandler(void) { /* USER CODE BEGIN USART3_IRQn 0 */ USART3_Own_IRQHandler(&LINUX_OBJECT); /* USER CODE END USART3_IRQn 0 */ /* USER CODE BEGIN USART3_IRQn 1 */ /* USER CODE END USART3_IRQn 1 */ }void DMA1_Channel2_IRQHandler(void) { HAL_DMA_IRQHandler(&hdma1_uart3); }

【STM32F103 UART中断接收 DMA发送】

    推荐阅读