STM32 DMA+空闲中断实现不定长数据接收
STM32CubeMX配置
1. 将串口设置为异步通信,波特率根据个人情况而定
2. 设置串口DMA接收
3. 打开串口中断
代码添加
1. 使能中断并开启接收
串口初始化完成后添加如下代码:
//使能接收中断和空闲中断并打开DMA接收
__HAL_UART_ENABLE_IT(&huart1, UART_IT_RXNE);
__HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);
__HAL_UART_CLEAR_IDLEFLAG(&huart1);
HAL_UART_Receive_DMA(&huart1, usart1_recv, RECV_SIZE);
2. 编写中断服务函数
/**
* @brief This function handles USART1 global interrupt.
*/
void USART1_IRQHandler(void)
{
/* USER CODE BEGIN USART1_IRQn 0 */
if(RESET != __HAL_UART_GET_FLAG(&huart1, UART_FLAG_IDLE)) //判读是否触发空闲中断
{
uint16_t temp = 0;
__HAL_UART_CLEAR_IDLEFLAG(&huart1); //清除空闲中断标志位
HAL_UART_DMAStop(&huart1); //关闭MDA
//以下两行用来清除中断,软件清除空闲中断先读SR后读DR
temp = huart1.Instance->SR; //清除SR状态寄存器
temp = huart1.Instance->DR; //读取DR数据寄存器
uint8_t data_length = RECV_SIZE - __HAL_DMA_GET_COUNTER(&hdma_usart1_rx); //获取接收的数据长度
printf("Receive Data length = %d\r\n",data_length);
printf("Receive Data:%s\r\n", usart1_recv);
memset(usart1_recv, 0, RECV_SIZE);
}
/* USER CODE END USART1_IRQn 0 */
HAL_UART_IRQHandler(&huart1);
/* USER CODE BEGIN USART1_IRQn 1 */
HAL_UART_Receive_DMA(&huart1, usart1_recv, RECV_SIZE); //重新打开DMA接收
/* USER CODE END USART1_IRQn 1 */
}