キーがデバウンスするのはなぜですか?

回路図分析

キーダイアグラム

回路図によれば、ボタンが押されていない場合、シングルチップピンBTN1は、高レベルの10K抵抗を介してVCCに接続されます。ボタンが押された場合、BTN1は、低レベルの10K抵抗を介して接地されます。 10K抵抗は電流制限として機能し、一般的なプログラム電流制限抵抗として機能します。理想的には、ボタンが押されていないときは高レベルで、押されているとき1は低レベルです0が、実際には、機械的ジッタのために、実際に生成された波形は次のようになります。

押したときの波形

信号の機械的ジッタにより、信号1との0何度もジャンプし、一般的なジッタ時間は5〜10ミリ秒です。シングルチップマイコンの処理速度は非常に速く、処理しないとキーを複数回押した後にプログラムが動作し、論理エラーとなります。たとえば、ライトを押してオンにしてからもう一度押してオフにすると、デバウンスを行わないと、1回の押しで複数の処理が発生し、ライトのスイッチの状態が変化しない場合があります。

ぶれ軽減を実現

シンプルなアンチシェイクの方法は、ボタンが押されたことを検出し、10ミリ秒待ってから、押された状態かどうかを確認します。押された状態の場合は、押された状態であると判断します。擬似コードは次のとおりです。

if (key == 0) {			//检测到按键按下
	DelayMs(10);		//等待10个毫秒
	if (key == 0) {		//按键仍然保持在按下的状态
		led = !led;		//切换LED的开关状态
		while (key == 0);	//等待松手
	}
}

プログラムを書いてテストする

#include <ioCC2530.h> 

#define LED1   P1_0     //定义LED1所在引脚
#define KEY1   P0_1     //定义BTN1所在引脚

void DelayMs(int ms)
{
    while (ms--) {
        volatile int x = 500;//注意:这个数字是估计的,不准确
        while (x--);
    }
}

void main(void)
{
    //配置P0_1引脚的按键1 
    P0SEL &= ~0x02; //普通GPIO模式<0为IO模式,1为外设模式>
    P0DIR &= ~0x02; //输入功能<0为输入,1为输出>
    P0INP &= ~0x02; //上拉或下拉模式<0为上拉或下拉模式,1为三态模式>

    //配置P1_0引脚的LED1
    P1SEL &= ~0x01; //普通GPIO模式<0为IO模式,1为外设模式>
    P1DIR |= 0x01;  //输出功能<0为输入,1为输出>
    P1INP &= ~0x01; //上拉或下拉模式<0为上拉或下拉模式,1为三态模式>
    
    P2INP |= 0xe0;  //P0,P1,P2都设置为上拉模式
    
    while (1)
    {
        if (0 == KEY1) {
            DelayMs(10);
            if (0 == KEY1) {
                LED1 = !LED1;
                while (0 == KEY1);
            }
        } 
    }
}

注意が必要な事項

上記の方法がより一般的に使用されますが、次の問題があります。

  • ユーザーが押し続けると、リリース待ちの位置でプログラムが停止します。
  • 10ms待機している間、プログラムは何もできず、プロセッサのパフォーマンスを浪費します。

次の記事では、より信頼性の高いキー検出方法を紹介します。

おすすめ

転載: www.cnblogs.com/iotplus/p/12687588.html