Previous: 1.1. OSを使用する理由 |
Up: 1.1. OSを使用する理由 |
Next: 1.1.2. 単純なループ処理の問題点 |
これまで各周辺回路の利用例をみてきました。一つのサンプルプログラムでは、だいたい一つ、多くても2?3種の周辺回路を利用していました。もっともSTM32は、一つのチップに、数多くのIOを多様な周辺回路を内蔵しています。これらのIOや周辺回路を同時に使いこなしてこそ、STM32を使用した意味があるとも言えます。そこで複数のIOと周辺回路を使用する例を考えてみましょう。ここでは複数のIOを利用する例として、STM32を利用したマウスロボットの仕様を考えてみることにします。
モータを2個内蔵し、左右のタイヤを独立して制御することにより、直進、回転、後進が行えるようにします。万が一モータがロックしたときには、モータやFETが焼けないように、電流検出用抵抗を利用して過電流を検出し、モータへの電力供給を停止できるようにします。PSDセンサにより、前方に障害物が迫ってきた場合には、随時停止し、方向転換が行えるようにします。機体底面の四隅に床に向けて反射型フォトインタラプタを設置し、机や床のヘリまで来たときには、すぐに停止できるようにします。走行方向やスピードはマイコンが自律的に判断して決定しますが、Zigbee無線により遠隔操作ができるようにします。自律動作をさせるか、無線操縦かは、本体に設置したボタン(セレクトボタンとキャンセルボタン)を操作しながら決定します。操作の状況や設定の内容は、本体に設置したI2C液晶に表示させます。離れているときは液晶を見ることができないので、高輝度のLEDを光らせて、動作状況がわかるようにします。LEDはフルカラーLEDを使用して、色や点滅パターンで、どういった状況なのかがわかるようにします。
これらの機能を周辺回路毎に分けてみましょう。ざっくりと分けると以下のようになります。
・GPIO フォトインタラプタ・ボタン(セレクト・キャンセル・パニック)
・タイマ(PWM) モータ・フルカラーLED
・ADC PSDセンサ
・USART Xbeeモジュール
・SPI ADC(電流検出抵抗用)
・I2C シリアル液晶モジュール
今回の仕様のマウスロボットを実現しようと思うと、これらの周辺回路をすべて制御できる必要があります。もっともCPUは一度に複数の周辺回路の操作を行うことはできません。そこで各周辺回路を順番に操作することになります。操作対象となる周辺回路を高速に切り替えれば、同時に制御しているように見えるはずです。このようなプログラムはどうやって構成すればよいのでしょうか。
単純な方法は、各周辺回路を1回だけ操作する関数を用意し、順番に実行するという方法です。たとえば、フォトインタラプタの状態を1回確認する以下のようなGetEdge関数を用意します。データはグローバル変数に格納することとしています。
void GetEdge (void) { ? PhotoInterrupterStatus = GPIO_ReadInputDataBit(PI_PORT, PI_PIN); } |
その他の周辺回路についても、同様に関数を用意します。
・ボタンの状態を1回だけ確認するGetButtonStatus関数
・モータ用タイマのPWMデューティー比を1回設定するSetMotorSpeed関数
・LED用タイマのPWMデューティー比を1回設定するSetLEDColor関数
・PSDセンサの出力をADCで1回取得するGetPSDDistance関数
・USARTからのデータを取得するGetUSARTData関数
・電流検出用抵抗の電圧値を取得するGetMotorCurrent関数
・I2C液晶にデータを送信するSetLCDData関数
・動作を判断するルーチンを実装したRobotControl関数
そして以下のように各関数を繰り返し実行します。
while(1) { ? GetEdge(); ? GetButtonStatus(); ? SetMotorSpeed(); ? SetLEDColor(); ? GetPSDDistance(); ? GetUSARTData(); ? GetMotorCurrent(); ? SetLCDData(); ? RobotControl(); } |
これで各周辺回路を並行して動作させられるようになりました。
Previous: 1.1. OSを使用する理由 |
Up: 1.1. OSを使用する理由 |
Next: 1.1.2. 単純なループ処理の問題点 |