STM32でシリアル通信してみる 割り込み編 その2

  • 2020.02.11
  • HAL
STM32でシリアル通信してみる 割り込み編 その2

今回は割り込みを使ったシリアル通信の続きです。

投稿時の開発環境を記しておきます。

PC:Windows10 OS
IDE: STM32CubeIDE Version1.1.0
Configurator: STM32CubeMX Version5.4.0
Board: STM32Nucleo-F401RE

割り込み処理の動作を確認してみる

それでは割り込み処理の動作を追いかけてみることにしましょう。

割り込みコントローラはNVICと呼ばれています。
NVICはベクタ割り込みをサポートしていて、割り込みや例外の要因別にベクタテーブルに登録されているアドレスに分岐してくれます。

USART2の割り込みベクタは stm32f4xx_it.c の203行目付近に書かれています。

HAL_UART2_IRQHandler関数内の HAL_UART_IRQHandler(&huart2); の行番号をダブルクリックしてブレークポイントを貼ります。

次にPC側のターミナルソフトを立ち上げます。
今回も Tera Term を使います。
Tera Term を起動し、新しい接続でシリアルを選択し、ポートは ST-Link Virturl COMポートが表示されるCOMポート番号を選択します。

設定ーシリアルポートで以下のように通信パラメータを設定します。

これらの値は MX_USART2_UART_Init()で設定された値に合わせておく必要があります。

IDE側は Run – Resume でプログラムを動かします。

Tera Term のウィンドウをクリックしてアクティブにしておき、何かキーをひとつだけ押します。

データが送られて来てプログラムがブレークポイントで停止します。

F5キーを押すとプログラムをステップ実行しますので、割り込みの中でどんな処理が行われているのか確認することができます。

ステップ実行していくと HAL_UART_IRQHandler内の UART_Receive_IT(huart) に来ます。

*huart->pRxBuffPtr++ = (uint8_t)(huart->Instance->DR & (uint8_t)0x00FF);

の行で受信したデータをバッファに保存します。

1回目(1バイト目)の受信なので、次の処理で RxXferCount は1になるため if() の中の処理は実行されません。

if (–huart->RxXferCount == 0U)
{

}

ステップ実行していき if() の外に出たら再び Run – Resume でプログラムを動かします。

Tera Term のウィンドウをクリックしてアクティブにして、もう一度何かキーをひとつだけ押します。

割り込み処理に入ってきてブレークポイントで停止するので F5キーでステップ実行していきます。

2回目(2バイト目)の受信なので、次の処理で RxXferCount は0になり if()の中の処理が実行されます。

if (–huart->RxXferCount == 0U)
{

}

受信系の割り込みをディセーブルにした後、HAL_UART_RxCpltCallback が呼ばれます。
ここで gUartReceive = 1 にしているので main関数の方の while()ループを抜けて HAL_UART_Transmit_IT(&huart2, buffer, 2); が実行されます。

ブレークポイントを解除して Run – Resume でプログラムを動かしてみましょう。
(解除はブレークポイントを貼った行の行番号をダブルクリックします)

送信系の割り込み処理について

HAL_UART_Transmit_IT では

huart->pTxBuffPtr = pData;
huart->TxXferSize = Size;
huart->TxXferCount = Size;
__HAL_UART_ENABLE_IT(huart, UART_IT_TXE);

のようにコードが書かれていて、構造体の送信バッファポインタにバッファの先頭アドレスをセットしています。
それから送信するデータのサイズをサイズとカウンタ変数にセットしています。
そして送信系の割り込みが入るようにしています。

割り込みベクタは USART2 に対するものなので送信も受信も同じです。
USART2_IRQHandler ~ HAL_UART_IRQHandler が呼ばれる流れになります。

そして UART_Transmit_IT が呼ばれてデータを送信します。

1回目(1バイト目)の送信なので、次の処理で TxXferCount は1になるので if()の中の処理は実行されません。

if (--huart->TxXferCount == 0U)
{
      __HAL_UART_DISABLE_IT(huart, UART_IT_TXE);
      __HAL_UART_ENABLE_IT(huart, UART_IT_TC);...
}

2回目(2バイト目)の送信後に TxXferCountが0になり、if()の中の処理が実行され送信割り込みがディセーブルされます。

受信したbufferの中には送られてきたデータが入っていて、それをそのまま返信しています。

Tera Term で送った2つの文字がループバックして表示されれば成功です。

HALカテゴリの最新記事