STM32串口空闲中断

简介: STM32串口空闲中断

STM32如何接收不定长数据?

Modbus协议中经常返回的数据的长度是不同的,或者在使用串口通讯的一些模块的时候发送不同的命令返回的一帧数据的长度也是不同,因此在接收的时候我们需要准确判断一帧数据是否已经传输完成,传输完成后再对数据进行分析。判断一帧数据是否传输完成有两种方法,第一种是使用定时器,定时一个字节的数据传输的时间,当进入定时器中断,表示在一个字节的传输时间内未收到数据,表示一帧数据传输完成,同时在串口接收中断中需不断重新开始定时器计时,该方法比较麻烦,还占用定时器的资源。第二种是使用串口的空闲中断判断一帧数据是否传输完成。


串口的空闲中断

检测到接收数据后,在数据总线上的一个字节时间内,没有接收到数据触发空闲中断。RXNE置位一次,空闲总线就检测一次!上电后未触发串口接收中断即未接收到数据时不会进入空闲中断。


HAL库代码

注意:初始化的时候需要打开空闲中断和接收中断(勿使用HAL_UART_Received_IT()使能中断)

初始化:

    /*Enable USART1 idle interrupt*/  
   __HAL_UART_ENABLE_IT(&huart1,UART_IT_IDLE);  
    /*Enable USART1 received interrupt*/  
    __HAL_UART_ENABLE_IT(&huart1,UART_IT_RXNE);  
串口接收中断:
    /** 
      * @brief This function handles USART1 global interrupt. 
      */  
    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 */  
     /*Enter USART1 received interrupt*/  
    if(__HAL_UART_GET_FLAG(&huart1, UART_FLAG_RXNE) != RESET)  
     {  
        /*Clear USART1 received interrupt flag*/  
         __HAL_UART_CLEAR_FLAG(&huart1, UART_FLAG_RXNE);  
         /*Save the USART1 received data to Rec_Buff[]*/  
         Rec_Buff[Rec_Cnt] = USART1 -> DR;  
         SEGGER_RTT_printf(0, "Enter usart1 received interrupt! Rec_Buff[%d] = %x\n", Rec_Cnt, Rec_Buff[Rec_Cnt]);  
         Rec_Cnt++;  
         if(Rec_Cnt > 31)  
         {  
             Rec_Cnt = 0;  
         }  
     }  
     /*Enter USART1 idle interrupt*/  
     else if(__HAL_UART_GET_FLAG(&huart1, UART_FLAG_IDLE) != RESET)  
     {  
         /*Clear USART1 idle interrupt flag*/  
         __HAL_UART_CLEAR_IDLEFLAG(&huart1);  
         /*Enter USART1 idle interrupt clear Rec_Cnt, Ready to receive another frame of data*/  
         Rec_Cnt = 0;  
         SEGGER_RTT_printf(0, "Enter usart1 idle interrupt! Rec_Cnt = %d\n", Rec_Cnt);  
     }  
     /* USER CODE END USART1_IRQn 1 */  
   }

标准库代码

初始化:

1.    USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); //使能接收中断  
2.    USART_ITConfig(USART1, USART_IT_IDLE, ENABLE); //使能接收空闲中断


串口接收中断:

    /*串口接接收中断服务函数*/  
    void USART1_IRQHandler(void)  
    {  
        if(USART_GetITStatus(USART1, USART_IT_IDLE) != RESET) //触发空闲中断,表示一帧数据传输完成  
        {     
            volatile uint8_t Clear = 0;  
            Idle_Flag = 1;  
USART_ClearITPendingBit(USART1, USART_IT_IDLE);  //清除空闲中断标志位  
           Clear = (USART1 -> DR); //测试发现无该语句无法每次都能进入空闲状态  
           Rx_Cnt = 0;  
       }  
       if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  
       {  
           USART_ClearITPendingBit(USART1, USART_IT_RXNE);  //清除接收中断标志位  
          Rec_Buff[Rx_Cnt] = (USART1 -> DR); //接收到的字节保存,数组地址加1  
          SEGGER_RTT_printf(0, "Rec_Buff[%d] = %d\n", Rx_Cnt, Rec_Buff[Rx_Cnt]);  
           Rx_Cnt++;  
           Rec_Data = Rx_Cnt;  
           SEGGER_RTT_printf(0, "Rx_Cnt = %d, Rec_Data = %d\n", Rx_Cnt, Rec_Data);  
          if(Rx_Cnt == 3)  
           {  
               Rx_Cnt = 0;  
           }     
       }  
   }


注意:使用标准库清除空闲中断标志位一定要加上“Clear = (USART1 -> DR);”该语句,否则会存在异常。


以此作为日常学习的记录,有不对之处欢迎大家指正!

相关文章
|
6月前
|
开发者
STM32中断详解及其编程实践
STM32中断详解及其编程实践
391 1
|
4月前
stm32f407探索者开发板(十七)——串口寄存器库函数配置方法
stm32f407探索者开发板(十七)——串口寄存器库函数配置方法
646 0
|
4月前
STM32CubeMX 串口收发一帧数据
STM32CubeMX 串口收发一帧数据
50 9
|
4月前
|
芯片
STM32CubeMX 串口数据收发
STM32CubeMX 串口数据收发
122 2
|
4月前
|
监控
stm32f407探索者开发板(十八)——串口通信实验讲解(USART_RX_STA流程图详解)
stm32f407探索者开发板(十八)——串口通信实验讲解(USART_RX_STA流程图详解)
219 0
|
5月前
|
芯片
【STM32】STM32简述中断的基础知识
【STM32】STM32简述中断的基础知识
|
6月前
|
存储 缓存 芯片
STM32--USART串口
STM32--USART串口
101 0
|
6月前
|
Java C语言
STM32使用printf重定向到USART(串口)并打印数据到串口助手
STM32使用printf重定向到USART(串口)并打印数据到串口助手
295 0
|
6月前
|
存储 传感器
【STM32基础 CubeMX】uart串口通信
【STM32基础 CubeMX】uart串口通信
341 0