2016-04-26 9 views
1

USARTの動作に問題があり、お手伝いできない方がいらっしゃいますか?私は使用中の3つのUSARTを持つSTM32F303を使用しています。そのうちのUSART1は、DEラインが自動的に制御された非同期RS485ポートとして設定されています。マイクロコントローラのTX、RX、DEピンはTI SN65HVD1792 RS485トランシーバに接続されています。このトランシーバは、通信のために4本のライン(TX +、TX-、RX +、RX-)をユーザに提示します。STM32F303:RS485バス衝突後にUSART割り込みトリガが繰り返し発生する

私は、割り込み駆動のUSART通信を使用しています。これは、ほとんどの場合、絶対にうまく動作します。しかし、私は、RS485リンクが2線(TX +/RX +とTX-/RX-が一緒に接続され、両方の線に+ ve/-ve線を形成するように構成されている)送信および受信)、およびバス上の複数のデバイスが同時に送信しようとします。これが発生すると、STM32は電源が再投入されるまですべてのシリアル通信に応答しなくなります。

何が起こっているのか少し見ると、ボードの電源を切るまで、stm32f3xx_it.cのUSART1_IRQHandlerが繰り返し呼び出されています。これはstm32f3xx_hal_uart.cのHAL_UART_IRQHandler(& huart1)を呼び出します。この関数は、どの割り込みが発生したかをチェックする機能です(パリティエラー、フレームエラー、ノイズエラー、オーバーラン、ウェイクアップ停止、rxレジスタが空でない、tx ready、tx完了)それを適切に処理し、割り込み状態をクリアします。しかし、これらの特定の割り込みのどれもトリガされていないと認識されます。実行はすべての "if"文を単に通過し、関数が終了し、再び実行されます。

認識されたエラー状態が発生しないため、これが発生したことを認識する方法が見つかりません。私は、RS485バスの衝突が良いシステム設計によって避けられるべきであることを認識していますが、システムが顧客の設置場所にあるときに起こる可能性を排除することはできません。エラー、「矛盾した」メッセージを無視して続行 - 電源を切る必要があり、受け入れられません。

どのようにこの状態を認識するか、システムが割り込みループに入るのを止める方法について考えている人はいませんか? (13日11月15日、HALファイルのバージョン1.2.0)を以下のように割り込みルーチンが事前

おかげ

void HAL_UART_IRQHandler(UART_HandleTypeDef *huart) 
{ 
    /* UART parity error interrupt occurred -------------------------------------*/ 
    if((__HAL_UART_GET_IT(huart, UART_IT_PE) != RESET) && (__HAL_UART_GET_IT_SOURCE(huart, UART_IT_PE) != RESET)) 
    { 
    __HAL_UART_CLEAR_IT(huart, UART_CLEAR_PEF); 

    huart->ErrorCode |= HAL_UART_ERROR_PE; 
    /* Set the UART state ready to be able to start again the process */ 
    huart->State = HAL_UART_STATE_READY; 
    } 

    /* UART frame error interrupt occurred --------------------------------------*/ 
    if((__HAL_UART_GET_IT(huart, UART_IT_FE) != RESET) && (__HAL_UART_GET_IT_SOURCE(huart, UART_IT_ERR) != RESET)) 
    { 
    __HAL_UART_CLEAR_IT(huart, UART_CLEAR_FEF); 

    huart->ErrorCode |= HAL_UART_ERROR_FE; 
    /* Set the UART state ready to be able to start again the process */ 
    huart->State = HAL_UART_STATE_READY; 
    } 

    /* UART noise error interrupt occurred --------------------------------------*/ 
    if((__HAL_UART_GET_IT(huart, UART_IT_NE) != RESET) && (__HAL_UART_GET_IT_SOURCE(huart, UART_IT_ERR) != RESET)) 
    { 
    __HAL_UART_CLEAR_IT(huart, UART_CLEAR_NEF); 

    huart->ErrorCode |= HAL_UART_ERROR_NE; 
    /* Set the UART state ready to be able to start again the process */ 
    huart->State = HAL_UART_STATE_READY; 
    } 

    /* UART Over-Run interrupt occurred -----------------------------------------*/ 
    if((__HAL_UART_GET_IT(huart, UART_IT_ORE) != RESET) && (__HAL_UART_GET_IT_SOURCE(huart, UART_IT_ERR) != RESET)) 
    { 
    __HAL_UART_CLEAR_IT(huart, UART_CLEAR_OREF); 

    huart->ErrorCode |= HAL_UART_ERROR_ORE; 
    /* Set the UART state ready to be able to start again the process */ 
    huart->State = HAL_UART_STATE_READY; 
    } 

    /* Call UART Error Call back function if need be --------------------------*/ 
    if(huart->ErrorCode != HAL_UART_ERROR_NONE) 
    { 
    HAL_UART_ErrorCallback(huart); 
    } 

    /* UART wakeup from Stop mode interrupt occurred -------------------------------------*/ 
    if((__HAL_UART_GET_IT(huart, UART_IT_WUF) != RESET) && (__HAL_UART_GET_IT_SOURCE(huart, UART_IT_WUF) != RESET)) 
    { 
    __HAL_UART_CLEAR_IT(huart, UART_CLEAR_WUF); 
    /* Set the UART state ready to be able to start again the process */ 
    huart->State = HAL_UART_STATE_READY; 
    HAL_UARTEx_WakeupCallback(huart); 
    } 

    /* UART in mode Receiver ---------------------------------------------------*/ 
    if((__HAL_UART_GET_IT(huart, UART_IT_RXNE) != RESET) && (__HAL_UART_GET_IT_SOURCE(huart, UART_IT_RXNE) != RESET)) 
    { 
    UART_Receive_IT(huart); 
    /* Clear RXNE interrupt flag */ 
    __HAL_UART_SEND_REQ(huart, UART_RXDATA_FLUSH_REQUEST); 
    } 


    /* UART in mode Transmitter ------------------------------------------------*/ 
if((__HAL_UART_GET_IT(huart, UART_IT_TXE) != RESET) &&(__HAL_UART_GET_IT_SOURCE(huart, UART_IT_TXE) != RESET)) 
    { 
    UART_Transmit_IT(huart); 
    } 

    /* UART in mode Transmitter (transmission end) -----------------------------*/ 
if((__HAL_UART_GET_IT(huart, UART_IT_TC) != RESET) &&(__HAL_UART_GET_IT_SOURCE(huart, UART_IT_TC) != RESET)) 
    { 
    UART_EndTransmit_IT(huart); 
    } 

} 
+0

デバッガにアクセスできますか? if文を壊して、どの割り込みがトリガされているかを確認できますか?私の推測では、割り込みがトリガされ、フラグが正しくリセットされていないということです。私の最初の推測はTXEフラグ/ ITです。 – mban

+0

こんにちはmban - 私はそれをしました。 if文はすべて「false」と評価されます。割り込みフラグはリセットされないので、割り込みハンドラへの繰り返しエントリが発生する可能性がありますが、割り込みはトリガされたものとして認識されないため、割り込みハンドラがなぜ入力されているのかわかりません。ありがとう – JMessenger

+0

割り込みルーチンを投稿できますか?それが私が考えているのと同じものなら、if文ごとに2つのチェックがあります.1つはIT用、もう1つはフラグ用です。割り込みがトリガされている可能性がありますが、フラグはリセットされず、適切な割り込み処理ステートメントに入ることができません。これは、実際にはHALライブラリの問題です。彼らはかなり厄介なバグを持っています。 – mban

答えて

0

は、私はどうしたらまず最初は、割り込みのすべてを無効にすることですあなたは明示的に使用していません。少なくとも、これは原因を特定するのに役立つはずです。無効にする割り込みを渡すことにより、マクロ__HAL_UART_DISABLE_IT()でこれを行います。

これでうまくいかない場合は、UART_Transmit_IT()関数がIRQによって呼び出されて、TXE割り込みが無効になっていることを確認してください。これが問題であるかどうかを簡単に把握するには、手動で割り込みを無効にして(問題が発生している間)、IRQがトリガを停止しているかどうかを確認することがあります。そうでなければ、UART_Transmit_IT()関数を実行し、__HAL_UART_DISABLE_IT(huart, UART_IT_TXE);行が実行されるかどうかを調べることができます。終了時にTXE割り込みが適切に無効にされていない場合、引き続き引き金を引いて、見た目に似たものが発生します。

関連する問題