關於stm32不斷進入串口中斷的問題


問題說明:比如說我串口中斷函數執行時間是2s,在2s內再次發生串口中斷,就會造成無法進入接收中斷

void USART2_IRQHandler(void)
{
if(USART_GetITStatus(USART2,USART_IT_RXNE) != RESET)
{
USART_ClearITPendingBit(USART2,USART_IT_RXNE);
led_toggle();
delay_ms(1000);
delay_ms(1000);
}
}

具體現象就是串口發送數據給單片機,led燈不會閃爍,但是用示波器觀察單片機的RX腳,每次觸發都有信號,說明串口是有把信號給單片機的。

於是做了下面這樣的測試

void USART2_IRQHandler(void)
{
   
        led_toggle();
        delay_ms(1000);
        delay_ms(1000);
    
}

當進入串口中斷后在2s內再次通過串口給單片機發送數據,則led燈會一直閃爍(每隔2s)即使沒有再給單片機發送數據,led燈也會一直閃爍,是什么原因造成單片機一直進入串口中斷呢?

於是做了下面這樣的測試

void USART2_IRQHandler(void)
{
    
    led_toggle();
    delay_ms(1000);
    delay_ms(1000);
    
    if(USART_GetITStatus(USART2,USART_IT_RXNE) != RESET)
    {
        USART_ClearITPendingBit(USART2,USART_IT_RXNE);
        UART_RxBuf[0] = USART_ReceiveData( USART2 ); 
    }
    if(USART_GetITStatus(USART2,USART_IT_ORE) != RESET)
    {
        USART_ClearITPendingBit(USART2,USART_IT_ORE);
        UART_RxBuf[0] = USART_ReceiveData( USART2 );  
    }
    
    
    if(USART_GetITStatus(USART2,USART_IT_PE) != RESET)
    {
        USART_ClearITPendingBit(USART2,USART_IT_PE);
    }
    
    if(USART_GetITStatus(USART2,USART_IT_TXE) != RESET)
    {
        USART_ClearITPendingBit(USART2,USART_IT_TXE);
    }
    
    if(USART_GetITStatus(USART2,USART_IT_TC) != RESET)
    {
        USART_ClearITPendingBit(USART2,USART_IT_TC);
    }
    
    if(USART_GetITStatus(USART2,USART_IT_IDLE) != RESET)
    {
        USART_ClearITPendingBit(USART2,USART_IT_IDLE);
    }
    
    if(USART_GetITStatus(USART2,USART_IT_LBD) != RESET)
    {
        USART_ClearITPendingBit(USART2,USART_IT_LBD);
    }
    
    
    if(USART_GetITStatus(USART2,USART_IT_CTS) != RESET)
    {
        USART_ClearITPendingBit(USART2,USART_IT_CTS);
    }
    
    
    if(USART_GetITStatus(USART2,USART_IT_ERR) != RESET)
    {
        USART_ClearITPendingBit(USART2,USART_IT_ERR);
    }
    
    
    if(USART_GetITStatus(USART2,USART_IT_NE) != RESET)
    {
        USART_ClearITPendingBit(USART2,USART_IT_NE);
    }
    
    if(USART_GetITStatus(USART2,USART_IT_FE) != RESET)
    {
        USART_ClearITPendingBit(USART2,USART_IT_FE);
    }
    
}

發現觸發中斷的條件一種都不滿足,但還是一直進入中斷,查資料后發現

stm32中文參考手冊541業

ORE:過載錯誤 (Overrun error)
RXNE仍然是’1’的時候,當前被接收在移位寄存器中的數據,需要傳送至RDR寄存器時,硬
件將該位置位。如果USART_CR1中的RXNEIE’1’的話,則產生中斷。由軟件序列將其清零
(先讀USART_SR,然后讀USART_CR)
0:沒有過載錯誤;
1:檢測到過載錯誤。
注意:該位被置位時, RDR寄存器中的值不會丟失,但是移位寄存器中的數據會被覆蓋。如果
設置了EIE位,在多緩沖器通信模式下, ORE標志置位會產生中斷的

 

解決方法,在串口初始化配置時,打開ORE溢出中斷

 USART_Init(USART2, &USART_InitStructure); //初始化串口4
    USART_ClearFlag(USART2, USART_FLAG_RXNE);//防止配置完就進入中斷
    USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);//開啟串口接受中斷
    USART_ITConfig(USART2, USART_IT_ORE, ENABLE);//開啟串口溢出中斷
    USART_Cmd(USART2, ENABLE);                 
void USART2_IRQHandler(void)
{
    
    led_toggle();
    delay_ms(1000);
    delay_ms(1000);
    
    if(USART_GetITStatus(USART2,USART_IT_RXNE) != RESET)
    {
        USART_ClearITPendingBit(USART2,USART_IT_RXNE);
        UART_RxBuf[0] = USART_ReceiveData( USART2 ); 
    }
    if(USART_GetITStatus(USART2,USART_IT_ORE) != RESET)
    {
        USART_ClearITPendingBit(USART2,USART_IT_ORE);
        UART_RxBuf[0] = USART_ReceiveData( USART2 );  //這步一定要有的,相當於清空緩存區
    }
}

 

 

 



免責聲明!

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



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