今回はPWM(Pulse Width Modulation)出力をMbed OSのAPIを使って動作させてみたいと思います。前回、外部端子割り込みが使えるようになったので、外部端子割り込みでPWM出力を開始/停止する機能付きとしてみました。簡潔で分かり易いAPIのMbed OSです。サンプルプログラムの作成もお気楽。
※「モダンOSのお砂場」投稿順Indexはこちら
PWM出力制御のAPI
PWMを制御するMbed OSのAPIに関しては、以下のページに説明があります。
多数の半導体ベンダのこれまた多数のマイコン品種上で動作できるMbed OSが「仕切って」くれているので、マイコン品種毎の違いをほとんど気にせずにプログラムが書けてしまいます。今更ながら世界を覆うArm のお陰であります。
PWM出力端子の選定
流石にPWM出力機能がある端子を選ばないとなりません。作成したサンプルプログラムを走らせているのはST Microelectronics社のSTM32F401RE搭載 NUCLEO-F401REボードです。どの端子がPWM出力として使用できるのか、Mbed OSの以下のページの端子図で確認することができます。色分けされていて一目瞭然であります。
STM32マイコンの製品数は多いですが、互換性は高いので、NUCLEOボード搭載の品種であれば同端子がだいたい使用できるのではないかと思います。
なお、上記の端子図のPWM出力端子の横にはAPIが使用するタイマ番号とチャネル番号が書いてあります。複数の出力端子で同じタイマを共有する場合、相矛盾するタイマ設定はできないので、多数の出力を同時に使う場合は要注意かと思います。今回は、PWM出力2本を同時に使用していますが、異なるタイマなので矛盾など気にせず勝手に設定してます。
サンプルプログラムの作成
サンプルプログラムは、いつもお世話になっているMbedのWebコンパイラではなく、WindowsOS上で走っているVSCode+PlatformIOを使ってみています。PlatformIOはupload, debugにST-LINKをサポートしており、PCのUSBポートにNUCLEOボードを接続するだけで使えるようになります。とても楽。ただし毎度申し上げますが、初回コンパイルは全ソースをコンパイルするので長時間かかります。あっという間のWebコンパイラとは違いますです。
作製したサンプルソースが以下に。前回の外部端子割り込みのサンプルソースを流用し、それにPWM機能を追加した形です。機能はこんな感じ。
-
- PWM出力は2本。PB_3とPB_5の2端子を使用。us単位の制御API(他にもms単位、秒単位などある)を使って異なる周期とデューティのPWM波形を出力。
- B1_USERボタンの割り込みハンドラ内で、PWM出力のサスペンド、リジュームを制御。
- main()関数はユーザーボタン割り込みとPWMの初期化を行った後、我関せずLチカを続ける
ソース見る方が早いです、多分。
#include <mbed.h> #include <stdio.h> using namespace std::chrono_literals; // B1 USER pin for Nucleo-64-boards InterruptIn B1_USER(PC_13, PullUp); DigitalOut LD2(LED1); PwmOut pwmPB03(PB_3); PwmOut pwmPB05(PB_5); volatile bool pwmEnable = true; void b1UserHandler() { pwmEnable = !pwmEnable; if (pwmEnable) { pwmPB05.resume(); pwmPB03.resume(); } else { pwmPB05.suspend(); pwmPB03.suspend(); } } int main() { pwmEnable = true; B1_USER.fall(b1UserHandler); pwmPB05.period_us(10); pwmPB05.pulsewidth_us(3); pwmPB03.period_us(3); pwmPB03.pulsewidth_us(1); while(1) { LD2 = !LD2; ThisThread::sleep_for(1s); } }
ビルド&アップロードの様子
ビルドの最後の方とアップロードの様子が以下に。ビルドしたオブジェクトは36Kバイト程。NUCLEOのオンボードデバッガ、ST-LINK通じてアップロードされとります。
動作確認
冒頭のアイキャッチ画像では、PA_10とPB_3にAnalog Discovery2を接続してPWM波形を測定しているところを載せてしまいましたが、以下は、上記ソースどおりPB_5とPB_3にPWM出力しています。
黄色のC1がPB_5端子で、青色のC2がPB_3端子です。右側に周波数とデューティ比の計測結果が表示されています。PB_5は周期10us、ハイ期間3us、PB_3は周期3us、ハイ期間1usに設定しています。ほぼほぼ設定どおりの値でPWM出力出ているように見えます。
そして B1_USERボタンを押してみます。その瞬間、PWM波形は止まり C1/C2ともLOW出力となりました。続いてもう一度B1_USERボタンを押してみます。PWM波形復活。ま、割り込みでの制御も予定通り動作ということで。今回は完了。