LEDを決まった回数だけ点滅させるプログラムを考えました。LED0が0.5秒間隔で5回点滅して消灯するプログラムです。マイコン回路は「LED点滅テスト用回路」を使用します。
5回点滅といってすぐ思いつくのがこれでしょう。Forループで点灯と消灯を5回繰り返すプログラムです。
プログラムファイル blink2a.bas
1 | $regfile = "at26def.dat" | ATtiny26Lを使用する。 | |
2 | $crystal = 1000000 | クロック周波数を1MHzに設定。 | |
3 | Config Porta = Output | ポートAを出力に設定する。 | |
4 | Dim N As Byte | バイト型変数「N」を定義する。 | |
5 | For N = 1 To 5 | Forループの範囲ここから。5回繰り返し。 | |
6 | Porta.0 = 1 | PA0の出力を「1」にする。LED0が点灯。 | |
7 | Waitms 500 | 0.5秒間そのまま。 | |
8 | Porta.0 = 0 | PA0の出力を「0」にする。LED0が消灯。 | |
9 | Waitms 500 | 0.5秒間そのまま。 | |
10 | Next N | Forループの範囲ここまで。5行目へ戻る。 | |
11 | End | 終わり。 |
「LEDの点滅(その1)」で無限ループ(Do〜Loop)というのが出てきましたが、ループの最後の行を「Loop Until (条件式)」と書くと、条件式と合致するまでループを繰り返す、というプログラムになります。これによりループの回数を有限にすることができます。
プログラムファイル blink2b.bas
1 | $regfile = "at26def.dat" | ATtiny26Lを使用する。 | |
2 | $crystal = 1000000 | クロック周波数を1MHzに設定。 | |
3 | Config Porta = Output | ポートAを出力に設定する。 | |
4 | Dim N As Byte | バイト型変数「N」を定義する。 | |
5 | Do | Doループの範囲ここから。 | |
6 | N = N + 1 | 変数「N」に1を加えて新たな「N」とする。 | |
7 | Porta.0 = 1 | PA0の出力を「1」にする。LED0が点灯。 | |
8 | Waitms 500 | 0.5秒間そのまま。 | |
9 | Porta.0 = 0 | PA0の出力を「0」にする。LED0が消灯。 | |
10 | Waitms 500 | 0.5秒間そのまま。 | |
11 | Loop Until N = 5 | Doループの範囲ここまで。5行目へ戻る。 | |
変数「N」の値が5になったらループを抜けて次行へ。 | |||
12 | End | 終わり。 |
変数「N」の初期値は、何も指定がなければ「0」になります。Doループ1巡目、6行目「N = N + 1」で「N」の値は「1」に変わります。LEDが1回点灯・消灯したあと5行目「Do」へ戻ります。これを5回繰り返しますが、5巡目で「N = 5」になると、11行目「Loop Until N = 5」という条件に合致するのでDoループを抜け出し、プログラムは終了します。なお、11行目は「Loop Until N > 4」と書くこともできます。
条件分岐(条件判断)とよばれる構文があります。書式は「If (条件式) Then」となります。もし条件式に合っていれば「Then」以下のプログラムを実行するという意味です。これをDoループの中に入れてみました。
プログラムファイル blink2c.bas
1 | $regfile = "at26def.dat" | ATtiny26Lを使用する。 | |
2 | $crystal = 1000000 | クロック周波数を1MHzに設定。 | |
3 | Config Porta = Output | ポートAを出力に設定する。 | |
4 | Dim N As Byte | バイト型変数「N」を定義する。 | |
5 | Do | Doループの範囲ここから。 | |
6 | Incr N | 変数「N」に1を加えて新たな「N」とする。 | |
7 | Porta.0 = 1 | PA0の出力を「1」にする。LED0が点灯。 | |
8 | Waitms 500 | 0.5秒間そのまま。 | |
9 | Porta.0 = 0 | PA0の出力を「0」にする。LED0が消灯。 | |
10 | Waitms 500 | 0.5秒間そのまま。 | |
11 | If N = 5 Then | 条件分岐のプログラムここから。 | |
もし「N = 5」ならば次行のプログラムを実行。 | |||
12 | Exit Do | Doループを抜けて15行目へ。 | |
13 | End If | 条件分岐のプログラムここまで。 | |
14 | Loop | Doループの範囲ここまで。5行目へ戻る。 | |
15 | End | 終わり。 |
6行目「Incr N」は「N = N + 1」と同じです。加える数が1ならばこのように書くことができます。こっちの方が簡単ですね。「Incr」は「Increment」(インクリメント、増加)の略です。逆に「N = N - 1」のときは「Decr N」と書きます。これは「Decrement」(デクリメント、減少)の略です。
「Do〜Loop」内で「N」の値は1ずつ増えていきますが、「N」が4以下のときは12行目のプログラム「Exit Do」は無視されます。「N = 5」になったとき、11行目「If N = 5 Then」で設定した条件に合致しますので、12行目「Exit Do」が実行され、Doループを抜けてプログラムは終了します。
(追記 : 2007年1月26日)
なお、条件式に合致したときに実行するプログラムが1行だけのときは、11行目と12行目をまとめて「If N = 5 Then Exit Do」と書いても差し支えありません。このように書いたときは13行目「End If」は不要です。ただし、11行目と12行目を「If N = 5 Then : Exit Do」のように「:」(コロン)で区切って書いたときは、改行したのと同じとみなされるので「End If」が必要になります。ちょっとややこしいです。
(追記ここまで)
条件分岐のプログラムでは、「Else」という命令を使って、条件に合わないときに実行するプログラムを記述することができます。ここでは、条件に合致したときは点滅を継続、合致しないときはLEDを消灯する、という動作にしました。また、「Do〜Loop」の代わりに「Main:〜Goto Main」を用いています。
プログラムファイル blink2d.bas
1 | $regfile = "at26def.dat" | ATtiny26Lを使用する。 | |
2 | $crystal = 1000000 | クロック周波数を1MHzに設定。 | |
3 | Config Porta = Output | ポートAを出力に設定する。 | |
4 | Dim N As Byte | バイト型変数「N」を定義する。 | |
5 | Main: | この場所に「Main」という名前を付ける。 | |
6 | Porta.0 = 1 | PA0の出力を「1」にする。LED0が点灯。 | |
7 | Waitms 500 | 0.5秒間そのまま。 | |
8 | Porta.0 = 0 | PA0の出力を「0」にする。LED0が消灯。 | |
9 | Waitms 500 | 0.5秒間そのまま。 | |
10 | Incr N | 変数「N」に1を加えて新たな「N」とする。 | |
11 | If N < 5 Then | 条件分岐のプログラムここから。 | |
もし「N < 5」ならば次行のプログラムを実行。 | |||
12 | Goto Main | 5行目「Main」へ戻る。 | |
13 | Else | 「N < 5」でなければ次行のプログラムを実行。 | |
14 | Porta.0 = 0 | PA0の出力を「0」にする。LED0が消灯。 | |
15 | End If | 条件分岐のプログラムここまで。 | |
16 | End | 終わり。 |
6〜9行目でLEDを1回点滅させた後、10行目で「N」を「1」にします。11行目に「If N < 5 Then」という条件文がありますが、「N = 1」ならこの条件に合っていますので12行目「Goto Main」が実行され、プログラムは5行目へ戻ります。こうして「N = 5」になるまでLEDの点滅と「Incr N」が繰り返されます。「N = 5」になったとき、これは「N < 5」という条件に合致しませんから13行目「Else」によって14行目「Porta.0 = 0」という命令が実行されます。
BASCOM-AVRのマニュアルを見ていて「While〜Wend」という構文を見つけました。これははじめから有限回数のループを意図した命令のようです。最初に「While (条件式)」と書き、「Wend」との間に繰り返すプログラムを記述します。変数が条件式に合致するまで、「While〜Wend」間の命令を繰り返します。
プログラムファイル blink2e.bas
1 | $regfile = "at26def.dat" | ATtiny26Lを使用する。 | |
2 | $crystal = 1000000 | クロック周波数を1MHzに設定。 | |
3 | Config Porta = Output | ポートAを出力に設定する。 | |
4 | Dim N As Byte | バイト型変数「N」を定義する。 | |
5 | While N < 5 | While〜Wendループの範囲ここから。 | |
「N < 5」のうちは「While〜Wend」間をループ。 | |||
6 | Porta.0 = 1 | PA0の出力を「1」にする。LED0が点灯。 | |
7 | Waitms 500 | 0.5秒間そのまま。 | |
8 | Porta.0 = 0 | PA0の出力を「0」にする。LED0が消灯。 | |
9 | Waitms 500 | 0.5秒間そのまま。 | |
10 | Incr N | 変数「N」に1を加えて新たな「N」とする。 | |
11 | Wend | While〜Wendループの範囲ここまで。5行目へ戻る。 | |
変数「N」の値が5になったらループを抜けて次行へ。 | |||
12 | End | 終わり。 |
5行目「While N < 5」は、変数「N」の値が5より小さいうちは「While〜Wend」間の命令を繰り返すという意味です。「N = 5」になったらループを抜けてプログラムを終了します。