STM32 HAL庫關於串口中斷燒錄程序后可以正常運行,斷電重啟后無法進入中斷的問題分析以及解決方法


1、情景描述:

  最近在做一個項目,X86的上位機通過串口控制MCU,使用串口中斷接收上位機數據時,MCU在上電的情況下燒錄程序,可以正常接收上位機的數據,在斷電重啟后,一直進入不了中斷回調函數,上電的情況是X86上電,MCU也同時上電。

 

2、原因分析:

  造成這個的原因是因為硬件上電的時候,因為X86跟MCU是同時上電的,上電后會把串口的電平拉高,這個高電平觸發了MCU的串口中斷,導致MCU的串口中斷誤以為接收到了一個數據,例如 HAL_UART_Receive_IT(&huart1, (uint8_t *)Rx_buff, 5) 這里,上電后MCU誤以為接收了一個數據,還剩下4個數據沒有接收,然后上位機每次發送5個數據過來后MCU中斷數據接收個數錯誤,所以一直無法進入中斷回調函數。

  我們看到 HAL_StatusTypeDef UART_Receive_IT(UART_HandleTypeDef *huart) ,里面的 RxXferCount  是告訴我們中斷要接收的剩余數據量大小,根據上面舉例子的話,上電時因為那個高電平的原因導致 RxXferCount 變成了4,如下圖打印信息所示

  

   接着我們重新看回 HAL_StatusTypeDef UART_Receive_IT(UART_HandleTypeDef *huart) 函數里的調用回調函數部分,下圖所示,發現 RxXferCount  要為0的時候才會調用中斷回調函數,依舊以上面例子說明,當MCU誤以為上電時的高電平為數據時,上位機再發送5個數據下來,RxXferCount  就永遠無法變成0,所以導致一直進入不了中斷回調函數。

  

 

 3、解決方法:

  3.1軟件解決方法

    軟件解決的時候,我們要知道導致這個問題的根源是 RxXferCount 這個值被誤判了,所以我們只需要在上電的時候,對這個值進行修正即可;

    首先我們定義一個標志位,用來標志MCU的狀態是剛上電的狀態  

char uart_error_flag=0;

    接着我們編寫函數對 RxXferCoun 值進行處理

/***
 函數名:void uart_error(void)
 說  明:解決剛上電時,由於串口電平拉高,導致串口中斷誤以為接收到了一個字節,
        導致后面接收數據個數一直錯誤,無法進入中斷回調函數問題
 傳入值:無
 傳出值:無
**/
void uart_error(void)
{
      if( (huart1.RxXferCount < Rxdsize) && (uart_error_flag==0) )
        { 
            /*RxXferCount 告訴我們剩余空間大小,如果剩余空間和總空間不一樣,則說明中斷收到數據了*/
            printf("huart1.RxXferCount = %d\r\n",huart1.RxXferCount);    
            uart_error_flag = 1;
            huart1.RxXferCount = 5; //修改剩余空間,防止無法進入回調        
        }
}

    最后我們在 main 函數里的 while 循環前調用即可

int main(void)
{

  HAL_Init();
  SystemClock_Config();
  MX_GPIO_Init();
  MX_USART2_UART_Init(); //初始化打印信息串口
  MX_USART1_UART_Init(); //初始化中斷接收串口  
  HAL_UART_Receive_IT(&huart1, (uint8_t *)Rx_buff, Rxdsize); //打開串口中斷接收
  uart_error(); //處理上電時串口中斷誤判的問題
  while (1)
  {
   /* 注意要在中斷回調函數里重新打開串口中斷接收,否則串口中斷接收只能接收一次 */
  }
}

  3.2 硬件解決方法

    硬件解決方法比較粗暴,就是做一個電源延時電路,等X86重新上電后,再給MCU上電。

 

補充說明:

  使用DMA接收時候不會出現這種情況,不過使用DMA接收,如果上位機發送數據過快,會出現數據粘包現象,例如上位機發送是數據一包是5個數據,如果上位機發送數據過快(20ms以內),MCU就好會把接收到的好幾包數據當做一包數據來處理,例如把3包數據當做1包數據來處理,這樣MCU就會誤以為一包數據的15個了,出現誤判的情況,不過它接收的數據是准確的,就是分包能力沒有串口中斷強。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM