概念
键盘分为编码键盘和非编码键盘(是否有编码器);非编码键盘分为独立键盘和行列式(矩阵式)键盘。
独立键盘检测
抖动现象(5~10ms),一般在检测按下时加入去抖延时,检测松手时不需。
目标:1、数码管前两位显示一个十进制数,变化范围00~59,开始时显示00,
2、每按下S2键一次,数值加1;每按下S3键一次,数值减1;每按下S4键一次,数值归零;
3、每按下S5键一次,利用定时器功能使数值开始自动每秒加1,再次按下S5键,数值暂停。
代码分析:(省略版)
#include "reg52.h"
#define uchar.....
sbit....
uchar code table[]={};
void display(uchar numdis){
shi=numdis/10;
ge=numdis%10;
} //显示子函数
void delayms(uint xms){} //延时子函数
void init(){ //初始化函数
//定时器初始化
TMOD = 0x01; //设置定时器0为工作方式1(M1M0为01)
TH0 = (65536-45872)/256; //装初值11.0592M晶振定时50ms数为45872
TL0 = (65536-45872)%256;
EA = 1; //开总中断
ET0 = 1; //开定时器0中断(通过 TR0 = 1;开启)
}
void keyscan(){ //按键扫描子函数
if(key1==0)
{
delayms(10); //消抖
if(key1==0)
{
num++;
if(num==60)
num=0;
while(!key1); //等待按键释放
}
}
if(key2==0){}
if(key3==0){}
if(key4==0){ while(!key4); TR0=~TR0;}
}
void main()
{
init();
while(1)
{
keyscan();
display(num);
}
}
void T0_time()interrupt 1
{
TH0 = (65536-45872)/256; //重装初值
TL0 = (65536-45872)%256;
numt0++;
if(numt0==20) //1秒时间到
{
numt0=0; //时间清零重计
num++; //每秒加1
if(num==60)
num=0;
}
}
矩阵键盘检测
目标:TX-1C:上电,数码管不显示,顺序按下矩阵键盘后,数码管上依次显示0~F,6个数码管同时静态显示即可
代码分析:(省略版)
void main()
{
P0=0; //关闭所有数码管段选
dula=1;
dula=0;
P0=0xc0; //位选中所有数码管(以后直接送段选信号)
wela=1;
wela=0;
while(1)
{
matrixkeyscan(); //不停调用键盘扫描程序
}
}
void display(uchar num)
{
P0=table[num]; //显示函数只送段选数据
dula=1;
dula=0;
}
void matrixkeyscan()
{
uchar temp,key;
P3=0xfe; //1111 1110 第一行线置低电平,其余为高电平
temp=P3; //P3状态赋给临时变量,用于计算
temp=temp&0xf0; //1111 0000 若temp高四位有0,则结果不为0xf0; 若无,则一直为0xf0
if(temp!=0xf0) //说明有键按下
{
delayms(10); //消抖
temp=P3; //重读
temp=temp&0xf0; //重&
if(temp!=0xf0) //说明确实有键按下
{
temp=P3; //再读一下P3状态(行列交叉)
switch(temp)
{
case 0xee: //1110 1110
key=0;
break;
case 0xde: //1101 1110
key=1;
break;
case 0xbe: //1011 1110
key=2;
break;
case 0x7e: //0111 1110
key=3;
break;
}
while(temp!=0xf0) //等待按键释放
{
temp=P3; //不断读取
temp=temp&0xf0; //不断相&,只要结果不为0xf0,就说明按键没有被释放
}
display(key); //显示
}
}
P3=0xfd; //1111 1101第二行置低电平,其余为高电平
。。。。。。。。。。。。。
P3=0xfb;
.......................
P3=0xf7;
.......................
}
switch(表达式)
{
case 常量表达式1:
语句1; //可多条语句
break;
case 常量表达式2:
语句2;
break;
case 常量表达式n:
语句n;
break;
default: //可无
语句n+1;
break;
}