一、原理圖
二、獨立按鍵電路分析
J5跳帽接23,即BTN,實作獨立按鍵功能。
當獨立按鍵中有鍵按下時,P30~P33中對應的IO口變為低電平0,即可确認是哪個按鍵按下。
三、代碼實作
狀态機消抖
每隔10ms調用該函數,配合定時器使用。
#define KEY P3
#define key_state_0 0 //判斷按鍵是否按下
#define key_state_1 1 //判斷按鍵是否抖動
#define key_state_2 2 //判斷按鍵是否釋放
狀态機消抖
unsigned char scan_key()
{
static char key_state=0;//狀态值
unsigned char key_return=0;//傳回值
unsigned char key_press;//鍵值
key_press=KEY&0x0f;//屏蔽高四位
switch (key_state)
{
case key_state_0:
if (key_press!=0x0f)
key_state=key_state_1;
break;
case key_state_1:
if (key_press!=0x0f)
{
switch (key_press)
{
case 0x07:
key_return=4;break;//S4
case 0x0b:
key_return=5;break;//S5
case 0x0d:
key_return=6;break;//S6
case 0x0e:
key_return=7;break;//S7
}
key_state=key_state_2;
}
else
key_state=key_state_0;
break;
case key_state_2:
if (key_press==0x0f)
key_state=key_state_0;
break;
}
return key_return;
}
三行代碼
每隔10ms調用該函數,配合定時器使用。
#define KEY P3
unsigned char Trg;//判斷哪個按鍵按下
unsigned char Cont;//判斷按鍵是否釋放
//三行代碼
void scan_key()
{
unsigned char ReadData=KEY^0xff;//^異或 相同為0 不同為1
Trg=ReadData&(ReadData^Cont);
Cont=ReadData;
}
四個獨立按鍵按鍵數字顯示在數位管上 狀态機消抖 定時器中斷實作
#include <STC15F2K60S2.h>
#define KEY P3
#define key_state_0 0 //判斷按鍵是否按下
#define key_state_1 1 //判斷按鍵是否抖動
#define key_state_2 2 //判斷按鍵是否釋放
unsigned char scan_key();//按鍵掃描函數
void display();//顯示函數
void Timer0Init(void);//定時器
code unsigned char tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf,0xff};//共陽數位管段碼
unsigned char dspbuf[8]={11,11,11,11,11,11,11,0};//顯示緩沖區
unsigned char dspcom=0;
unsigned char key_flag;//消抖标志
//主函數
void main()
{
unsigned char x;
Timer0Init();
EA=1;
ET0=1;
while(1)
{
if (key_flag==1)
{
key_flag=0;
x=scan_key();
if (x==4)
dspbuf[7]=x;
if (x==5)
dspbuf[7]=x;
if (x==6)
dspbuf[7]=x;
if (x==7)
dspbuf[7]=x;
}
}
}
//定時器
void Timer0Init(void) //1毫秒@11.0592MHz
{
AUXR |= 0x80; //定時器時鐘1T模式
TMOD &= 0xF0; //設定定時器模式
TL0 = 0xCD; //設定定時初值
TH0 = 0xD4; //設定定時初值
TF0 = 0; //清除TF0标志
TR0 = 1; //定時器0開始計時
}
//中斷服務函數
void isr_timer_0() interrupt 1
{
static unsigned char count=0;
count++;
if (count==10)//10ms
{
count=0;
key_flag=1;
}
display();
}
//按鍵掃描函數
unsigned char scan_key()
{
static char key_state=0;//狀态值
unsigned char key_return=0;//傳回值
unsigned char key_press;//鍵值
key_press=KEY&0x0f;//屏蔽高四位
switch (key_state)
{
case key_state_0:
if (key_press!=0x0f)
key_state=key_state_1;
break;
case key_state_1:
if (key_press!=0x0f)
{
switch (key_press)
{
case 0x07:
key_return=4;break;//S4
case 0x0b:
key_return=5;break;//S5
case 0x0d:
key_return=6;break;//S6
case 0x0e:
key_return=7;break;//S7
}
key_state=key_state_2;
}
else
key_state=key_state_0;
break;
case key_state_2:
if (key_press==0x0f)
key_state=key_state_0;
break;
}
return key_return;
}
//顯示函數
void display()
{
//消隐
P2=((P2&0x1f)|0xe0);
P0=0xff;
P2&=0x1f;
//位選
P2=((P2&0x1f)|0xc0);
P0=(1<<dspcom);
P2&=0x1f;
//段選
P2=((P2&0x1f)|0xe0);
P0=tab[dspbuf[dspcom]];
P2&=0x1f;
if (++dspcom==8)
dspcom=0;
}
四個獨立按鍵按鍵數字顯示在數位管上 三行代碼法 定時器中斷實作
#include <STC15F2K60S2.h>
#define KEY P3
void scan_key();//按鍵掃描函數
void display();//顯示函數
void Timer0Init(void);//定時器
code unsigned char tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xbf,0xff};//共陽數位管段碼
unsigned char dspbuf[8]={11,11,11,11,11,11,11,0};//顯示緩沖區
unsigned char dspcom=0;
unsigned char key_flag;//消抖标志
unsigned char Trg;//判斷哪個按鍵按下
unsigned char Cont;//判斷按鍵是否釋放
//主函數
void main()
{
Timer0Init();
EA=1;
ET0=1;
while(1)
{
if (key_flag==1)
{
key_flag=0;
scan_key();
if (Trg&0x08)
dspbuf[7]=4;//S4
if (Trg&0x04)
dspbuf[7]=5;//S5
if (Trg&0x02)
dspbuf[7]=6;//S6
if (Trg&0x01)
dspbuf[7]=7;//S7
}
}
}
//定時器
void Timer0Init(void) //1毫秒@11.0592MHz
{
AUXR |= 0x80; //定時器時鐘1T模式
TMOD &= 0xF0; //設定定時器模式
TL0 = 0xCD; //設定定時初值
TH0 = 0xD4; //設定定時初值
TF0 = 0; //清除TF0标志
TR0 = 1; //定時器0開始計時
}
//中斷服務函數
void isr_timer_0() interrupt 1
{
static unsigned char count=0;
count++;
if (count==10)//10ms
{
count=0;
key_flag=1;
}
display();
}
//三行代碼
void scan_key()
{
unsigned char ReadData=KEY^0xff;
Trg=ReadData&(ReadData^Cont);
Cont=ReadData;
}
//顯示函數
void display()
{
//消隐
P2=((P2&0x1f)|0xe0);
P0=0xff;
P2&=0x1f;
//位選
P2=((P2&0x1f)|0xc0);
P0=(1<<dspcom);
P2&=0x1f;
//段選
P2=((P2&0x1f)|0xe0);
P0=tab[dspbuf[dspcom]];
P2&=0x1f;
if (++dspcom==8)
dspcom=0;
}