目次

スイッチの状態取得

 出力処理の次に、入力処理を扱います。

 PICのリセット回路は、どちらかを使うことを説明しています。



 右の回路は、スイッチを押さなければ、常に'L'レベルを与えるので
 リセット状態をキープするようになります。
 ただし、RA5ピンをリセットとして使う場合です。

 RA5ピンを入出力ピンで使うように指定すると、デジタルの論理値を
 扱えるようになります。

 左の回路では、スイッチを押すとリセットがかかります。
 ただし、RA5ピンをリセットとして使う場合です。

 どちらにするかは、PICに与える制御ワードで指定できますが
 リセット機能をもったピンは、リセットで使うべきでしょう。

 よく使われる回路は、左側の方です。

 スイッチ状態を、LEDに反映する接続は、以下。



 ポートBの0ビットを出力、1ビットを入力にするために
 I/Oの設定は、以下。

 入出力方向を考える必要のないピンを入力にすると、入出力方向
 設定のコードは、次のようになります。

 TRISB = 0xfe ;

 LEDは、RB0ピンに'1'を設定すると点灯する、正論理です。

 スイッチは押さないと、RB1ピンに'0'が入力されます。
 スイッチを押すと、RB1ピンに'1'が入力されます。

 RB1ピンの状態を反転して、RB0に出力するとうまくいきます。

  PORTB.F0 = ~PORTB.F1 ;

 ビット反転に、「~」を使います。
 全体では、次のコードとします。

#define OFF 0
#define ON  OFF+1

/* prototype */
void usr_init(void);

void main(void)
{
  /* initialize PORT */
  usr_init();
  /* endless loop */
  while (ON) {
    PORTB.F0 = ~PORTB.F1 ;
  }
}

void usr_init(void)
{
  /* initial value */
  PORTB.F0 = OFF ;
  /* direction */
  TRISB = 0xfe ;
}

 2つのスイッチを用意しておき、LEDの点灯と消灯を制御します。
 スタート、ストップと役割を持たせてみます。



 RB1、RB2を入力で利用するので、入出力の設定は、そのまま。

 スイッチには、チャタリングがあるので、時間をおいて
 スイッチの状態を2回あるいは3回入力して、1が続くと
 有効と判断して、LEDの点灯状態を変更します。

 LEDの点灯状態を変えたいので、状態変数stateを用意して
 次のシーケンスで、LEDの点灯消灯を制御します。

  PORTB.F0 = state & ON ;

 STARTスイッチを押して'1'のときは、状態変数stateをONにします。
 STOPスイッチを押して'1'のときは、状態変数stateをOFFにします。

 2回時間差をおいて、2ビットのスイッチ状態を読込んで
 各ビットの状態を調べて、状態変数stateに反映させます。

 動作フローは、以下とすればよいでしょう。



 チャタリングは、10msから50msほど続くと言われているので
 50msの時間差をおいて、2度読みしました。

 動作フローをプログラムにします。

#define OFF 0
#define ON  OFF+1

typedef unsigned char UBYTE ;

volatile UBYTE state ;
volatile UBYTE btn1 ;
volatile UBYTE btn2 ;

/* prototype */
void usr_init(void);

void main(void)
{
  /* initialize PORT */
  usr_init();
  /* endless loop */
  while (ON) {
    /* get first time state */
    btn1 = PORTB.F1 ;
    btn2 = PORTB.F2 ;
    /* delay */
    Delay_ms(50) ;
    /* judge */
    if ( btn1 == ON && PORTB.F1 == ON ) { state = ON ; }
    if ( btn2 == ON && PORTB.F2 == ON ) { state = OFF; }
    /* impress */
   PORTB.F0 = state & ON ;
  }
}

void usr_init(void)
{
  /* turn off LED */
  PORTB.F0 = OFF ;
  /* direction */
  TRISB = 0xfe ;
  /* set first state */
  state = OFF ;
}

 スイッチ処理は、タイマー割込みとシフトレジスタを使うと
 もっと綺麗に扱うことができます。次のページで説明します。


目次

inserted by FC2 system