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

BASCOM-AVR LEDの点灯・消灯(その4)

 「その3」と同じく、ポートAに接続した8個のLEDを、右(LED0)から順に1個ずつ点灯させるプログラムですが、For〜Next命令を使って簡単にしてみました。点灯のしかたは下図の通りです。マイコン回路は「LED点滅テスト用回路」を使用します。

時間LED7LED6LED5LED4 LED3LED2LED1LED0
0
1
2
3
4
5
6
7
8

1. Rotate命令を使う

 最初にLED0を点灯させ、その形のまま左へ1ビットずつ移動させます。

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

1 $regfile = "at26def.dat" ATtiny26Lを使用する。
2 $crystal = 1000000 クロック周波数を1MHzに設定。
3 Config Porta = Output ポートAを出力に設定する。
4 Dim N As Byte バイト型変数「N」を定義する。
5 Porta =1 ポートAを「1」にする。LED0が点灯。
6 For N = 1 to 8 Forループの範囲ここから。
変数Nに1から8を順に代入する。
7  Waitms 500 0.5秒間そのまま。
8  Rotate Porta , Left ポートAの出力を1ビット左に回転させる。
左隣のLEDが点灯する。
9 Next N Forループの範囲ここまで。
6行目へ戻り、Nに1を加えて繰り返し。
10 Porta = 0 ポートAを「0」にする。すべてのLEDが消灯する。
11 End 終わり。

 6行目の「For 〜 」は9行目の「Next 〜 」と対応しています。6行目は「For N = 1 to 8 」となっていますが、最初に「N=1」として7行目と8行目のプログラムを実行し、「Next」で6行目「For」へ戻ります。2回目は「N=2」として7,8行目のプログラムを実行し、また「For」へ戻ります。こうしてNが8になるまで8回同じことを繰り返します。8回目のプログラムを実行したあと、ループを抜けて10行目へ移ります。なお、9行目「Next N」は「Next」だけでも差し支えないようです。

 8行目の「Rotate Porta , Left」は、ポートAのPA7〜PA0の出力を8桁の2進数とみなし、これを1桁(1ビット)左へずらすプログラムです。これにより「00000001」から「00000010」へ、さらに「00000100」へと出力状態が変化していきます。今回のプログラムは「10000000」で止めていますが、左へさらに一回Rotateすると「00000001」に戻ります。だからRotate (回転)というのだと思います。

 8行目を「Rotate Porta , Right」と書けば、右向きに回転します。また、「Rotate Porta , Left , 2」と書けば左へ2ビットずつ回転します。1ビットずつ回転させるときは「1」は省略できます。

2. 指数を変数にする

 「その3」でポートAの出力を10進数で指定するプログラムを作りました。このときの数字を見ると、Porta = 1, 2, 4, 8, 16, 32, 64, 128 と、2の累乗(べき乗)になっています。これを利用して、指数部分を変数Nにしてプログラムを組んでみました。

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

1 $regfile = "at26def.dat" ATtiny26Lを使用する。
2 $crystal = 1000000 クロック周波数を1MHzに設定。
3 Config Porta = Output ポートAを出力に設定する。
4 Dim N As Byte バイト型変数「N」を定義する。
5 For N = 0 to 7 Forループの範囲ここから。
変数Nに0から7を順に代入する。
6  Porta = 2 ^ N ポートAの出力を「2のN乗」にする。
7  Waitms 500 0.5秒間そのまま。
8 Next N Forループの範囲ここまで。
5行目へ戻り、Nに1を加えて繰り返し。
9 Porta = 0 ポートAを「0」にする。すべてのLEDが消灯する。
10 End 終わり。

 5行目「Porta = 2 ^ N」は、ポートAの出力を2のN乗(10進数)にするという意味です。累乗を表わす記号「^」はキーボードの右上のほうにあると思います。この記号は「ハット」とか「やま」とかよばれているようです。ループ1回目では「Porta = 2 ^ 0」つまり「Porta = 1」となってLED0のみが点灯します。2回目は「Porta = 2 ^ 1」つまり「Porta = 2」ですからLED1のみが点灯します。7回目は「Porta = 2 ^ 7」すなわち「Porta = 128」で、LED7が点灯します。変数Nの値と同じ番号のLEDが点灯することになります。

3. 逆方向に1個ずつ順次点灯させる

 For 〜 Next命令では、変数に代入する値を1ずつ減らすこともできます。これを使うと、上記と逆方向、つまりLED7からLED0へ向かって1個ずつ点灯させるプログラムができます。

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

1 $regfile = "at26def.dat" ATtiny26Lを使用する。
2 $crystal = 1000000 クロック周波数を1MHzに設定。
3 Config Porta = Output ポートAを出力に設定する。
4 Dim N As Byte バイト型変数「N」を定義する。
5 For N = 7 to 0 Step -1 Forループの範囲ここから。
変数Nに7から0を順に代入する。
6  Porta = 2 ^ N ポートAの出力を「2のN乗」にする。
7  Waitms 500 0.5秒間そのまま。
8 Next N Forループの範囲ここまで。
5行目へ戻り、Nから1を減じて繰り返し。
9 Porta = 0 ポートAを「0」にする。すべてのLEDが消灯する。
10 End 終わり。

 先のプログラムと違うのは5行目だけです。ここは「For N = 7 to 0 Step -1」となっています。これは変数Nに7, 6, 5, 4, 3, 2, 1, 0 を順に代入することを意味します。ループ1回目は「Porta = 2 ^ 7」になるのでLED7が点灯、その後LED6, LED5と順に点灯します。なお、For命令文で「Step 〜 」の記述がない場合は「Step 1」とみなされます。

4. 変数を2個使用する

 順序が後先になりますが、「その3」の最初に出てきた「on_off3a.bas」をForループに当てはめたプログラムを作りました。LEDを消灯する端子の番号をN1、点灯する端子の番号をN2とします。

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

1 $regfile = "at26def.dat" ATtiny26Lを使用する。
2 $crystal = 1000000 クロック周波数を1MHzに設定。
3 Config Porta = Output ポートAを出力に設定する。
4 Dim N1 As Byte バイト型変数「N1」を定義する。
5 Dim N2 As Byte バイト型変数「N2」を定義する。
6 Porta.0 = 1 LED0を点灯する。
7 Waitms 500 0.5秒間そのまま。
8 For N1 = 0 to 6 Forループの範囲ここから。
変数N1に0から6を順に代入する。
9  Porta.n1 = 0 ポートAのN1番の出力を「0」にする。LED・N1消灯。
10  N2 = N1 + 1 変数N1に1を加えて変数N2に代入する。
11  Porta.n2 = 1 ポートAのN2番の出力を「1」にする。LED・N2点灯。
12  Waitms 500 0.5秒間そのまま。
13 Next N1 Forループの範囲ここまで。
8行目へ戻り、N1に1を加えて繰り返し。
14 Porta = 0 ポートAを「0」にする。すべてのLEDが消灯する。
15 End 終わり。

 最初にLED0を点灯させます(6行目「Porta.0 = 1」)。Forループ1回目ではN1=0なので、9行目は「Porta.0 = 0」になり、LED0は消灯します。10行目「N2 =N1 + 1」は変数N1の値に1を加えた数値を変数N2の値にするという意味です。N1が0ならN2は1です。よって11行目は「Porta.1 = 1」の意味になり、LED1が点灯します。以降、LED7まで1個ずつ順次点灯します。なお、9行目や11行目ではNが小文字になっていますが、BASCOM-AVR IDEの仕様でこのように変換されます。

5. 変数を1個ですませる

 上のプログラムを見ていて、LEDを消灯するときはわざわざピン番号まで指定しなくても「Porta=0」で良いことに気が付きました。これなら変数は1個ですみます。

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

1 $regfile = "at26def.dat" ATtiny26Lを使用する。
2 $crystal = 1000000 クロック周波数を1MHzに設定。
3 Config Porta = Output ポートAを出力に設定する。
4 Dim N As Byte バイト型変数「N」を定義する。
5 Porta.0 = 1 LED0を点灯する。
6 Waitms 500 0.5秒間そのまま。
7 For N = 1 to 7 Forループの範囲ここから。
変数Nに1から7を順に代入する。
8  Porta = 0 ポートAの出力を「0」にする。LEDはすべて消灯。
9  Porta.n = 1 ポートAのN番の出力を「1」にする。LED・N点灯。
10  Waitms 500 0.5秒間そのまま。
11 Next N Forループの範囲ここまで。
7行目へ戻り、Nに1を加えて繰り返し。
12 Porta = 0 ポートAを「0」にする。すべてのLEDが消灯する。
13 End 終わり。