STM32CubeMX配置串口——HAL+DMA+串口空闲中断

什么是空闲中断?

说直白一点,就是你的串口在接收数据的时候,并不是一直都在接收的。我们的数据一般是打包成数据帧的形式进行发送或者接收。举个例子,你有一个设备,通过串口以100hz的速度给stm32发送数据,一帧数据是32个字节。也就是说,10ms发送一次。在这10ms中,其中不到1ms是在接收数据,而其他9ms你的串口都是处于空闲状态。从接收数据切换到空闲状态,stm32就会产生一次中断。这就是空闲中断!

空闲中断有什么好处?

试想一下,你有一个蓝牙小车。你的遥控器要给他发送方向,速度等数据。数据帧以“帧头+数据+校验+帧尾”的方式发送。这种方式,通过在程序中判断是否接收到帧尾来确定数据接收完毕,这就要造成频繁进入中断去判断,造成额外的开销。如果你的数据量较大,甚至直接影响到主程序的运行。

STM32单片机空闲检测中断可以很好的解决这个问题。他的工作原理为:当STM32的串口接收完一包数据后,会产生一个空闲中断。这个中断在串口其他任何状态都不产生,只会在接收完一包数据后才会产生,一包数据可以是1个字节或者多个字节。因此,我们可以在这个空闲中断函数中,设置一个接收完成标志位。那么,我们只需要在主程序中检测这个标志位就知道数据是否接收完成了。这种方式甚至都不需要你的数据打包成帧。

利用STM32CubeMX+DMA实现空闲中断

加上DMA的好处就是,你的stm32在接收数据时,只用产生一次空闲中断,就可以获得你的一帧数据了。而不用在频繁去判断。废话不多说,上配置:

创建stm32工程:选择异步,打开全局中断

STM32CubeMX配置串口——HAL+DMA+串口空闲中断_第1张图片

STM32CubeMX配置串口——HAL+DMA+串口空闲中断_第2张图片

基本的配置结束之后,就是重头戏了

新建一个c文件,然后在C文件中添加如下两个函数。

void Usart_Receive_Data(UART_HandleTypeDef *huart)
{
        if(RESET != __HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE))   //判断是否是空闲中断
        {
            __HAL_UART_CLEAR_IDLEFLAG(huart);                     //清除空闲中断标志(否则会一直不断进入中断)
            Mycallback_handler();                                 //调用中断处理函数,这个函数自己写
            memset(buffer,0,255);                                 //清空缓冲区
            HAL_UART_Receive_DMA(huart, buffer, 255);             //重启开始DMA传输
        }
}
void Mycallback_handler(void)
{
/*写下你自己的中断处理过程*/
}

main函数中进行初始化

STM32CubeMX配置串口——HAL+DMA+串口空闲中断_第3张图片

在stm32f1xx_it.c文件中,找到void USART1_IRQHandler(void)函数,并添加Usart_Receive_Data(&huart1)

void USART1_IRQHandler(void)
{
  /* USER CODE BEGIN USART1_IRQn 0 */

  /* USER CODE END USART1_IRQn 0 */
  HAL_UART_IRQHandler(&huart1);
  /* USER CODE BEGIN USART1_IRQn 1 */
  Usart_Receive_Data(&huart1);      <-----------------/*在这里添加*/
  /* USER CODE END USART1_IRQn 1 */
}

这样,当产生空闲中断或者buffer中的数据超过255个时,进入Usart_Receive_Data()函数,进而进入Mycallback_handler()函数。所以这个255一定要大于你要发送的最大数据量,当然也不是越大越好。

你可能感兴趣的:(stm32,单片机)