はじめに

ここでは3つのタクトスイッチの状態に応じてLEDの点灯・消灯をするプログラムを作成します.前提として,すでにLEDを制御するプログラムが完成していることがあります.もしできていない場合にはこちらを参照してください.

  1. スイッチが接続されているマイコンの端子

    下の図はすっちが接続されているマイコンの端子を中心に表示した回路図です.緑色のタクトスイッチはポートBビット4,赤色のタクトスイッチはポートBビット3,青色のタクトスイッチはポートBビット1に接続されていることが分かります.これらの端子を入力端子にし,端子の状態(つまりHighかLowか)を読み取ればスイッチの様子が分かるようになっています.
    SW01

    スイッチ周りの回路図の一例を下に示します.この例は赤色タクトスイッチの回路図です.チャタリングを和らげるためにRC回路が入っています.この回路ではタクトスイッチを押すとLow,放すとHighがマイコンに伝えられます.
    SW02

    下の表にスイッチと端子をまとめておきました.
    スイッチの種類 端子
    緑色タクトスイッチ ポートBビット4
    赤色タクトスイッチ ポートBビット3
    青色タクトスイッチ ポートBビット1

  2. ファイルの作成

    まずは関係するファイルを作成しましょう.具体的にはTactSwitch.hとTactSwitch.cです.LEDの時と同様に作成してください.下の図のようになるはずです.
    SW05

    ヘッダファイルには次の関数のプロトタイプ宣言をしてください.
    1. void TactSwitch_initialize(void)
    2. bool TactSwitch_isPressedRedButton(void)
    3. bool TactSwitch_isPressedGreenButton(void)
    4. bool TactSwitch_isPressedBlueButton(void)
    LEDとは異なり,タクトスイッチの種類ごとに押されているか確認する関数を用意しました.戻り値はbool型のため,stdbool.hをインクルードしてある必要があります.下の図のようにヘッダを作りましょう.
    SW06
    #include <stdbool.h>
    
    extern void TactSwitch_initialize(void);
    extern bool TactSwitch_isPressedRedButton(void);
    extern bool TactSwitch_isPressedGreenButton(void);
    extern bool TactSwitch_isPressedBlueButton(void);
    
    次にソースファイルについてです.上記のプロトタイプ宣言をコピーし,externを削除するとともにセミコロンを{ }に置き換えます.後ほど関数の中身を実装していきます.定番のヘッダファイルもお忘れなく.
    SW07
    #include <stdbool.h>
    #include <stdint.h>
    #include <stdio.h>
    #include <xc.h>
    #include "TactSwitch.h"
    
    void TactSwitch_initialize(void){
    }
    bool TactSwitch_isPressedRedButton(void){
    }
    bool TactSwitch_isPressedGreenButton(void){
    }
    bool TactSwitch_isPressedBlueButton(void){
    }
    


  3. 初期化

    スイッチにつながった端子の初期化を行います.ここではLEDの時とは反対にTRISxyレジスタを1にすることで入力端子にします.それに加えて,今回用いる端子にはアナログ端子としての役割が備わってしまっているため,これを無効にしてディジタル端子にする必要があります.アナログ端子の機能の有無はデータシートを読むことになりますが,回路図からも実はわかるようになっています.下の図は先ほど示しましたタクトスイッチに関する回路図です.よく見ると「ANx」という機能が備わっていますね.これがアナログ端子として使える証拠です.PICでは,アナログ端子として設定できる端子を起動時にはアナログとして取り扱うこととなっています.従いまして,ディジタル端子として使用する場合には必ずその設定をしなければなりません.アナログ端子かディジタル端子かを設定するためのレジスタはANSxyです.このレジスタの値を0にすればディジタル,1にすればアナログ端子になります.ここでxにはポート名,yにはビットが入ります.例えば緑色のタクトスイッチが接続されているポートBビット4の端子をディジタル端子にするには,ANSB4=0とすればよいです.
    SW03
    以上の初期化をまとめると下の図のようになります.青色のオブジェクトノードはすべてレジスタです.
    SW04

    演習

    上のアクティビティ図をもとにTactSwitch_initialize関数を記述してください.
  4. 押されたか確認する関数

    押されたか確認するための関数である,TactSwitch_isPressedXXXButton関数を実装しましょう.XXXにはGreen,Red,Blueが入ります.さて,今回用いている回路では,スイッチが押されていたらLow,放されていたらHighとなります.回路を十分にわかっているのでしたらそれで問題ないのですが少しわかりづらいです.そこで,押されたときには_PRESSED(=0)というような定数を定義しておくとプログラムの可読性が高まります.下の図のように,インクルード分の後阿多rに定数として用意しておきましょう.
    SW09

    下の図はポートBビット4につながっている緑色のタクトスイッチが押されているか確認するための関数TactSwitch_isPressedGreenButton関数です.
    SW08
    もし押されていたらRB4レジスタが_PRESSEDである,というようなプログラムを作成すればよさそうです.いろいろな書き方があると思いますが,ここではこのようにしてみました.if文を使ったり,3項演算子を使ったりする方法もあるでしょう.
    SW10
        return (RB4 == _PRESSED);
    

    演習

    TactSwitch_isPressedRedButton,TactSwitch_isPressedBlueButton関数をそれぞれ実装してください.
  5. メイン関数での動作

    メイン関数では押されたスイッチに従ってLEDが点灯もしくは消灯するプログラムを書きましょう.下にプログラムの流れを表すアクティビティ図を示します.
    SW11

    演習

    上記のアクティビティ図をもとにmain関数を実装してください.なお,オシレータの設定とLCDの無効についてはそのままでお願いします.