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

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

 LCD・液晶ディスプレイの上の行で数をカウントすると同時に、下の行でカウント数をバー表示するプログラムの実験をしました。マイコン回路は「LCD表示テスト用回路」を使用します。

1. 1桁単位でバー表示する

 最初はいちばん簡単なパターンでやってみました。上の行で「Count 0」から「Count 16」までカウントします。下の行では、数字に応じて1桁分ずつバーが延びていきます。16を超えると0に戻ります。下の図のような感じです。バー表示用に右のような文字を作りました。

 第1図

 プログラムファイル lcd6a.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 Declare Sub Bargraph サブルーチン「Bargraph」を使用する。
8 Dim N As Byte バイト型変数「N」を使用する。
9 Deflcdchar 0, 32, 32, 31, 31, 31, 31, 32, 32 バー表示用「Chr(0)」の文字データ。
10 Cursor Off カーソルを表示しない。
11 Cls LCDの表示を消去する。
12 Do Doループの範囲ここから。
13  For N = 0 To 16 Forループの範囲ここから。17回繰り返し。
14  Lcd "Count " ; N LCD画面に「Count 」と「N」の値を表示する。
15  Call Bargraph サブルーチン「Bargraph」を実行。
16  Wait 1 1秒間そのまま。
17  Cls LCDの表示を消去する。
18  Next N Forループの範囲ここまで。13行目へ戻る。
19 Loop Doループの範囲ここまで。12行目へ戻る。
20 End メインプログラム終わり。
21 Sub Bargraph サブルーチン「Bargraph」ここから。
22  Local Bar As Byte サブルーチン内で変数「Bar」を使用する。
23  Lowerline LCDの下の行に表示する。
24  For Bar = 1 To N Forループここから。1から「N」まで繰り返し。
25  Lcd Chr(0) LCD画面に「Chr(0) 」を表示する。
26  Next Bar Forループここまで。24行目へ戻る。
27 End Sub サブルーチン「Bargraph」ここまで。

 12行目「Do」から19行目「Loop」までがメインプログラムです。ここで0〜16をカウントしてLCDの上の行に表示します。21行目「Sub Bargraph」から27行目「End Sub」までが「Bargraph」(バーグラフ)という名前のサブルーチンです。ここではLCDの下の行にバーグラフを表示する仕事をします。メインプログラムで数字がひとつ増えるごとにサブルーチンが1回呼び出されます。

 メインプログラムのForループ1回目は「N = 0」です。LCDに「Count 0」と表示してからサブルーチンへ飛びますが、24行目に「N = 0」を代入すると「For Bar = 1 To 0」となってしまいます。つまり「N = 0」のときはサブルーチンでは何もしません。したがって「Count 0」のときは下の行にバーは表示されません。

 Forループ2回目「N = 1」のとき、上の行の表示は「Count 1」に変わります。サブルーチンのForループは「For Bar = 1 To 1」となり、ループが1回だけ回ります。下の行にはバー(「Chr(0)」)が1個だけ表示されます。「N = 2」のときは「For Bar = 1 To 2」ですからループ回数は2回になり、バーは2個表示されます。こうして、変数「N」が増えるにつれて、下の行には「N」と同じ数のバーが並びます。

 メインプログラムのForループ17回目で「Count 16」が表示されると、プログラムは「Do〜Loop」で元へ戻り、再び「N = 0」としてForループを繰り返します。

 バーグラフの表示は「N」が増えるたびにその都度すべて消されて新たに左端からN個書き込まれます。最初、23行目「Lowerline」をForループの中に入れたら、バーグラフがいつまでたっても「1」のままでした。「Lowerline」という命令は「下の行の1文字目から、今ある表示を消して上書きする」という意味なのでした。「Locate 2, 1」も同じです。

2. 目盛付のバーグラフ

 バーグラフに4桁毎に目盛(タテ線)を入れます。「Select Case (変数) 〜 End Select」という構文を用います。こういうプログラムを何と言うのかわかりませんが、ここではとりあえず「変数値選択」とよぶことにします。

 第2図

 プログラムファイル lcd6b.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 Declare Sub Bargraph サブルーチン「Bargraph」を使用する。
8 Dim N As Byte バイト型変数「N」を使用する。
9 Deflcdchar 0, 32, 16, 16, 16, 16, 16, 16, 32 バー表示用「Chr(0)」の文字データ。
10 Deflcdchar 1, 32, 16, 31, 31, 31, 31, 16, 32 バー表示用「Chr(1)」の文字データ。
11 Deflcdchar 2, 32, 32, 31, 31, 31, 31, 32, 32 バー表示用「Chr(2)」の文字データ。
12 Deflcdchar 3, 32, 1, 31, 31, 31, 31, 1, 32 バー表示用「Chr(3)」の文字データ。
13 Deflcdchar 4, 32, 1, 1, 1, 1, 1, 1, 32 バー表示用「Chr(4)」の文字データ。
14 Cursor Off カーソルを表示しない。
15 Cls LCDの表示を消去する。
16 Do Doループの範囲ここから。
17  For N = 0 To 16 Forループの範囲ここから。17回繰り返し。
18  Lcd "Count " ; N LCD画面に「Count 」と「N」の値を表示する。
19  Call Bargraph サブルーチン「Bargraph」を実行。
20  Wait 1 1秒間そのまま。
21  Cls LCDの表示を消去する。
22  Next N Forループの範囲ここまで。17行目へ戻る。
23 Loop Doループの範囲ここまで。16行目へ戻る。
24 End メインプログラム終わり。
25 Sub Bargraph サブルーチン「Bargraph」ここから。
26 Local Bar As Byte サブルーチン内で変数「Bar」を使用する。
27 Lowerline LCDの下の行に表示する。
28 For Bar = 1 To N Forループここから。1から「N」まで繰り返し。
バーグラフと目盛を表示するプログラム。
29  Select Case Bar 「変数値選択」のプログラムここから。
「Bar」の値に応じて下記のプログラムを実行。
30  Case 1 : Lcd Chr(1) 「Bar = 1」なら「Chr(1) 」を表示する。
31  Case 4 : Lcd Chr(3) 「Bar = 4」なら「Chr(3) 」を表示する。
32  Case 8 : Lcd Chr(3) 「Bar = 8」なら「Chr(3) 」を表示する。
33  Case 12 : Lcd Chr(3) 「Bar = 12」なら「Chr(3) 」を表示する。
34  Case 16 : Lcd Chr(3) 「Bar = 16」なら「Chr(3) 」を表示する。
35  Case Else : Lcd Chr(2) 「Bar」が上記以外なら「Chr(2) 」を表示する。
36  End Select 「変数値選択」のプログラムここまで。
37 Next Bar Forループここまで。28行目へ戻る。
38 For Bar = N To 15 Forループここから。「N」から15まで繰り返し。
バーのない所に目盛だけ表示するプログラム。
39  Select Case Bar 「変数値選択」のプログラムここから。
「Bar」の値に応じて下記のプログラムを実行。
40  Case 0 : Lcd Chr(0) 「Bar = 0」なら「Chr(0) 」を表示する。
41  Case 3 : Lcd Chr(4) 「Bar = 3」なら「Chr(4) 」を表示する。
42  Case 7 : Lcd Chr(4) 「Bar = 7」なら「Chr(4) 」を表示する。
43  Case 11 : Lcd Chr(4) 「Bar = 11」なら「Chr(4) 」を表示する。
44  Case 15 : Lcd Chr(4) 「Bar = 15」なら「Chr(4) 」を表示する。
45  Case Else : Lcd Chr(&Hfe) 「Bar」が上記以外ならスペースを表示する。
46  End Select 「変数値選択」のプログラムここまで。
47 Next Bar Forループここまで。38行目へ戻る。
48 End Sub サブルーチン「Bargraph」ここまで。

 見るからに面倒くさそうなプログラムです。もっとスマートなやり方があるのかもしれませんが、現時点ではわかりません。

 メインプログラムは前と同じです。サブルーチン内の29行目「Select Case Bar」から36行目「End Select」までが「変数値選択」のプログラムです。「条件分岐」の条件がたくさんあるヤツ、と考えてください。変数「Bar」の値によって実行するプログラムが細かく分かれます。例えば30行目「Case 1 : Lcd Chr(1)」は、変数「Bar」の値が「1」ならLCDに「Chr(1)」を表示するという意味になります。35行目「Case Else : Lcd Chr(2)」は、変数「Bar」の値が上で指定した値以外のときはLCDに「Chr(2)」を表示するという意味です。

 39行目から46行目にも同じく「変数値選択」の構文が出てきます。2つの「変数値選択」プログラムはそれぞれがForループの中に入っています。28行目からの最初のForループはバーグラフを表示するためのプログラムです。ただし4桁毎に目盛付のバーを書き込みます。38行目からの2つめのForループは、バーグラフのない所に目盛線だけを書き込むプログラムです。

 「N = 0」のときは最初のForループは素通りします。2番目のForループは「For Bar = 0 To 15」になりますので、ローカル変数「Bar」に0から15を順に代入して16回繰り返します。「Bar = 0」のときは40行目「Case 0 : Lcd Chr(0)」によって下の行の1桁目に「Chr(0)」つまりタテの目盛線を表示します。「Bar = 1」のときは45行目の条件「Case Else : Lcd Chr(&Hfe)」にあたりますので、2桁目にスペースが表示されます (見えませんが)。このようにして「Bar」が3, 7, 11, 15のときには目盛線、それ以外の値の時にはスペースが表示されます。これが上の図の一番上、「Count 0」の画面になります。

 「N = 1」になると最初のForループも1回だけ回ります。「Bar = 1」のときは30行目「Case 1 : Lcd Chr(1)」によって1桁目に「Chr(1)」(目盛線付きのバー)が表示されます。このあと2番目のForループに移り、2桁目以降に目盛線とスペースを表示します (上図「Count 1」の画面)。「N = 2」のときは最初のForループで1桁目に「Chr(1)」(目盛線付きのバー)、2桁目に「Chr(2)」(目盛線のないバー)が表示され、3桁目以降は2番目のForループによって目盛線とスペースが書き込まれます (上図「Count 2」の画面)。

 まとめると、「N」桁目までは最初のForループによって目盛線付きのバーあるいは目盛線のないバーが書き込まれ、「N+1」桁目から16桁目までは2番目のForループによって目盛線あるいはスペースが書き込まれます。最初のForループでは変数「Bar」の値と表示する桁が同じですが、2番目のForループでは変数「Bar」の値に「1」を加えた桁に表示されることに注意してください。

3. 1⁄5桁単位でバー表示する

 上の例よりもっと細かく、1⁄5桁単位でバーグラフが延びていくプログラムです。16桁で80までカウントします。

 第3図

 プログラムファイル lcd6c.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 Declare Sub Bargraph1 サブルーチン「Bargraph1」を使用する。
8 Declare Sub Bargraph2 サブルーチン「Bargraph2」を使用する。
9 Dim N As Byte バイト型変数「N」を使用する。
10 Deflcdchar 1, 32, 32, 16, 16, 16, 16, 32, 32 1⁄5桁表示用「Chr(1)」の文字データ。
11 Deflcdchar 2, 32, 32, 24, 24, 24, 24, 32, 32 2⁄5桁表示用「Chr(2)」の文字データ。
12 Deflcdchar 3, 32, 32, 28, 28, 28, 28, 32, 32 3⁄5桁表示用「Chr(3)」の文字データ。
13 Deflcdchar 4, 32, 32, 30, 30, 30, 30, 32, 32 4⁄5桁表示用「Chr(4)」の文字データ。
14 Deflcdchar 5, 32, 32, 31, 31, 31, 31, 32, 32 5⁄5桁表示用「Chr(5)」の文字データ。
15 Cursor Off カーソルを表示しない。
16 Cls LCDの表示を消去する。
17 Do Doループの範囲ここから。
18  For N = 0 To 80 Forループの範囲ここから。81回繰り返し。
19  Lcd "Count " ; N LCD画面に「Count 」と「N」の値を表示する。
20  Call Bargraph1 サブルーチン「Bargraph1」を実行。
21  Call Bargraph2 サブルーチン「Bargraph2」を実行。
22  Wait 1 1秒間そのまま。
23  Cls LCDの表示を消去する。
24  Next N Forループの範囲ここまで。18行目へ戻る。
25 Loop Doループの範囲ここまで。17行目へ戻る。
26 End メインプログラム終わり。
27 Sub Bargraph1 サブルーチン「Bargraph1」ここから。
28 Local Col As Byte サブルーチン内で変数「Col」を使用する。
29 Local Bar5 As Byte サブルーチン内で変数「Bar5」を使用する。
30 Bar5 = N ⁄ 5 「N÷5」を変数「Bar5」に代入する。
31 Lowerline LCDの下の行に表示する。
32 For Col = 1 To Bar5 Forループここから。1から「Bar5」まで繰り返し。
5カウント毎に1桁分のバーを表示するプログラム。
33  Lcd Chr(5) LCDに「Chr(5) 」を表示する。
34 Next Col Forループここまで。32行目へ戻る。
35 End Sub サブルーチン「Bargraph1」ここまで。
36 Sub Bargraph2 サブルーチン「Bargraph2」ここから。
37 Local Bar1 As Byte サブルーチン内で変数「Bar1」を使用する。
38 Bar1 = N Mod 5 「N÷5」の余りを変数「Bar1」に代入する。
39  Select Case Bar1 「変数値選択」のプログラムここから。
「Bar1」の値に応じて下記のプログラムを実行。
1桁未満のバーを表示するプログラム。
40  Case 1 : Lcd Chr(1) 「Bar1 = 1」なら「Chr(1) 」を表示する。
41  Case 2 : Lcd Chr(2) 「Bar1 = 2」なら「Chr(2) 」を表示する。
42  Case 3 : Lcd Chr(3) 「Bar1 = 3」なら「Chr(3) 」を表示する。
43  Case 4 : Lcd Chr(4) 「Bar1 = 4」なら「Chr(4) 」を表示する。
44  End Select 「変数値選択」のプログラムここまで。
45 End Sub サブルーチン「Bargraph2」ここまで。

 サブルーチンが2個あります。サブルーチン「Bargraph1」は5カウントごとに1桁分のバーを表示するプログラム、サブルーチン「Bargraph2」は1桁に満たない端数分のバーを表示するプログラムです。「Bargraph1」ではカウント数「N」を5で割ってその答えを変数「Bar5」に代入します。「Bar5」はバイト型変数なので、小数部分は切り捨てられます。例えば「N」が10〜14のどれであっても「Bar5」は「2」になります。32行目から34行目のForループで「Bar5」の数の分だけ「Chr(5) 」(1桁分のバー)を表示します。

 サブルーチン「Bargraph2」では38行目「Bar1 = N Mod 5」により、カウント数「N」を5で割った余りを求めます。変数「Bar1」の値は1〜4のどれかになります。39〜44行目の「変数値選択」プログラムで、「Bar1」の値に応じた幅のバーを表示します。