前回に引き続いて、最大99分50秒の時間を設定できるキッチンタイマを設計・製作します。マイコンボードは、テキサス・インスツルメンツ(TI)のMSP430™ LaunchPadバリュー・ライン開発キットを使用します。
ダイナミック点灯と1秒カウントダウンを同時に行う
前回、4桁の7セグメントLEDをダイナミック点灯するための回路とソフトウェアを作成しました。前回のソフトウェアは、常に同じ数値「3210」を表示し続けるというものでした。今回は、この数値を1秒ごとにカウントダウンする部分を作ってみましょう。前回のプログラムにちょっと手を加えるだけで実現できます。
1秒ごとのカウントダウンは、タイマ割り込みを利用するのが簡単です。ダイナミック点灯では、MSP430の内蔵発振器(DCO)を用いて比較的高精度(許容差±3%)の16MHzクロックを生成し、それを使用して4msごとに割り込みを発生しています。この割り込みを250回カウントすれば、1秒ごとのタイミングが得られます。
そこで、プログラムでは#defineを使用して、1秒生成用の定数INT1SECを250と定義しておきます(図1の①)。なお、開発段階では、この250を例えば25に変更すれば、高速にカウントダウンされるので、デバッグ時間を短縮できます。
また、プログラムで必要となるグローバル変数をいくつか追加します。一般的なC言語ではグローバル変数の使用は推奨されませんが、CPUの省電力モードを活用してタイマ割り込みで間欠的に動作するシステムでは、グローバル変数を用いて、CPUがスリープしている間も変数を主記憶に記憶しておく方が便利です。
まず、動作モードを保持するために、変数modeを用意します(図1の②)。今回のテストではなくてもいいのですが、キッチンタイマのシステムには必要になるので、ここで入れておきます。今回は、アイドルモード(mode = 0)と、カウントダウンモード(mode = 1)の2つの動作モードしか使いません。
また、残り秒数を保持するために、変数secを用意します(図1の③)。キッチンタイマの要求仕様は最大99分59秒なので、それを秒数に換算すると最大5999秒となります。ここでは、仮の初期値として6000を入れてあります。
なお、ダイナミック点灯に便利なように、分分秒秒の4桁のデータを配列data[]として保持しています。変数secと配列dataは相互に換算可能で、どちらか1つにまとめることもできます。メモリ容量が厳しくなってきたら削減を検討すべきでしょう。
さらに、4ms割り込みの回数をカウントするための変数nを用意します(図1の④)。
プログラムの部分は、割り込みサービス関数を読みやすくするために、1桁分の表示関数disp()(図1の⑤)と、秒数secから4桁表示値data[]への変換関数sec2data()(図1の⑥)を独立の関数として作っています。
メイン関数main()の変更はほとんどありません。
このシステムでは、1秒ごとにカウントダウンするカウントダウンモードと、1秒ごとにカウントダウンしない(表示値が変化しない)アイドルモードの2つのモードを用いて動作の切り替えを行います。このプログラムはテスト段階なので、メイン関数で変数modeに1を代入して、強制的にカウントダウンモードに切り替えています(図2の⑦)。
割り込みサービス関数Timer0_A ()は、タイマ割り込みによって4msごとに呼び出されて、ダイナミック点灯の動作を実行します。今回は、1桁分の表示関数disp()(図1の⑤)を別に作ったので、ここでは関数disp()を呼び出しています(図2の⑧)。処理の内容は前回と同じです。
今回のプログラムで新たに追加したのは、1秒の判定とカウントダウンの部分です(図2の⑨)。タイマ割り込みの回数が250回になったら、1秒分のカウントダウンを行います。
回数を数える変数nは、初期値が0で、タイマ割り込みごとに1ずつ加算(++n)していきます。そして、nの値が249(INT1SEC - 1)になったら、nを0に戻して、1秒カウントダウンを実行します(図2の⑩)。なお、数え終わりの値を250ではなくて249にしているのは、数え始めが0だからです。
もう1つ、++nという書き方について説明しておきます。
C言語では1ずつ加算するのにn++という表現(後置演算)をよく使います。ただし、n++を使うと、nの値を先に調べてからその後で1を加算するので、自分がやりたいことと実際のnの値が1だけずれてしまうことがあります。そこで、ここでは++nという表現(前置演算)を使っています。++nを使うと、先に1を加算してからnの値を調べるので、nを加算していって249になったタイミングを正しく検出できます。
タイマ割り込みの250回ごとに、もしカウントダウンモードであれば(mode == 1)、残り秒数secを1だけ減らします(図2の⑪)。そして、残り秒数secが0になったら、カウントダウンモードを終了してアイドルモード(mode = 0)に移行します。残り秒数が負の数になってしまうことはありません(図2の⑫)。
ここでも、secを減算するのに後置演算(sec--)ではなく、前置演算(--sec)を使っています。後置演算だと、secが0になった後にさらに1を減算して、secの値が-1になってしまうからです。
1秒カウントダウンしたら、秒数secから4桁表示値data[]への変換関数sec2data()(図1の⑥)を使って、配列data[]の値を更新します(図2の⑬)。これによって、その4ms後のタイマ割り込みから、更新された4桁の値が7セグメントLEDに表示されます。
ダイナミック点灯回路
図3に回路図を示します。今回のシステムではDPは表示しないので、セグメントデータ用としてP1.7〜P1.1の7ビットを割り当てています。また、桁選択用としてP2.3〜P2.0の4ビットを割り当てています。アノードコモンのLEDを使用しているので、桁選択信号をHighにして、セグメントデータ信号をLowにすれば該当するLEDが点灯します。
■MSP430 超低消費電力マイコン・ファミリ
■TIのマイコン製品
■MSP430 LaunchPadバリュー・ライン開発キット
■TIのツールの購入はこちらから:TI eStore
※MSP430はTexas Instruments Incorporatedの商標です。その他すべての商標および登録商標はそれぞれの所有者に帰属します。
提供:日本テキサス・インスツルメンツ株式会社
アイティメディア営業企画/制作:EDN Japan 編集部/掲載内容有効期限:2015年3月31日
Copyright © ITmedia, Inc. All Rights Reserved.