見出し画像

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出版社の下記の書籍を参考にさせていただきました


いいなと思ったら応援しよう!