STM32 ゼロから始めるローパワーマイコン ADCを使ってスイッチを読み分ける 前編

STM32 ゼロから始めるローパワーマイコン ADCを使ってスイッチを読み分ける 前編

皆さま こんにちは。

今回はADCを使ったスイッチの読み分け(判定)をしてみます。

スイッチ4つの on/off 判定は4ビットのI/Oポートを使うのが一般的だと思います。

20ピンマイコンで4ビットを消費してしまうのはもったいないので、ADCを使い1ビットで4つの内のどのスイッチが押されたのか判定してみます。

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

PC:Windows10 OS
IDE: STM32CubeIDE Version1.3.0
Configurator: STM32CubeMX Version5.6.0
マイコン: STM32L010F4P6
Board: 自作のボード

回路図

USBシリアルモジュールを使って結果を出力するので、その回路をベースにスイッチと抵抗を追加しました。
回路図は以下の通りです。

ADCを使ってどのスイッチが押されたのか判定する

ADCはアナログ・ディジタル・コンバーターの略で、アナログの電圧をディジタルに変換するものです。

ADCについてご存じない方は STM32 HALを使ってAD変換してみる という記事を書いていますので参考にしてください。

スイッチの情報はマイコンの7番ピン(PA1)に接続しています。
データシートを見て頂くとわかりますが、このピンには ADC_IN1 の機能が割り振られています。

ADコンバータのチャンネル1の機能になります。

押されたスイッチによってADC_IN1に読み込まれる電圧がかわるので、ADCで読み込むことでどのスイッチが押されたのか判定しようというものです。

ADCは分解能を12ビットで使い最大値が4000ちょっとと考えて、

S1 ON時の変換値が : 0
S2 ON時の変換値が : 1000ちょっと
S3 ON時の変換値が : 2000ちょっと
S4 ON時の変換値が : 3000ちょっと

になるように E24系までの抵抗値 で R4,5,6,7 を決めました。

使用するプロジェクト

IDEで以前つくったSTM32L-UARTのプロジェクトを開きます。

まだプロジェクトをつくられていない方は STM32 ゼロから始めるローパワーマイコン USBシリアル通信してみる 前編 からの 前・後編を参考にしてUSBシリアル通信ができるようにしておきます。

コンフィグレーターで設定を行う

IDEを起動したら Project Explorer から(水色のアイコンの) STM32L-UART.ioc ファイルをダブルクリックします。

This kind of project is associated with the STM32CubeMx perspective. Do you want to open this perspective now ? と聞いてくるので Yesを押します。

これは平たく言うと STM32CubeMX を IDE に関連づけして開きますか? という内容です。
初期化コード生成ツールを STM32CubeIDE に統合して使えるようなイメージになります。

これで設定画面が開きます。(いわゆるコンフィグレーターの設定画面が開きます)

ADCが使えるように設定する

マイコンの図が出てくるので7番ピンをクリックし、出てきたリストから ADC_IN1 を選択します。

タイマー割り込みの設定を行う

clock Configuration タブをクリックし、クロックの系統図を開きます。

SYSCLK, APB1 Timer, APB2 Timer が 2.097MHz であることを確認します。

Pinout & Configuration – Categories – Timers をクリックし, TIM2 をクリックします。

TIM2 Mode and Configuration – Clock Source で Internal Clock を選択します。

Configuration – Parameter Settings – Counter Settings を以下の通りに設定します。

Prescaler : 499
Counter Mode : Up
Counter Period : 42
Internal Clock Division : No Division
auto-reload preload : Enable

そして NVIC Settingsを選択し、 TIM2 global interrupt Enabled にチェックを入れます。

10msecでタイマー割り込みする計算

プリスケーラ × カウンタピリオド × 1/f = タイマー周期[秒] になります。
クロック周波数 f = 2.097MHz です。
プリスケーラを 50 、タイマー周期を約 10msec とすると、カウンタピリオドは 420 になります。
プリスケーラとカウンタピリオドは16ビットなので 1-65535 までの値を設定するようにしてください。
それからオートリロードを Enable にしておきます。

プリスケーラとカウンタピリオドのカウント始まりはゼロなので、-1した値を設定します。

プリスケーラは 49, カウンタピリオドは 419 を設定します。

以下の画像の通りであることを確認してください。

パラメーターの設定

割り込みの設定

ビルドする

ひとまず、ここまでで一度ビルドしておきましょう。

Project – Build All を選択します。

Do you want generate Code ? と聞いてくるので Yes を選択します。

MX_TIM2_Init()という関数が追加されて設定した値を確認することができます。

コーディングする

タイマーを動かすにはスタートの関数を呼ぶ必要があります。
main.cの while()ループの手前の BEGIN 2 と END 2 の間に以下の関数を記述します。

  MX_TIM2_Init();
  /* USER CODE BEGIN 2 */
  HAL_TIM_Base_Start_IT(&htim2);
  /* USER CODE END 2 */

次に Core - Src - stm32l0xx_it.c をダブルクリックして開き、以下の関数内に HAL_GPIO_TogglePin()を追記します。
お約束で BEGIN と END の間に記述するのでしたね。

TIM2_IRQHandler()がTIM2の割り込み関数になります。

void TIM2_IRQHandler(void)
{
  /* USER CODE BEGIN TIM2_IRQn 0 */

  /* USER CODE END TIM2_IRQn 0 */
  HAL_TIM_IRQHandler(&htim2);
  /* USER CODE BEGIN TIM2_IRQn 1 */
  HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_1);
  /* USER CODE END TIM2_IRQn 1 */
}

ビルドして実行してみる

Project - Built All でビルドしてエラーがないことを確認し、 Run - Debug します。

HAL_Init()のところで停止するので、F8キーを押して実行します。

LEDは点灯しているように見えます。

LEDを点灯させたり消灯させたりしているのですが、人間の目には点灯している残像が残っていて消えているように見えないというわけです。

プログラムと設定が正しければ、割り込みサービスルーチンのTIM2_IRQHandler()内でHAL_GPIO_TogglePin()が実行されているはずです。

stm32l0xx_it.c の HAL_GPIO_TogglePin()のところをダブルクリックしてみます。(ブレークポイントを貼る)

プログラムが停止したら F8キーを押します。停止するたびにF8キーを押すとLEDが点滅しLチカ動作していることがわかりました。

次回はタイマー割り込み処理ルーチン内にAD変換の処理を実装します。

少し長くなりましたので、この続きは次回に。

お疲れさまでした。

続きを読むには こちら からどうぞ。

LowPowerカテゴリの最新記事