STM32マイコンのIoT実験で遊ぼう! その17 ~パルス幅計測回路を動かす~
今回の実験ではスイッチを押してパルスを作り、そのパルスの幅を計ります。スイッチが押されている時間を測定し、画面に出力します。
使用する外付け回路は、前回と同じです。
1.使用する外付け回路
チャタリング除去機能のあるスイッチ回路を使います。
2.マイコンの設定
① STM32CubeIDEを使用して、新しいプロジェクトを作成します。
② USBの設定と、基板上の2つのLEDを使いますので、PB4ピンとPA15ピンをGPIO_Output に設定します。
③ PA5ピンを入力端子として使います。
PA5ピンをクリックして、TIM2_CH1 を選択します。
④ インプット・キャプチャの設定を行います。
・Timers の TIM2を選び、Channel1のModeを「Input Capture direct mode」 に設定します。
・Counter Settings のPrescaler には48000-1 を設定して、48MHzのクロックから1kHzに分周して、1ミリ秒ごとにカウントアップするようにします。
・Counter Period は上限値の65535にします。
・Polarity Selection は、スイッチを押したときに捉えたいので、Rising Edge にします。
⑤ 割り込みの設定
・System Core の NVIC を選び、NVIC Interrupt Table の TIM2 global interrupt の Enable にチェックをいれ、Preempion Priority を1に設定します。
3.ソースプログラムの作成
次にプログラムのソースコードを自動生成します。
main.c が出来上がりました。
次のコードを追加します
ヘッダファイルをインクルードします。
複数の関数から参照する変数をグローバル変数として宣言します。
・char msgbuf[128];
パソコンに送信するメッセージを格納する配列を宣言
・int captureTime;;
計測した時間間隔を格納する変数を宣言
・HAL_TIM_IC_Start_IT(&htim2, TIM_CHANNEL_1);
タイマ入力キャプチャ機能(Input Capture)の設定および割り込みの有効化
・HAL_GPIO_WritePin(GPIOA,GPIO_PIN_15,GPIO_PIN_RESET);
A15ピンのLEDを消灯させます
・HAL_GPIO_WritePin(GPIOB,GPIO_PIN_4,GPIO_PIN_RESET);
B4ピンのLEDを消灯させます
・ICIntrCount = 0;
割り込み回数をカウントする変数の初期化
・snprintf(msgbuf,sizeof(msgbuf),"InputCapture: PUSH BUTTON: ");
パソコンに出力するメッセージを作ります
・CDC_Transmit_FS((uint8_t *)msgbuf,strlen(msgbuf));
パソコンに送信
・HAL_Delay(10);
10ミリ秒待ちます
・while(ICIntrCount < 2) ;
インプットキャプチャ割込みが2回発生するまで、空回し
・if(CaptureTime1 < CaptureTime2)
captureTime = CaptureTime2 - CaptureTime1;
else
captureTime = 65536 + CaptureTime2 - CaptureTime1;
1回目の計測値(CaptureTime1)と2回目の計測値(CaptureTime2)からボタンが押されていた時間を計算。
・snprintf(msgbuf,sizeof(msgbuf),"time=%d(ms)\r\n",captureTime);
パソコンに出力するメッセージを作ります
・CDC_Transmit_FS((uint8_t *)msgbuf,strlen(msgbuf));
パソコンに送信
・HAL_Delay(5000);
5秒待ちます
・void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim)
割り込みが発生すると呼び出される関数です
キャプチャした値を読み出し、次のキャプチャの準備をします。
・if(htim == &htim2){
++ICIntrCount;
switch(ICIntrCount){
タイマ2であることが確認できたら、ICIntrCount変数を1加算しています。そして、この変数の値によって、次のswitch文で分岐処理をします。
・case 1:
CaptureTime1 = __HAL_TIM_GET_COMPARE(htim,TIM_CHANNEL_1);
__HAL_TIM_SET_CAPTUREPOLARITY(htim,TIM_CHANNEL_1,
TIM_INPUTCHANNELPOLARITY_FALLING);
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_15,GPIO_PIN_SET);
break;
ICIntrCountが1の場合、1回目の割り込み処理です。ボタンを押したときに発生します。
その時点のタイマ値を、__HAL_TIM_GET_COMPARE()関数で読みだして、変数CaptureTime1に格納しています。
次に、__HAL_TIM_SET_CAPTUREPOLARITY()関数を呼び出して、キャプチャをおこなうトリガの設定をFALLING(ボタンが離されたとき)に変更をしています。
HAL_GPIO_WritePin(GPIOA,GPIO_PIN_15,GPIO_PIN_SET);で、橙色のLEDを点灯しています。
・case 2:
CaptureTime2 = __HAL_TIM_GET_COMPARE(htim,TIM_CHANNEL_1);
__HAL_TIM_SET_CAPTUREPOLARITY(htim,TIM_CHANNEL_1,
TIM_INPUTCHANNELPOLARITY_RISING);
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_4,GPIO_PIN_SET);
break;
ICIntrCountが2の場合、2回目の割り込み処理です。ボタンを離したときに発生します。
その時点のタイマ値を、__HAL_TIM_GET_COMPARE()関数で読みだして、変数CaptureTime2に格納しています。
次に、__HAL_TIM_SET_CAPTUREPOLARITY()関数を呼び出して、キャプチャをおこなうトリガの設定をRISING(ボタンが押されたとき)に変更をしています。
HAL_GPIO_WritePin(GPIOB,GPIO_PIN_4,GPIO_PIN_SET);で、緑色のLEDを点灯しています。
このプログラムを実行すると、2つのLEDは消灯状態で、画面には "InputCapture: PUSH BUTTON:" のメッセージが表示されます。
ボタンを押すと、橙色のLEDが点灯し、ボタンを離すと緑色のLEDが点灯し、画面にはボタンを押していた間の時間が表示されます。
4.ビルドの実行
成功!
エラーはありません。
5.マイコンへの書込み
ARM-First をパソコンに接続します。
STM32CubeProgrammer ツールで書込みます。
6.実行
プログラムを実行して、
端末エミュレータ(Tera Term)を起動します。
PUSH BUTTON のメッセージが表示されます。
ボタンを押すと、橙色のLEDが点灯して、計測開始です。
ボタンを離すと、緑色のLEDも点灯して、計測終了です。
ボタンを押していた間の時間が表示されました!
成功です!
(参考にした教材です)
CQ出版社の下記の書籍を参考にさせていただきました