標(biāo)題:
51單片機(jī)按鍵消抖方式總結(jié)
[打印本頁(yè)]
作者:
xinzhi1992
時(shí)間:
2021-8-20 16:39
標(biāo)題:
51單片機(jī)按鍵消抖方式總結(jié)
電路圖如下:
MCU采用89C52單片機(jī),晶振12MHZ。
1.png
(56.62 KB, 下載次數(shù): 182)
下載附件
2021-8-20 17:11 上傳
1、沒(méi)有消除抖動(dòng)的原始代碼:
#include <REGX52.H>
#include <intrins.h>
sbit KeyValue=P3^7;
unsigned char code segment[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
//定義數(shù)碼管顯示0~9
void main(){
static char count=1;
P2=segment[0]; //開始運(yùn)行顯示0
while(1){
if(KeyValue==0){
P2=segment[count];
count++;
if(count>=10){ //超過(guò)0~9,數(shù)碼管顯示回到0
count=0;
}
}
}
}
復(fù)制代碼
2、延時(shí)消除抖動(dòng)
存在如下缺點(diǎn):
delay()延時(shí)函數(shù)會(huì)占用大量時(shí)間;
需要while循環(huán)不斷的掃描按鍵,對(duì)單片機(jī)運(yùn)算資源的浪費(fèi)。
#include <REGX52.H>
#include <intrins.h>
sbit KeyValue=P3^7;
unsigned char code segment[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
void delay(){ //延時(shí)程序
unsigned int i=20500;
while(i--);
}
void main(){
static char count=1;
P2=segment[0];
while(1){
if(KeyValue==0){//按鍵按下
delay();//延時(shí)一段時(shí)間
if(KeyValue==0){//重新判斷按鍵狀態(tài)
P2=segment[count];
count++;
if(count>=10){
count=0;
}
}
}
}
}
復(fù)制代碼
3、使用定時(shí)器消抖
原理說(shuō)明:1次按下+1次抬起構(gòu)成一個(gè)按鍵動(dòng)作,當(dāng)同時(shí)檢測(cè)到這兩個(gè)動(dòng)作時(shí),才完成一次按鍵操作。按下時(shí),將按鍵值存儲(chǔ)為0;抬起時(shí),將按鍵值存儲(chǔ)為1。在前一次的按鍵值為0的前提下,檢測(cè)當(dāng)前按鍵值是否為1,如果為1,表示此次按鍵有效,否則此次按鍵無(wú)效。
缺點(diǎn):會(huì)占用一個(gè)定時(shí)
#include <REGX52.H>
#include <intrins.h>
sbit KeyValue=P3^7;
bit KeyStatus=1;
unsigned char code segment[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
void main(){
bit KeySave=1;
unsigned char count=0;
P2=segment[0];
/**************開啟中斷**************************/
EA=1;
TMOD=0x01;
TH0=0xF8;
TL0=0xCD;
ET0=1;
TR0=1;
while(1){
if(KeyStatus!=KeySave){//檢測(cè)按鍵值是否改變,初始時(shí)按鍵值為1,在此檢測(cè)按鍵值是否變?yōu)?,為0則繼續(xù)
if(KeySave==0){//如果前一次的按鍵值為0,說(shuō)明本次按鍵抬起,本次按鍵有效;否則為按鍵按下操作,跳轉(zhuǎn)到最后一步,將按鍵值取反
count++;//對(duì)按鍵值+1
if (count>=10){
count=0;
}
P2=segment[count];
}
KeySave=~KeySave;
}
}
}
void InterruptTimer0() interrupt 1 {
static unsigned KeyBuff=0xff;
TH0=0xF8;
TL0=0xCD;
KeyBuff=(KeyBuff<<1)|KeyValue;
switch(KeyBuff){
case 0xff:
KeyStatus=1;
break;
case 0x00:
KeyStatus=0;
break;
default:
break;
}
}
復(fù)制代碼
作者:
op5726170
時(shí)間:
2021-8-25 20:05
還可以搞兩個(gè)for嵌套循環(huán)! 最外層記錄按了多少次,用來(lái)處理多次連續(xù)按鍵。內(nèi)層在規(guī)定時(shí)間內(nèi)有按鍵動(dòng)作記為真,超過(guò)規(guī)定時(shí)間記為假,這樣可以高效消抖
作者:
炒菜
時(shí)間:
2021-9-9 09:51
我記的網(wǎng)上有人利用標(biāo)志位進(jìn)行消抖,用延時(shí)的話有點(diǎn)困難
作者:
herui2128
時(shí)間:
2021-9-9 14:47
一般來(lái)說(shuō)都是延時(shí)5MS,小程序上用不了多少
作者:
dyx811
時(shí)間:
2021-9-11 19:27
原理分析到位!多謝分享
作者:
我會(huì)想你的
時(shí)間:
2021-9-30 10:42
其實(shí)這個(gè)就是狀態(tài)機(jī)
作者:
DZY11
時(shí)間:
2021-10-4 15:45
挺好的啊,我自己也是這樣使用的
作者:
Su丿nice
時(shí)間:
2021-10-5 07:10
這樣很難嗎?
if(K5 == 0)
{
DelayM(20); q = ~q; //標(biāo)志位取反
if(q){kai_numl = kai_numl | 1;}
else { kai_numl = kai_numl&0;}
if(q){BLK = BLK | 1;}
else {BLK= BLK & 0;}
while(K5 == 0);
}
作者:
mxdkey
時(shí)間:
2021-10-9 17:04
主意不錯(cuò),站位留存一下!
作者:
一giao我里giao
時(shí)間:
2021-10-11 16:55
if(!key)
while(1)
{
//如果有顯示程序?qū)懸槐樵谶@里
if(key)
{
//按鍵要實(shí)現(xiàn)的功能
break;
}
}
這樣寫只能按一次實(shí)現(xiàn)一次
歡迎光臨 (http://www.torrancerestoration.com/bbs/)
Powered by Discuz! X3.1