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

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

 最初にLED0のみ点灯、次にLED0とLED1の2個が点灯、次はLED0〜LED2の3個が点灯、というように点灯個数が1個ずつ増えていくプログラムを作りました。点灯のようすは下の図のようになります。マイコン回路は「LED点滅テスト用回路」を使用します。

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

1. ポートの出力端子をひとつずつONにする

 ポートAの各端子をPA0から順にひとつずつ「1」にしていくプログラムです。それまで点いているLEDを消灯する命令が入っていないので、点灯個数が1個ずつ増えていきます。

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

1 $regfile = "at26def.dat" ATtiny26Lを使用する。
2 $crystal = 1000000 クロック周波数を1MHzに設定。
3 Config Porta = Output ポートAを出力に設定する。
4 Dim T As Word 待ち時間設定用の変数「T」を定義する。
5 T = 500 変数Tの値を500にする。(待ち時間500mS)
6 Porta.0 = 1 PA0の出力を「1」にする。LED0が点灯。
7 Waitms T Tミリ秒間(0.5秒間)そのまま。
8 Porta.1 = 1 PA1の出力を「1」にする。LED0はそのままでLED1が点灯。
9 Waitms T Tミリ秒間(0.5秒間)そのまま。
10 Porta.2 = 1 PA2の出力を「1」にする。LED0〜LED2が点灯。
11 Waitms T Tミリ秒間(0.5秒間)そのまま。
12 Porta.3 = 1 PA3の出力を「1」にする。LED0〜LED3が点灯。
13 Waitms T Tミリ秒間(0.5秒間)そのまま。
14 Porta.4 = 1 PA4の出力を「1」にする。LED0〜LED4が点灯。
15 Waitms T Tミリ秒間(0.5秒間)そのまま。
16 Porta.5 = 1 PA5の出力を「1」にする。LED0〜LED5が点灯。
17 Waitms T Tミリ秒間(0.5秒間)そのまま。
18 Porta.6 = 1 PA6の出力を「1」にする。LED0〜LED6が点灯。
19 Waitms T Tミリ秒間(0.5秒間)そのまま。
20 Porta.7 = 1 PA7の出力を「1」にする。すべてのLEDが点灯。
21 Waitms T Tミリ秒間(0.5秒間)そのまま。
22 Porta = 0 ポートAの出力を「0」にする。すべてのLEDが消灯。
23 End 終わり。

2. ポートの出力を2進数で指定する

 ポートAの出力を8桁の2進数で指定するやり方です。「&B」に続いて点灯パターンの通りに「0」と「1」を並べていくだけなので簡単です。

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

1 $regfile = "at26def.dat" ATtiny26Lを使用する。
2 $crystal = 1000000 クロック周波数を1MHzに設定。
3 Config Porta = Output ポートAを出力に設定する。
4 Dim T As Word 待ち時間設定用の変数「T」を定義する。
5 T = 500 変数Tの値を500にする。(待ち時間500mS)
6 Porta = &B00000001 ポートAの出力を「00000001」にする。LED0のみ点灯。
7 Waitms T Tミリ秒間(0.5秒間)そのまま。
8 Porta = &B00000011 ポートAの出力を「00000011」にする。LED0とLED1が点灯。
9 Waitms T Tミリ秒間(0.5秒間)そのまま。
10 Porta = &B00000111 ポートAの出力を「00000111」にする。LED0〜LED2が点灯。
11 Waitms T Tミリ秒間(0.5秒間)そのまま。
12 Porta = &B00001111 ポートAの出力を「00001111」にする。LED0〜LED3が点灯。
13 Waitms T Tミリ秒間(0.5秒間)そのまま。
14 Porta = &B00011111 ポートAの出力を「00011111」にする。LED0〜LED4が点灯。
15 Waitms T Tミリ秒間(0.5秒間)そのまま。
16 Porta = &B00111111 ポートAの出力を「00111111」にする。LED0〜LED5が点灯。
17 Waitms T Tミリ秒間(0.5秒間)そのまま。
18 Porta = &B01111111 ポートAの出力を「01111111」にする。LED0〜LED6が点灯。
19 Waitms T Tミリ秒間(0.5秒間)そのまま。
20 Porta = &B11111111 ポートAの出力を「11111111」にする。すべてのLEDが点灯。
21 Waitms T Tミリ秒間(0.5秒間)そのまま。
22 Porta = &B00000000 ポートAの出力を「00000000」にする。すべてのLEDが消灯。
23 End 終わり。

3. For 〜 Next 命令を使う

 ポートAのピン番号を変数にしてForループで回すとプログラムが簡単になります。1回前のループで点灯したLEDを消灯する命令が入っていないので、点灯するLEDの数はひとつずつ増えていきます。

 プログラムファイル on_off5b.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.n = 1 ポートAのN番の出力を「1」にする。LED-Nが点灯。
7  Waitms 500 0.5秒間そのまま。
8 Next N Forループの範囲ここまで。
5行目へ戻り、Nに1を加えて繰り返し。
9 Porta = 0 ポートAを「0」にする。すべてのLEDが消灯する。
10 End 終わり。

4. 指数を変数にする

 2番目のプログラム(on_off5a.bas)で、点灯パターンを示す8ビットの2進数を10進数に変換してみると、きまった法則があることに気付きます。下の表のように、すべて「2の累乗マイナス1」になっています。

2進数10進数2の累乗
0000000112^1−1
0000001132^2−1
0000011172^3−1
00001111152^4−1
00011111312^5−1
00111111632^6−1
011111111272^7−1
111111112552^8−1

 このことを利用して、「Porta = 2の累乗−1」としてForループで回すプログラムを作りました。ただ、一度で計算しようとするとエラーが出てしまったので、N1とN2の2つの変数を設定し、まず2のN1乗を計算してこれをN2に代入し、次にN2から1を引くという手順を取っています。おそらく一度で計算する方法もあると思いますが、現時点ではわかりません。

 プログラムファイル on_off5c.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 For N1 = 1 to 8 Forループの範囲ここから。
変数N1に1から8を順に代入する。
7  N2 = 2 ^ N1 2のN1乗をN2とする。
8  Porta = N2 - 1 ポートAの出力を「N2−1」にする。
9  Waitms 500 0.5秒間そのまま。
10 Next N1 Forループの範囲ここまで。
6行目へ戻り、N1に1を加えて繰り返し。
11 Porta = 0 ポートAを「0」にする。すべてのLEDが消灯する。
12 End 終わり。