一、独立按键
当按键按下时,IO口的电平会被拉低,即被置0,当检测到IO口为0时即可判断按键已经按下。
按键按下时会有一个抖动的过程(弹片会抖动),由于单片机检测IO口速度特别快,超过弹片抖动的频率,所以当单片机检测到IO口为0需要延时一小段时间再检测IO口是否为0,如果仍为0,则按键按下。
因为IO口里面有上拉电阻,所以松开按键时,IO口又被拉高。
可通过软件或者硬件电路进行消抖
#include "reg52.h"
typedef unsigned char u8;
typedef unsigned int u16;
sbit led1 = P2^0;
sbit k1 = P3^1;
void delay(u16 i)
{
while(i--);
}
void keyset()
{
if(k1 == 0){ //判断按键是否按下去
delay(1000); //进行消抖
if(k1 == 0){ //再次判断
led1 =~led1;
}
while(!k1);
}
}
void main()
{
while(1){
keyset();
}
}
二、矩阵按键
以行列扫描为例:
#include "reg52.h"
typedef unsigned char u8;
typedef unsigned int u16;
sbit LSA=P2^2;
sbit LSB=P2^3;
sbit LSC=P2^4;
#define GPIO_KEY P1
#define GPIO_DIG P0
u8 keyValue;
u8 code word[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07, //code使其保存在单片机ROM中
0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
void delay(u16 i)
{
while(i--);
}
void Keyset()
{
char a = 0;
GPIO_KEY = 0x0f; //高四位输出低电平,低四位输出高电平
if(GPIO_KEY != 0x0f){
delay(1000); //消抖
if(GPIO_KEY != 0x0f){
GPIO_KEY = 0x0f;
switch(GPIO_KEY){ //进行列判断
case 0x07:
keyValue = 0;
break;
case 0x0b:
keyValue = 1;
break;
case 0x0d:
keyValue = 2;
break;
case 0x0e:
keyValue = 3;
break;
}
GPIO_KEY = 0xf0; // 高四位输出高电平,低四位输出低电平
switch(GPIO_KEY){ //进行行判断
case 0x70:
keyValue = keyValue;
break;
case 0xb0:
keyValue = keyValue + 4;
break;
case 0xd0:
keyValue = keyValue + 8;
break;
case 0xe0:
keyValue = keyValue + 12;
break;
}
//当a为50时,会强制退出
while( a<50 && GPIO_KEY != 0xf0 ){ //当按键松开时,会退出
delay(1000);
a++;
}
}
}
}
void main()
{
//确定数码管位选
LSA = 0;
LSB = 0;
LSC = 1;
P0 = word[15];
while(1){
Keyset();
//通过数码管显示按键的编号
GPIO_DIG = word[keyValue];
}
}