「その3」と同じく、ポートAに接続した8個のLEDを、右(LED0)から順に1個ずつ点灯させるプログラムですが、For〜Next命令を使って簡単にしてみました。点灯のしかたは下図の通りです。マイコン回路は「LED点滅テスト用回路」を使用します。
時間 | LED7 | LED6 | LED5 | LED4 | LED3 | LED2 | LED1 | LED0 |
0 | ||||||||
1 | ||||||||
2 | ||||||||
3 | ||||||||
4 | ||||||||
5 | ||||||||
6 | ||||||||
7 | ||||||||
8 |
最初に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」は省略できます。
「その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が点灯することになります。
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」とみなされます。
順序が後先になりますが、「その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の仕様でこのように変換されます。
上のプログラムを見ていて、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 | 終わり。 |