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

BASCOM-AVR 入力スイッチ(その1)

 入力スイッチを使うプログラムをいろいろ試してみました。押しボタンスイッチを押すとLEDの点灯状態が変化するプログラムです。マイコン回路は「入力スイッチテスト用回路」を使用します。

1. 出力端子を入力端子と同じ状態にする

 まず最初に、出力端子を入力端子と同じ状態にするプログラムを作りました。入力スイッチはマイコンICのPB0〜GND間に接続されています。入力スイッチを押すと接点が閉じてPB0はGNDと同電位すなわち「0」になります。スイッチが押されていないときはPB0が「1」になっています。このプログラムは、入力(PB0)が「1」のときは出力(PA0)も「1」となってLED0が点灯、入力が「0」のときは出力も「0」になってLED0が消灯するものです。つまりスイッチが押されている間だけLEDが消灯することになります。動作の様子を図に書くと下のようになります。

 第1図

 プログラムは下記の通りです。BASCOM-AVRがインストールされたパソコンで下記リンクをクリックしてファイルをダウンロードすると、BASCOM-AVR IDEが自動的に立ち上がって画面内にプログラムが表示されます。

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

1 $regfile = "at26def.dat" ATtiny26Lを使用する。
2 $crystal = 1000000 クロック周波数を1MHzに設定。
3 Config Porta.0 = Output PA0を出力に設定する。
4 Config Portb.0 = Input PB0を入力に設定する。
5 Portb.0 = 1 PB0をプルアップする。
6 Do Doループの範囲ここから。
7  Porta.0 = Pinb.0 PA0の出力をPB0と同じ状態にする。
8 Loop Doループの範囲ここまで。6行目へ戻る
9 End 終わり。

 3行目でPA0を出力端子に、4行目でPB0を入力端子に設定します。5行目「Portb.0 = 1」は、PB0を「1」にするという意味ですが、これによりPB0はIC内部でプルアップされます。つまりスイッチが押されていないとき(接点が開いているとき)は常に入力端子が「1」の状態に保たれます。スイッチが押されたとき(接点が閉じたとき)だけ「0」になります。

 7行目「Porta.0 = Pinb.0」はPA0の状態をPB0と同じにするという命令です。右辺は「Portb.0」ではなく「Pinb.0」であることに注意してください。入力端子の状態を表わすときはこのように記述します。「Portb.0」と書いてコンパイルしてもエラーにはなりませんが、プログラムは正しく動作しません。「Pin」は「ピン」ではなく「Port input」の意味ではないかと思います。また「=」は数学の等号とは違うので、左辺と右辺を入れ替えることはできません。

 7行目が「Do〜Loop」で挟まれているのは、こうしないとスイッチを押す間もなくあっという間にプログラムが終わってしまうからです。入力スイッチが押されればいつでも反応するようにするためには、メインプログラム全体を「Do〜Loop」で挟む必要があります。

 入力端子をプログラム中でプルアップしない場合は、下図のように10kΩ程度のプルアップ抵抗を接続する必要があります。

 第2図

2. ポート全体を出力あるいは入力に設定する

 上記のプログラムではPA0及びPB0を個別に入出力端子として設定しましたが、これまでのプログラムと同様、ポート全体を入力あるいは出力に設定したほうが書式が簡単になります。PB0のプルアップは「Portb = 1」と書けばOKです。

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

1 $regfile = "at26def.dat" ATtiny26Lを使用する。
2 $crystal = 1000000 クロック周波数を1MHzに設定。
3 Config Porta = Output ポートAを出力に設定する。
4 Config Portb = Input ポートBを入力に設定する。
5 Portb = 1 PB0をプルアップする。
6 Do Doループの範囲ここから。
7  Porta.0 = Pinb.0 PA0の出力をPB0と同じ状態にする。
8 Loop Doループの範囲ここまで。6行目へ戻る
9 End 終わり。

3. スイッチを押している間だけLEDが点灯する (ハードウェアで)

 上記と逆の動作、つまり入力スイッチを押している間だけLEDを点灯させるにはどうしたらよいでしょうか。下記のような動作です。

 第2図

 ひとつには入力回路を下の回路図のように変更する方法が考えられます。下図左はプッシュオフ型の押しボタンスイッチを使うものです。ボタンを押すと接点が離れて入力端子が「1」になるので、出力も「1」になってLEDが点灯します。右は入力端子とGND間に抵抗をつないでプルダウンする方法です。これもスイッチを押すと入力端子が「1」になるのでLEDが点灯します。この場合はプログラム5行目の「Portb = 1」は削除します。

 第3図

4. スイッチを押している間だけLEDが点灯する (プログラムで)

 マイコン回路を変更することなく、スイッチを押している間だけLEDが点灯するようなプログラムができないか考えてみました。たぶん何通りもあるのでしょうが、下記のように条件分岐「If」を用いて入力端子の状態を判断する形にしたらうまくいきました。

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

1 $regfile = "at26def.dat" ATtiny26Lを使用する。
2 $crystal = 1000000 クロック周波数を1MHzに設定。
3 Config Porta = Output ポートAを出力に設定する。
4 Config Portb = Input ポートBを入力に設定する。
5 Portb = 1 PB0をプルアップする。
6 Do Doループの範囲ここから。
7  If Pinb.0 = 0 Then 条件分岐のプログラムここから。
もし「Pinb.0 = 0」ならば次行のプログラムを実行。
8  Porta = 1 ポートAを「1」にする。LED0が点灯。
9  Else そうでなければ(「Pinb.0 = 1」ならば)、
次行のプログラムを実行。
10  Porta = 0 ポートAを「0」にする。LED0が消灯。
11  End If 条件分岐のプログラムここまで。
12 Loop Doループの範囲ここまで。6行目へ戻る
13 End 終わり。

 7行目「If Pinb.0 = 0 Then」で入力端子の状態を判断します。ここも「Pinb.0」と書かなければなりません。「Portb.0」ではだめです。「Pinb.0 = 0」(スイッチが押されている)ならば、8行目の「Porta = 1」が実行され、LEDは点灯します。もし「Pinb.0 = 1」(スイッチが押されていない)ならば、10行目の「Porta = 0」が実行されてLEDは消灯します。

 このプログラムはいろいろ応用できます。たとえば8行目を「Porta = 0」、10行目を「Porta = 1」に変えれば、最初のプログラムと同じ、スイッチを押している間だけLEDが消灯する動作になります。また、8行目を「Porta = 255」と書けば、スイッチを押したとき8個のLEDすべてが点灯します。なお、「Else」命令(9行目と10行目)を書かないと、いったんLEDが点灯したら点灯しっぱなしになってしまいます。

5. BASCOM-AVRプログラムシミュレーターの使い方

 入力スイッチを使ったプログラムもプログラムシミュレーターでシミュレーションすることができます。「Hardware Simulation」の画面で「PA」「PB」と書かれた赤いLEDが出力の状態、「IA」「IB」と書かれた緑のLEDが入力を表わしています。それぞれ消灯していれば「0」、点灯していれば「1」です。最初のプログラム「input1a.bas」を例に取ると、スイッチを押したときの状態は下記のようになります。PB0はプルアップされている(Portb.0 = 1)のでここだけ点灯しています。

 第5図

 押しボタンスイッチの動きと逆になる感じですが、スイッチを放したときの状態を見るには「IB0」の緑のLEDをクリックします。するとこれが点灯し(Pinb.0 = 1)、同時にPA0の赤いLEDも点灯します(Porta.0 = 1になる)。このときのようすを下に示します。

 第6図