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

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

 数をカウントしてLCD・液晶ディスプレイの画面に表示するプログラムの実験をしました。マイコン回路は「LCD表示テスト用回路」を使用します。

1. 0から255までカウントする

 最初に「Count 0」と表示され、数字の部分が1秒毎に「1, 2, 3, ・・・」と1ずつ増えていくプログラムです。バイト型の変数を用いたので最大カウント数は255です。255の次は0に戻って再び最初からカウントします。

 第1図

 プログラムファイル lcd5a.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 Dim N As Byte バイト型変数「N」を使用する。
8 Cursor Off カーソルを表示しない。
9 Do Doループの範囲ここから。
10  Cls LCDの表示を消去する。
11  Lcd "Count " ; N LCD画面に「Count 」と表示、
続いて変数「N」の値を表示する。
12  Wait 1 1秒間そのまま。
13  Incr N 変数「N」に1を加える。
14 Loop Doループの範囲ここまで。9行目へ戻る。
15 End 終わり。

 11行目の「"Count "」は語尾にスペースが1個入っています。これは数字との間を少し空けるためです。変数「N」の初期値は何も書かなければ「0」になります。Do〜Loopの間に「Wait 1」と「Incr N」があるので、「N」の値は1秒間に1ずつ増加します。

2. 「000」の形で表示する

 上記のプログラムでは数字の桁が増えるたび、表示は右へずれていきます。ここでは表示を「000」という形式にそろえるプログラムを試してみました。カウント用の数値変数「N1」のほかに表示用の文字変数「N2」が必要です。

 第2図

 プログラムファイル lcd5b.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 Dim N1 As Byte バイト型変数「N1」を使用する。
8 Dim N2 As String * 3 3文字の変数「N2」を使用する。
9 Cursor Off カーソルを表示しない。
10 Do Doループの範囲ここから。
11  Cls LCDの表示を消去する。
12  N2 = Str(n1) 「N1」の値を文字に変換して「N2」に代入する。
13  N2 = Format(n2, "000") 「N2」の表示形式を「000」にする。
14  Lcd "Count " ; N2 LCD画面に「Count 」と表示、
続いて変数「N2」の値を表示する。
15  Wait 1 1秒間そのまま。
16  Incr N1 変数「N1」に1を加える。
17 Loop Doループの範囲ここまで。10行目へ戻る。
18 End 終わり。

 12行目「N2 = Str(n1)」は数値変数である「N1」の値を文字に変え、それを文字変数「N2」の値にするという命令です。続いて13行目「N2 = Format(n2, "000")」で文字変数「N2」の値を「000」という形式にそろえます。つまり「N2」の値が「1」なら「001」に、「10」なら「010」になります。これをLCD画面に表示します。文字変数は計算(「Incr N」など)ができませんので、カウント用の変数とは別にする必要があります。

 カウント数が1桁や2桁のとき、先頭の「0」を表示しないようにしたい場合は、13行目を「N2 = Format(n2, " 0")」と書きます。「" 0"」は「0」の前に半角のスペースが2個入っています (ご覧のパソコンでそのように表示されているかどうかわかりませんが)。

 先の「lcd5a.bas」のように表示形式について何も指定しないとき、および「N2 = Format(n2, "000")」と書いたとき、さらに「N2 = Format(n2, " 0")」と書いたときの、それぞれの表示の違いを下記に示します。

 第3図

3. 時計のような表示にする

 カウント数を時計のように「分, 秒」で表示します。「00m00s」という形式になります。秒(s)の単位が60になると分(m)の単位の数が1増え、秒数は「00」に戻ります。

 第4図

 プログラムファイル lcd5c.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 Dim S1 As Byte 秒カウント用変数「S1」を使用する。
8 Dim M1 As Byte 分カウント用変数「M1」を使用する。
9 Dim S2 As String * 2 秒表示用変数「S2」を使用する。
10 Dim M2 As String * 2 分表示用変数「M2」を使用する。
11 Cursor Off カーソルを表示しない。
12 Do Doループの範囲ここから。
13 Cls LCDの表示を消去する。
14 If S1 = 60 Then 条件分岐のプログラムここから。
「S1」が「60」になったら15, 16行目へ。
15  S1 = 0 「S1」を「0」にする。
16  Incr M1 「M1」に1を加える。
17 End If 条件分岐のプログラムここまで。
18 S2 = Str(s1) 「S1」の値を文字に変換して「S2」に代入する。
19 S2 = Format(s2, "00") 「S2」の表示形式を「00」にする。
20 M2 = Str(m1) 「M1」の値を文字に変換して「M2」に代入する。
21 M2 = Format(m2, "00") 「M2」の表示形式を「00」にする。
22 Lcd "Time " ; M2 ; "m" LCDに「Time 」と表示、
続いて変数「M2」と文字「m」を表示する。
23 Lcd S2 ; "s" LCDに変数「S2」と文字「s」を表示する。
24 Wait 1 1秒間そのまま。
25 Incr S1 変数「S1」に1を加える。
26 Loop Doループの範囲ここまで。12行目へ戻る。
27 End 終わり。

 14行目「If S1 = 60 Then」は条件分岐の構文です。秒数のカウント「S1」が「60」になったら、まず15行目「S1 = 0」で秒数を「0」に戻し、16行目「Incr M1」で分のカウント「M1」を「1」進めます。18〜22行目はさっきのプログラムに出てきた表示の桁揃えです。分, 秒ともに「00」の形にしてLCDに表示します。

 このプログラムは時計のような表示をしますが、時間はあまり正確ではありません。実測すると1分あたり1秒くらいの遅れがあり、しかも測るたびに少しずつ違います。この原因は2つ考えられます。ひとつは、時間を測る基準になるクロック周波数の精度が悪いことです。IC内部の発振回路は電源電圧や周囲の温度によって周波数が変動します。もうひとつは、Doループ内の「Wait 1」以外の命令の実行に時間がかかり、結果的にDoループを1巡するのに1秒以上かかってしまうことです。ループ1回分の誤差はわずかでも、60回分(1分間)積算されるとけっこうずれてしまうと思います。

4. 出力端子の状態を表示する

 「Lcd Porta.0」と書くと、PA0の状態を「1」または「0」で表示することができます。LED点滅プログラムを例に取ると、「Set Porta.0」のとき「1」、「Reset Porta.0」のとき「0」が表示されます。LCDの表示だけなら実際にLEDを接続しなくてもOKです。

 第5図

 プログラムファイル lcd5d.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 Cursor Off カーソルを表示しない。
8 Do Doループの範囲ここから。
9 Set Porta.0 PA0の出力を「1」にする。
10 Cls LCDの表示を消去する。
11 Lcd "Porta.0=" ; Porta.0 LCDに「Porta.0=」と表示、
続いてPA0の状態(「1」)を表示する。
12 Wait 1 1秒間そのまま。
13 Reset Porta.0 PA0の出力を「0」にする。
14 Cls LCDの表示を消去する。
15 Lcd "Porta.0=" ; Porta.0 LCDに「Porta.0=」と表示、
続いてPA0の状態(「0」)を表示する。
16 Wait 1 1秒間そのまま。
17 Loop Doループの範囲ここまで。8行目へ戻る。
18 End 終わり。