マイコン初心者講座その5 スイッチでLEDを制御する

前回のその4ではLEDを自動的に点滅させるプログラムを作りました。
今回はスイッチでLEDを点けたり消したりするプログラムを作ります。

回路

今回必要な部品は前回のLEDに加え、スイッチが必要となります。
LEDの接続ピンは前回同様PORTBの0番とし、追加するスイッチはPIC16F88の左上のピン、PORTAの2番ピンとします。
回路は以下のようになります。

回路の仕様としては、スイッチが押されていないときにはRA2には"1(5V)"が、押されたときには"0(0V)"が加わります。押されていないときが"0"なことに注意しないといけません。
また、RA2から電源に向かって接続されている10kΩの抵抗はプルアップ抵抗と呼ばれるものです。これがないとスイッチが押されていないときにPICのピンの状態が不定となり正常に動作しないだけでなく、PICを破壊してしまう可能性もあります。プルアップ抵抗について詳しくは調べてみてください。
タクトスイッチは以下の画像のようになっています。青のピン間は常に接続されており、赤のピン間はボタンを押したときに繋がります。接続の際はその点に注意してください。

プログラミング

新しくプロジェクトを作成するため、programmingフォルダの中に"switchLED"というフォルダを新しく作ります。
前回の手順を参考にしてswitchLEDというプロジェクトを作成します。今回もPIC16F88を8MHzで使用するので設定も同じです。

続いてプログラムを記述します。
初期状態では以下のようにmain関数に何も書かれていないものが作られています。

void main() {

}

まずクロックを設定するために以下を記述します。内蔵発振器を8MHzで使用する設定です。

     OSCCON = 0x70;

今回もアナログ入力機能を使用しないため、ANSELをクリアします。

     ANSEL = 0x00;

続いてポートの入出力の方向を設定します。今回はスイッチによってLEDを制御するので、マイコンに接続するスイッチのピンを入力に指定しないといけません。

ピンを入力に設定するにはTRISレジスタでそのピンに対応するビットを1にするだけです。
つまりこのようになります。

     TRISA = 0x04;
     TRISB = 0x00;

0x04というのは0b00000100と同じ意味です。ここで1になっているのはPORTAの2に対応する部分です。これでPORTAの2番ピンをディジタル入力ピンとして使う準備ができました。

その後全ポートをリセットします。

     PORTA = 0x00;
     PORTB = 0x00;

次にメインループの記述です。
まず外枠を用意します。

     while(1) {

     }

今回のメインとなる動作はスイッチが押されたかどうかを判定するということです。プログラムではif文でスイッチに接続されたピンの状態を判定することで実現します。
ポートに値を書き込む場合はPORTA = 0xXXというように書きました。mikcoCではポートを変数のように扱えるので、ポートの値を読み込むには"a = PORTA;"のような記述方法でOKです。
しかしポートの値は8bitごとにまとめてしか取得できないため、次のような方法を使います。

     if((PORTA & 0x04) != 0)

"&"は論理積を取る演算子です。論理積とは以下のような演算結果です。

0 & 0 = 0
0 & 1 = 0
1 & 0 = 0
1 & 1 = 1

つまりお互いが1でないとその出力は1にはならない演算です。
PORTAの2番ピンにスイッチが接続されているため、PORTAと0x04=0b00000100の論理積を取るとRA2の状態のみが分かります。
スイッチが押されていない状態、つまりRA2に"1"が入力されている状態ではPORTA = 0b00000100となります。ここで0x04と論理積を取ってみます。

PORTA 0000 0100
0x04  0000 0100
-----------------
      0000 0100

逆にスイッチが押されるとRA2が0になるため演算結果は以下のようになります。

PORTA 0000 0000
0x04  0000 0100
-----------------
      0000 0000

つまり論理積を取った結果が0なのかそうでないかを判定すればRA2のスイッチが押されたかどうかが分かるというわけです。

"if((PORTA & 0x04) != 0)"で0でなかった場合、すなわちスイッチが押されていない状態の時に実行される文はPORTBに0を出力するようなものとし、1だった場合、RB0に1を出力するような処理を書けばOKです。


以下がプログラムの全体像です。

void main() {
     OSCCON = 0x70;
     ANSEL = 0x00;
     TRISA = 0x04;
     TRISB = 0x00;
     PORTA = 0x00;
     PORTB = 0x00;

     while(1) {
          if((PORTA & 0x04) != 0) {
               PORTB = 0x00;
          } else {
               PORTB = 0x01;
          }
    }
}

このように記述することで、スイッチを押したときにLEDが光るということが実現できます。

  • 近日中

目次