――せっかくコンパイルまで完了したのに、プログラムが思うように動きません……。どうやら晴子さんは、ガッカリする健一君の姿を予想していたようですね。さて、今回も晴子さんのペースにすっかり翻弄(ほんろう)されている健一君。彼のプログラムのどこがいけなかったのでしょうか?
SW1を押した回数を、7セグメントLEDに表示するプログラムを作ってね。ただし、カウンタの初期値は「0」よ。それと、「9」の次のカウントで最初の「0」に戻ること!
それでは、謎を解明していきましょう。まずは、先ほどの健一君のプログラム(ソースコード1)を逆フローしていきます(図2)。
健一君のプログラムでは、「SW1」が押されている間、7セグメントLEDに「8」が表示されます。図2が、そのフローチャートです。
「SW1」が押されているときの処理の流れを赤線で示しました。このように、「SW1」が押されている間、「0」から「9」までのカウントが繰り返されます。しかし、マイコンの処理速度というのは大変高速なので、7セグメントLEDには「0」から「9」までが高速表示され、結果的に「8」と表示されているように見えていたのです。
どうやら健一君は、「SW1が押されているときにカウント処理する」と考えたようですが、そこに誤りがあったのです!
それでは、スイッチが押された回数を数えるプログラムとは、どんな処理になるのでしょうか?
実はこの処理には、2つのとらえ方があります。
それは、
です。
分かりやすいように、タイミングチャートで示してみましょう(図3)。
健一君のプログラムの場合、図3のピンク色で示した時間に、カウントを繰り返し実行するようになっていました。前回の宿題(2)では、図3の赤色で示した①か②のいずれかの時点、つまり、「スイッチのON/OFFが、変化したときにカウントする」プログラムを作ればよいのです。
ここでは、図3①のスイッチ操作をとらえるものとして、フローチャートを作ってみました(図4)。
スイッチが押されていない間、図4①のループでスイッチが押されるのを待ちます。スイッチが押されたならば、カウント処理し、さらに図4②のループでスイッチが押されている間待機します。
これでプログラムはうまく動きますが、CPUの処理能力はほとんど入力待ちループに費やされることが分かります。
それでは、ここまでの解説を基にしたC言語のプログラムを確認してみましょう(ソースコード2)。
/* SW1が押された回数を表示する。 * */ #define PCR1 (*((volatile unsigned char *)0xffe4)) #define PDR1 (*((volatile unsigned char *)0xffd4)) #define PCR5 (*((volatile unsigned char *)0xffe8)) #define PDR5 (*((volatile unsigned char *)0xffd8)) #define PCR8 (*((volatile unsigned char *)0xffeb)) #define PDR8 (*((volatile unsigned char *)0xffdb)) #define SW1 0x01 #define SW2 0x02 #define SW3 0x04 int main(void) { unsigned char LED[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; int count; PCR1 = 0x0; PDR5 = 0xfe; PCR5 = 0x03; PDR8 = 0xff; PCR8 = 0xff; count = 0; PDR8 = LED[count]; for (;;) { while ((PDR1 & SW1) != 0);/* SW1が押されていないとき待機 */ if (count < 9) count++; else count = 0; PDR8 = LED[count]; while ((PDR1 & SW1) == 0);/* SW1が押されているとき待機 */ } return 0; }
ソースコード2 健一君のプログラムを修正 |
わー!! プログラムが動いた。
見て、見て、晴子さん!
ちゃんとカウント処理してる〜。
よかったわねー。
さすが、健一君。
うん? 晴子さん、何だか妙に優しいなー。
おっ! するどい!
じゃあ、もう少しだけスイッチを押してみて。
はい……。
えっ、何! いまの?
カウントが飛んだ!
※画像2を参照のこと。
そう、それが第2の“ワナ”よ。
いまのプログラムには、「チャタリング」の配慮がなされていないの。
分かる?
えっ、チャタリングって?
ってことは、まだプログラムは完成していないの?
あーあ。今日は早く帰ってゲームしたかったのに……。
まったく!
Copyright © ITmedia, Inc. All Rights Reserved.