前の実験ではLEDが1秒ごとに点滅することでPICが正しく動作することを確認しました。ここでは、プログラムを設計する上で大変有効な、ステートマシンという考え方について説明します。 サンプルプログラムは、LEDの光らせ方を変えたものをステートマシンの考え方にのっとって作成してみました。
内部状態によって振る舞いが変化する仕組みをステートマシンといいます。たとえば、Aちゃんという子がいたとしましょう。Aちゃんは普段はどんな仕事を頼まれてもいやな顔をせず引き受けてテキパキとこなしますが、お昼近くになってお腹がすいてくると何を頼んでもやってくれません。お昼を食べて空腹が満たされると、また普段のAちゃんにもどりますが、定時のチャイムがなると仕事をやめて帰ってしまいます。このAちゃんは、内部状態によって振る舞いが変わるので、ステートマシンだといえます。ステートマシンの状態変化を表す図をステートチャート(状態遷移図)といいますが、このAちゃんの振る舞いをステートチャートであらわすと下図のようになるでしょう。
![]() |
| 図 Aちゃんの状態遷移 |
もう少し一般的なステートチャートを示すと、以下のようになります。
![]() |
| 図 一般的なステートチャート |
この例では、内部状態としてs1、s2、s3の3つの状態を持ち、状態が変化するきっかけとなるイベントは e1、e2 の2つがあります。この図では初期状態を表す●はありますが、最終状態がありません。これは、ロボットなどマイコンを積んだ処理系では一般に処理が終わったらもう動かないというのでは困るからで、電源が切られるまでは処理を続けるように設計するのが普通です。
ステートマシンの動作を検証する際には、ステートチャートよりも状態遷移表が便利です。
| s1 | s2 | s3 | |
| e1 | s2 | s3 | s3 |
| e2 | - | - | s2 |
状態遷移表を使うと、どの状態のときにどのイベントがおきたら次はどの状態に変化するかをもれなく検証することができます。また、新しい状態が加わったときや新しいイベントが加わったときにも、ステートチャートを修正するよりずっと楽に修正が可能で、モレやヌケを防ぐことができます。たとえば、上図のステートチャートでは状態s1のときにイベントe2が発生したらどのように振舞うべきかが記述されていませんが、状態遷移表をみると何もしないことが明記されています。全体的なイメージをつかみたいときはステートチャート、詳細な検討をするときには状態遷移表と使い分けるのが良いでしょう。
プログラムの設計にステートマシンを使うと、内部状態によって複雑な条件分岐を持つプログラムを見通しよく設計することができます。ステートマシンは、FPGAやCPLDなどの論理回路設計で多く用いられ、オブジェクト指向のデザインパターンでは state パターンとして広く知られています。
前回の実験に使用したソースコードに手を加えて、LEDの光が左右に行ったり来たりするプログラムを書いてみました。実は前回の実験のプログラムも、少しだけステートマシンっぽく作ってありましたが、今度のプログラムはもうちょっと工夫してあります。(ちょっとオブジェクト指向っぽく書いてみました。)
ソースコード ( pio_1a.c )
![]() |
![]() |
| LEDクラス | LEDクラスの状態遷移 |
△目次 / 4.5 基礎実験:ボタン操作によるLEDの点灯制御 >>