回路図分析
回路図によれば、ボタンが押されていない場合、シングルチップピン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待機している間、プログラムは何もできず、プロセッサのパフォーマンスを浪費します。
次の記事では、より信頼性の高いキー検出方法を紹介します。