STマイクロエレクトロニクスのSTM32 MCUのタイマ機能を使ってLチカする。
32ビットのARM系組み込みチップは、8ビットのPICやAVRに比べて、CPUが高性能になっているばかりでなく、ペリフェラルも高性能なものが組込まれていて、CPUを介さず独立してI/O制御を行えるだけの機能を持っている。しかし、mbedやarduino IDEといった汎用組み込みOSは、このようなペリフェラルを直接制御するAPIを持っておらず、CMSIS(Cortex Microcontroller Software Interface Standard)やSTM32Cube HAL(Hardware Abstraction Layer)といった、低レベルAPIを使用して制御しなければならない。
STM32 MCUに関しては、STM32CubeMXというツールが提供されており、GUIを使用して直感的な操作でペリフェラルの初期化コードを自動生成することができる。これは初期化コードのみであるから、追加のコードを書き加えて、プログラムを完成させる。
STM32CubeMXの設定
まず、STM32CubeMXを立ち上げ、プロジェクトを設定する。以下で、ペリフェラルを選択し、ソースコード生成を行う。細かな操作方法については、他の記事を参照していただきたい。
Pinoutタブ
ここではTIM3を選択した。Lチカのために、タイマのPWM機能を使用する。同じ機能を持つなら他のタイマでも使用できる。
PeripheralsのTIM3の中から、Internal Clockをチェックし、Channel1にPWM Generation CH1を選択する。タイマにクロック信号を供給し、クロックのカウント数を設定してパルス幅を決める。
内容については後述する。
Clock Configurationタブ
クロック関係は、ここではデフォルトのままで設定する。タイマに供給されるクロックは、このMCUでは、APB1 Timer clocksに示されるクロックで、ここでは8MHzが設定されている。
Configurationタブ
TIM3ボタン→Parameter/Settingsタブを選択する。
レファレンスマニュアル(RM0091)に書かれているタイマの構成図を示す。
Pinoutタブで「Internal Clock」をチェックしているので、CK_PSCには、CK_INTが供給されるよう設定される。
CK_PSC信号は、PSC prescalerで分周される。クロックが8MHzなので、8MHz ÷ (7999 + 1) = 1KHz で、1KHzのクロック信号CK_CNTが、CNT counterに供給されるよう設定される。
CNT counterは、Upカウンタモードに設定されるので、0から始まり、Auto-reload registerに設定される値 999に一致するまでカウントアップする。auto-reload preloadをEnableに設定しているので、CNT counterの値は、999の次は0に戻る。
PWM Generation CH1の設定では、PWM Generation Channel 1のPulseに記述した値がCapture/Compare 1 registerに設定される。PWM mode 1では、CNT counterの値が、Capture/Compare 1 registerの値より小さいと、Channel 1がアクティブになり、CNT counterの値がCapture/Compare 1 registerの値以上になると、インアクティブになる。アクティブになるとCH Polarityの設定に従って、Highレベル信号がピンに出力される。従って、1KHzのクロック信号によって、CNT counterが0から199をカウントしている間はTIM3_CH1ピンがHighになり、200から999まではLowになる。
プログラミング
STM32CubeMXで、Generate Code を実行すると、ここまでの初期設定を行うCのソースコードが出力される。初期設定直後は、タイマが起動されていないので、起動するためのコードを追加する。
HAL_TIM_PWM_Start (&htim3, TIM_CHANNEL_1);
上記のコードでタイマを起動すると、停止するまでTIM3_CH1ピンにパルスを出力し続ける。
TIM3のチャネルでは、出力はCHnのみであるが、TIM1では、CHnとCHnNの2系統の出力がある。しかし、HAL_TIM_PWM_Start ()関数は、CHnへの出力の設定しかできない。CHnNを出力に選択した場合は、現時点では(STM32CubeMX バージョン4.24.0)、HALライブラリには対応APIが存在せず、CMSISのAPIに直接アクセスしなければならない。
次回
LEDの点灯時間をDMAを使って書き換え、CPUを介さず点滅間隔を変化させるサンプルを作成する。→STM32のタイマとDMAを組み合わせてLチカする