ステップ6

チャタリング防止2進カウンタ

 チャタリング防止プログラムを作り、スイッチの回数をLEDでカウントするプログラムを作ってみよう。

チャタリングとは?

 チャタリングとは、スイッチを1回押すと、複数回スイッチを押したことになる現象のことです。このチャタリングをプログラムでこれから解決していきます。

チャタリング防止2進カウンタ回路図

■スイッチの読み取り

^ :排他的論理和をすることによってスイッチの変化したところだけ1がたつ
& :ビット積をすることによって1が立っているところだけそのまま通すことができる。

 xxxx xxxx
×0000 1111
----------
 0000 xxxx

 if (w & 0x01 == 1)は 下位1びっとだけ取り出してそれが1だったら処理をする

●main.c

#include "iodefine.h"
#include "intrinsics.h"

#ifdef CPPAPP
//Initialize global constructors
extern "C" void __main()
{
  static int initialized;
  if (! initialized)
    {
      typedef void (*pfunc) ();
      extern pfunc __ctors[];
      extern pfunc __ctors_end[];
      pfunc *p;

      initialized = 1;
      for (p = __ctors_end; p > __ctors; )
	(*--p) ();

    }
}
#endif 

unsigned char	sw_prev;  // SWの直前のOn/Off状態
unsigned char	scan_cnt; // 入力スキャン用カウンタ
unsigned char	count;      // カウンタ


void initIO(void){
	P1.DDR = 0xff;
	P2.DDR = 0x0f;
	P3.DDR = 0xff;
	P4.DDR = 0xff;
	P5.DDR = 0xff;
	P6.DDR = 0xf0;
	P8.DDR = 0xff;
	P9.DDR = 0xff;
	PA.DDR = 0xff;
	PB.DDR = 0xff;

	P2.PCR.BYTE = 0xf0; // Pull Up Enable
	sw_prev  = 0x0f & (P2.DR.BYTE >> 4);
	scan_cnt = 0;
	count = 0;
}

void initITU(void){
	set_imask_ccr(1);		// 割込み禁止
	ITU0.TCR.BIT.CCLR = 1;	// GRAコンペアマッチ-->TCNTクリア
	ITU0.TCR.BIT.CKEG = 0;	// 立ち上がりエッジでカウント
	ITU0.TCR.BIT.TPSC = 3;	// φ/8(分周比)
	ITU0.TCNT = 0;
	ITU0.GRA = 15624;		// 1/200秒でコンペアマッチ
	ITU0.TSR.BIT.IMFA = 0;	// フラグクリア
	ITU0.TIER.BYTE = 1;		// コンペアマッチA-->割込み
	ITU.TSTR.BYTE = 1;		// ITU0 START
	set_imask_ccr(0);		// 割込み許可
}

int main(void)
{
	initIO();
	P1.DR.BYTE = ~count;
	initITU();

    while (1) {
    }
    return 0;
}

/*
 * タクトスイッチの状態をスキャンし、
 * 押されたスイッチに対応する処理を行う。
 */
void scan_sw(void){
	unsigned char sw, w;

	sw = 0x0f & (P2.DR.BYTE >> 4); // スイッチの状態をスキャン
	w = (sw_prev ^ sw) & ~sw;      // 押されたスイッチを 1

	if (w & 0x01)
		count++;

	if (w & 0x02)
		count--;

	if (w & 0x04)
		count = 0;

	sw_prev = sw;                  // 直前の状態を保存
}

/*
 * チャタリング防止
 * 5ミリ秒間隔でコールされる。
 */
void onTimer(void){
	scan_cnt++;
	if (scan_cnt >= 10){
		// 50ミリ秒毎にスキャン
		scan_cnt = 0;
		scan_sw();
	}
	P1.DR.BYTE = ~count;
}

 今回5ミリ秒ごとにスイッチの状態を読み取りをすることでチャタリングを防止するように設定しています。

●inthandler.c

#include "inthandler.h"
#include "iodefine.h"

void INT_IMIA0(void) {
	ITU0.TSR.BIT.IMFA = 0; // フラグクリア
	onTimer();
}

チャタリング防止2進カウンタ回路完成写真

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です