按键检测
说明
以理论来说是不需要按键检测的,按一下就执行一次。但是实际却不是这样,在你按下的瞬间间会出现大概10MS电平在上下乱跳,松开也是同理,这是因为你按下和松开的瞬间是有抖动的,人感觉不出来,但是机器却可以,因此我们在做按钮时需要进行消抖。下面一点亮一盏灯为例。
方法
1.等待按键释放
程序卡在一个地方,没办法运行,只能先执行此处;
#include<reg52.h>
sbit d1=P1^0;
sbit dula=P2^6;
sbit wela=P2^7;
sbit key1=P3^4;
void main()
{
P3=0xff;
while(1)
{
while(!key1)//平时不执行,按下去卡着
{
d1=~d1;//LED灯翻转
}
}
}
2.10ms检测一次
利用定时器计时,每10ms检测按键有无按下。下降沿触发。
#include <stc12c5a60s2>
#define uint unsigned int
#define uchar unsigned char
uchar code table[]={
0xc0,0xf9,0xa4,0xb0,
0x99,0x92,0x83,0xf8,
0x80,0x98};//code编码表
sbit key1=P3^4;
sbit S1=P1^0;
uchar key1_1,key1_2,num,f,m,p;//定义前一状态和现有状态
void Timer0Init();//声明定时器0初始化
void main()
{
num=0;//显示值
S1=0;//第一个数码管
Timer0Init();//定时器0开启初始化
EA=1; //开总中断
while(1)
{
if(m-p>10) //按键检测
{
p=m;//10ms记一次
key1_2=key1_1; //按键前一个状态
key1_1=key1; //按键现在的状态
}
if((key1_2==1)&&(key1_1==0))//检测到下降沿触发
{
if(f==1)//标志位在10ms内只执行一次
{
num++; //数码管+1
if(num==10) //数码管显示到10清零
num=0;
f=0; //标志位置0,使让在符合条件时,只执行一次
}
}
else
f=1; //恢复标志位
P0=table[num]; //数码管显示
}
}
void Timer0Init(void) //100微秒秒@11.0592MHz
{
TMOD= 0x01; //设定定时器0为工作方式1
TL0 = 0xAE; //设置定时初值
TH0 = 0xFB; //设置定时初值
ET0 = 1; //开定时器0中断
TR0 = 1; //定时器0开始计时
}
void t0_1ms() interrupt 1//表示它是中断服务子程序
{
TL0 = 0xAE; //设置定时初值
TH0 = 0xFB; //高八位初值
m++;
}
3.外部中断触发
虽然要机器停顿10ms,但是只会在按钮触发时出现,去检测按键,平时不会执行
#include <stc12c5a60s2>
#define uint unsigned int
#define uchar unsigned char
uchar code table[]={
0xc0,0xf9,0xa4,0xb0,
0x99,0x92,0x83,0xf8,
0x80,0x98};//code编码表
sbit key1=P3^2; //外部中断0
sbit S1=P1^0;
uchar f,num;
void Delay10ms();
void main()
{
IT0=1;//定义外部中断0为跳变触发
EA=1;//开启总中断
EX0=1;//开启外部中断0
S1=0;//开启数码管第一位
while(1)
{
P0=table[num];
}
}
void s0() interrupt 0
{
if(key1==0) //判断是否按下键盘
{
Delay10ms(); //延时,软件去干扰
if(key1==0) //确认按键按下
num++;
}
if(num==10)//大于10清零
num=0;
}
void Delay10ms() //@11.0592MHz
{
unsigned char i, j;
i = 108;
j = 145;
do
{
while (--j);
} while (--i);
}
4.Delay延时检测
最好少用,增加程序运行时间
#include<stc12c5a60s2>
#define uchar unsigned char
#define uint unsigned int
uchar code table[]={
0xc0,0xf9,0xa4,0xb0,
0x99,0x92,0x83,0xf8,
0x80,0x98};//code编码表
sbit key1=P3^2;
sbit S1=P1^0;
uchar f,num;
void main()
{
S1=0;//开启数码管第一位
while(1)
{
if(key1==0) //判断是否按下键盘
{
Delay10ms(); //延时,软件去干扰
if(key1==0) //确认按键按下
num++;
}
if(num==10)//大于10清零
num=0;
P0=table[num];
}
}
void Delay10ms() //@11.0592MHz
{
unsigned char i, j;
i = 108;
j = 145;
do
{
while (--j);
} while (--i);
}