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串口编程基础知识讲解
58 0
|
1月前
|
存储 缓存 芯片
STM32--USART串口
STM32--USART串口
|
1月前
|
Java C语言
STM32使用printf重定向到USART(串口)并打印数据到串口助手
STM32使用printf重定向到USART(串口)并打印数据到串口助手
35 0
|
6月前
|
存储 物联网 芯片
STM32速成笔记(十四)—串口IAP
本文介绍了什么是IAP,IAP有什么作用,如何实现IAP。最后,给出了IAP的实现程序。
115 0
STM32速成笔记(十四)—串口IAP
|
6月前
|
芯片
STM32速成笔记(四)—中断
本文介绍了中断的概念,中断的相关名词,STM32外部中断配置方法以及使用中断的注意事项。给出了外部中断点亮LED程序设计思路和关键代码。
164 0
STM32速成笔记(四)—中断
|
7月前
STM32F0单片机快速入门七 串口(UART)操作从轮询到中断
STM32F0单片机快速入门七 串口(UART)操作从轮询到中断
STM32F0单片机快速入门七 串口(UART)操作从轮询到中断
|
7月前
|
芯片
STM32F0单片机快速入门六 用库操作串口(UART)原来如此简单
STM32F0单片机快速入门六 用库操作串口(UART)原来如此简单
|
7月前
|
缓存 自然语言处理 网络协议
STM32CubeMX | | 使用小熊派串口驱动峰汇ETH-01以太网模块上传数据到OneNet
STM32CubeMX | | 使用小熊派串口驱动峰汇ETH-01以太网模块上传数据到OneNet
103 0
No.8 STM32F429IGT6 USART串口初始化结构体 总结
No.8 STM32F429IGT6 USART串口初始化结构体 总结
|
2月前
|
C++ 芯片 编译器
STM32F103标准外设库—— 新建工程与库函数(四)
STM32F103标准外设库—— 新建工程与库函数(四)
44 0
STM32F103标准外设库—— 新建工程与库函数(四)