「天文屋のためのマイコン入門」3モードをさらに発展
前回までのプログラムで3つのモードを扱うプログラムを完成させました。
モード0 LED消灯
モード1 LED点灯
モード2 LED点滅(1秒間隔)
このモードに意味を持たせれば、目的とするインターバルシャッターのプログラムに近づきます。次のように意味を持たせてみます。
モード0 LED消灯------------->停止中
モード1 LED点灯------------->インターバル中(露出と露出の間)
モード2 LED点滅------------->露出中
ただ、それぞれの状態遷移は単純ではありません。それを図示したのが以下です。
最初はモード0停止中です。ここでプッシュスイッチを押すとモード2露出中に移行します。設定時間経過すると、モード1インターバル中に移行します。そして3秒経過するとまた露出中に移行し、これを永遠に繰り返します。
モード1インターバル中、モード2露出中、いずれの場合もプッシュスイッチを押せば、モード0停止中に移行します。
これをプログラムにしてみましょう。また変更のあった部分のみ説明します。プログラムはの主要部分はすべて割込み処理の中にあります。割込み処理を前半、後半に分けて説明します。
まずは前半部分です。
赤枠の部分は、プッシュSWが押されたことを検出する部分です。これは前回とまったく同じです。
青枠の部分はプッシュSWが押された場合にモードを変化させる部分です。SWが押されなければ素通りされます。
青枠の中の緑枠の部分が、モード0停止中の時に、SWが押された場合で、モード2露出中に移行する準備をしています。MINUTEに露出時間をとりあえず1分に設定しています。それ以外のデータは0クリアして初期化しています。
黄色の枠の中は、モード1インターバル中またはモード2露出中にプッシュSWが押された場合で、LEDを消し、モード0へ移行しています。
次に後半部分です。
赤枠の部分は時間をカウントする部分です。前回より拡張しています。この部分でやっていることは、
1 TIME_COUNTをカウントし32になったら0に戻し、SECONDをインクリメントする
2 SECONDをカウントし、60になったら0に戻し、MINUTEをデクリメントする
ただし、プログラムではSECONDが10になった場合にMINUTEをデクリメントしています。ここは60が正解です。プログラムを早く動かした方がデバックしやすいので1分を10秒に設定しました。プログラムが完成したら60に戻します。
この割込み処理の後半部分ですが、81行目までは、1/32秒間隔のタイマー割込み処理のすべてで実行されます。82行目以降は、32回に一回しか実行されません。つまり1秒間隔でした実行されません。
もともと1/32秒間隔にしたのは、プッシュSWのチャタリングの影響を除去するためで、プッシュSWの処理はもう終わっているので、1秒ごとでよいのです。
さて、赤枠移行は各モードごとの処理です。
まずは緑枠のモード0停止中の場合ですが、これは何もしませんので、割込み処理の出口にジャンプします。
次に、紫枠モード1インターバル中の場合ですが、SECONDが3になったかどうか調べています。3ではなければ、そのまま何もしません。3になった場合はモード2露出中に移行しますので、CUR_MODE_0へジャンプします。CUR_MODE_0は割込み処理の前半部分にあります。モード0でスイッチが押された場合の処理とまったく同じなので、ここへジャンプさせています。
最後、青枠はモード2露出中の処理です。ここではMINUTEを調べて0かどうか判断します。0なら露出終了なので、モード1インターバル中に移行する準備をします。まだ露出中なら、黄色の枠の中、LEDを点滅させる処理をします。
説明はここまでです。
さて、もうほとんど完成に近いですね。あとは、MINUTEの初期化にロータリースイッチの値を読み込み、残り露出時間、つまりMINUTEの値を7セグメントLEDに表示する処理を加えるだけです。あ、あとシャッター信号もありますね。いずれにせよもう少しです。
| 固定リンク
コメント