ブレッドボードラジオAVRマイコン入門

BASCOM-AVR LCDの表示(その7)

 LCD・液晶ディスプレイでの数字のカウントを入力スイッチで操作するプログラムを実験しました。どれも簡単な動作なんですが、なかなか思うように動きません。マイコン回路は「LCD表示テスト用回路」を使用します。入力スイッチはPB0〜GND間につないであります。

1. スイッチを押している間だけカウントが止まる

 LCD画面では「Count 0」から順に数を数えています。押しボタンスイッチを押している間だけカウントアップが止まり、その時点でのカウント数を表示します。押していたスイッチを放すと、その数字から再びカウントアップを始めます。

 第1図

 プログラムファイル lcd7a.bas

1 $regfile = "at26def.dat" ATtiny26Lを使用する。
2 $crystal = 1000000 クロック周波数を1MHzに設定。
3 Config Lcdpin=Pin, Db4=Porta.4, Db5=Porta.5 LCDのピン接続の設定。DB4=PA4, DB5=PA5。
4 Config Lcdpin=Pin, Db6=Porta.6, Db7=Porta.7 LCDのピン接続の設定。DB6=PA6, DB7=PA7。
5 Config Lcdpin=Pin, E=Porta.3, Rs=Porta.2 LCDのピン接続の設定。E=PA3, RST=PA2。
6 Config Lcd = 16 * 2 16文字×2行表示のLCDを使用する。。
7 Config Portb = Input ポートBを入力に設定する。
8 Portb = 1 PB0をプルアップする。
9 Dim N As Byte バイト型変数「N」を使用する。
10 Cursor Off カーソルを表示しない。
11 Cls LCDの表示を消去する。
12 Do Doループの範囲ここから。
13  If Pinb.0 = 1 Then 条件分岐。「Pinb.0 = 1」ならば、
14  Cls LCDの表示を消去する。
15  Lcd "Count " ; N LCD画面に「Count 」と「N」の値を表示する。
16  Wait 1 1秒間そのまま。
17  Incr N 変数「N」に「1」を加える。
18  End If 条件分岐のプログラムここまで。
19 Loop Doループの範囲ここまで。12行目へ戻る。
20 End 終わり。

 1秒間に1ずつカウントアップするプログラムに条件分岐が加わった形です。13行目「If Pinb.0 = 1 Then」は「Pinb.0 = 1」ならばカウントを続けるという意味です。つまり押しボタンスイッチが押されていなければ普通にカウントが進みます。

 スイッチが押されたらどうするかはプログラムでは何も指定していません。こういう場合は「何もしない」、つまりプログラムの進行がそこでストップして、そこまで数えた数がそのまま表示されます。スイッチが押されている間じゅうそのままの状態です。押していたスイッチを放すと「Pinb.0 = 1」に戻るので、表示されている数字からカウントが再開されます。

2. スイッチを押すとカウントをやめる

 スイッチをチョンと押すとカウントをやめて、その時点でのカウント数を表示します。下の行には「Stop」の文字が表示されます。リセットスイッチを押すと0に戻ってカウントを再開します。

 第2図

 プログラムファイル lcd7b.bas

1 $regfile = "at26def.dat" ATtiny26Lを使用する。
2 $crystal = 1000000 クロック周波数を1MHzに設定。
3 Config Lcdpin=Pin, Db4=Porta.4, Db5=Porta.5 LCDのピン接続の設定。DB4=PA4, DB5=PA5。
4 Config Lcdpin=Pin, Db6=Porta.6, Db7=Porta.7 LCDのピン接続の設定。DB6=PA6, DB7=PA7。
5 Config Lcdpin=Pin, E=Porta.3, Rs=Porta.2 LCDのピン接続の設定。E=PA3, RST=PA2。
6 Config Lcd = 16 * 2 16文字×2行表示のLCDを使用する。。
7 Config Portb = Input ポートBを入力に設定する。
8 Portb = 1 PB0をプルアップする。
9 Dim N As Byte バイト型変数「N」を使用する。
10 Cursor Off カーソルを表示しない。
11 Cls LCDの表示を消去する。
12 Do Doループの範囲ここから。
13  If Pinb.0 = 0 Then 条件分岐。「Pinb.0 = 0」ならば、
14  Lowerline : Lcd "Stop" 下の行に「Stop」と表示する。
15  Exit Do Doループを抜けて22行目へ。
16  End If 条件分岐のプログラムここまで。
17  Cls LCDの表示を消去する。
18  Lcd "Count " ; N LCD画面に「Count 」と「N」の値を表示する。
19  Waitms 100 0.1秒間そのまま。
20  Incr N 変数「N」に「1」を加える。
21 Loop Doループの範囲ここまで。12行目へ戻る。
22 End 終わり。

 13行目「If Pinb.0 = 0 Then」は条件分岐です。もし「Pinb.0 = 0」すなわちスイッチが押されていれば14行目「Lowerline : Lcd "Stop"」でLCDの下の行に「Stop」の文字を表示し、15行目「Exit Do」でループを抜けてプログラムが終了します。スイッチが押された時点で表示されていたカウント数字はそのままです。リセットスイッチを押すとカウントは再開しますが、数字は0に戻ります。

 このプログラムでは、スイッチを押してもカウントが止まるまで「Wait」命令の時間だけ待たされます。しかもその間にカウントが「1」進みます。そのためカウントアップの間隔を0.1秒と短くして欠点をごまかしています。

 スイッチをチョンと押すとカウントがストップ、もう1回チョンと押すとカウント再開、という動作にできればストップウォッチのように使えて便利ですが、そういうプログラムはまだ実現できていません。「入力スイッチ(その3)」の「7.スイッチを押すとLEDが点滅、もう1回押すと点滅止まる」のような形にすればそれらしい動作にはなるのですが、やはり上記と同じ欠点は残ります。

3. スイッチを押すたびにカウントが増える

 スイッチを1回チョンと押すたびにカウント数が「1」ずつ増えていくプログラムです。「Debounce」命令を使います。

 第3図

 プログラムファイル lcd7c.bas

1 $regfile = "at26def.dat" ATtiny26Lを使用する。
2 $crystal = 1000000 クロック周波数を1MHzに設定。
3 Config Lcdpin=Pin, Db4=Porta.4, Db5=Porta.5 LCDのピン接続の設定。DB4=PA4, DB5=PA5。
4 Config Lcdpin=Pin, Db6=Porta.6, Db7=Porta.7 LCDのピン接続の設定。DB6=PA6, DB7=PA7。
5 Config Lcdpin=Pin, E=Porta.3, Rs=Porta.2 LCDのピン接続の設定。E=PA3, RST=PA2。
6 Config Lcd = 16 * 2 16文字×2行表示のLCDを使用する。。
7 Config Portb = Input ポートBを入力に設定する。
8 Portb = 1 PB0をプルアップする。
9 Declare Sub Switch サブルーチン「Switch」を使用する。
10 Dim N As Byte バイト型変数「N」を使用する。
11 Cursor Off カーソルを表示しない。
12 Cls LCDの表示を消去する。
13 Lcd "Count 0" LCDに「Count 0」と表示する。
14 Do Doループの範囲ここから。
15  Debounce Pinb.0, 0, Switch, Sub 「Pinb.0 = 0」ならサブルーチン「Switch」を実行。
16 Loop Doループの範囲ここまで。14行目へ戻る。
17 End メインプログラム終わり。
18 Sub Switch サブルーチン「Switch」ここから。
19  Cls LCDの表示を消去する。
20  Incr N 変数「N」に「1」を加える。
21  Lcd "Count " ; N LCD画面に「Count 」と「N」の値を表示する。
22 End Sub サブルーチン「Switch」ここまで。

 メインプログラム(14〜16行目)ではスイッチの状態を調べる仕事だけをしています。「Pinb.0 = 0」すなわちスイッチが押されたと判断すれば、サブルーチン「Switch」へ飛んで、カウントアップとLCDへの表示を実行します。