写在前面
上次写了一篇采用状态机来检测矩阵键盘的博文,今天用实体板子来做的时候发现单按键检测的写法与状态机略有不同,这里也顺带贴出来以备自己以后不时之需,同时供给大家参照。
代码如下:
#include <reg52.h>
typedef unsigned char uint8;
typedef unsigned int uint16;
#define key_state0 0 //初始状态
#define key_state1 1 //按键按下
#define key_state2 2 //按键是否释放
sbit key_s1 = P3^2;
sbit key_s2 = P3^3;
sbit key_s3 = P3^4;
uint8 seconds,flag;
code uint8 num[]={0xc0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};
code uint8 seg[]={0xFE,0xFD,0xFB,0xF7};
void delay(uchar k){
unsigned char i,j;
for(i=k;i>0;i--){
for(j=110;j>0;j--);
}
}
void timer_init(){
EA = 0;
TR0 = 0;
TMOD = 0x01;
TH0 = 0xDC; //10ms
TL0 = 0x00;
ET0 = 1;
EA = 1;
TR0 = 0;
}
void timer0() interrupt 1 using 0{
TH0 = 0xDC;
TL0 = 0x00;
if(++flag >= 100){
flag = 0;
if(++seconds >= 100) seconds = 0;
}
}
void key_handle(){
static char key_state; //此处一定要用static定义,或定义到全局变量中
switch(key_state){
case key_state0:
if(!key_s1||!key_s2||!key_s3) key_state = key_state1;
break;
case key_state1:
if(!key_s1) {
TR0 = 1;
key_state = key_state2;
}
else if(!key_s2) {
TR0 = 0;
key_state = key_state2;
}
else if(!key_s3) {
if(TR0 == 0) seconds = 0;
key_state = key_state2;
}
else{
key_state = key_state0;
}
break;
case key_state2:
if(key_s1 && key_s2 && key_s3) { //全部键都松开后才回状态0
key_state = key_state0;
}
break;
}
}
void display(){
P2 = 0xff;
P0 = num[seconds/10];
P2 = seg[0];
delay(10);
P2 = 0xff;
P0 = num[seconds%10];
P2 = seg[1];
delay(10);
}
void main(){
timer_init();
while(1){
key_handle();
display();
}
}
电路图如下:
只用到了P3.2/3/4这三个按键口线以及P2.1/2/3/4四个数码管位选口和P0的8个段选口。