实验原理:
按键包含四个管脚,初始13、24导通,而12、34不导通,当按键按下时12、34导通,类似于开关的结构。按键未按下时电压信号为高电平,当按键按下时电压信号为低电平。
由于机械开关的的按动会出现“抖动”(一般5-10ms),导致电压信号和理想信号不一致(如下图)。“抖动”可能导致电压信号被多次触发,可以设计硬件消除(会增加成本,如接入电容),或者软件消除(延时函数避开抖动区间)。
实验电路:
当按键按下时,管脚得到低电平(输入0),将K1-8分别关联LED1-8,当该按键所接的IO口收到低电平信号时,对应LED灯输出值取反(点亮/熄灭)。
完整代码:
#include "reg52.h"
typedef unsigned char u8;
typedef unsigned int u16;
void delay_10us(u16 ten_us); //延时函数
u8 key_scan(u8 mode); //读取函数
sbit KEY1=P0^0;
sbit KEY2=P0^1;
sbit KEY3=P0^2;
sbit KEY4=P0^3;
sbit KEY5=P0^4;
sbit KEY6=P0^5;
sbit KEY7=P0^6;
sbit KEY8=P0^7;
sbit LED1=P1^0;
sbit LED2=P1^1;
sbit LED3=P1^2;
sbit LED4=P1^3;
sbit LED5=P1^4;
sbit LED6=P1^5;
sbit LED7=P1^6;
sbit LED8=P1^7;
#define KEY1_PRESS 1
#define KEY2_PRESS 2
#define KEY3_PRESS 3
#define KEY4_PRESS 4
#define KEY5_PRESS 5
#define KEY6_PRESS 6
#define KEY7_PRESS 7
#define KEY8_PRESS 8
#define KEY_UNPRESS 0
void main()
{
u8 key=0;
while(1){
key=key_scan(1);
if(key==KEY1_PRESS)
LED1=!LED1;
else if(key==KEY2_PRESS)
LED2=!LED2;
else if(key==KEY3_PRESS)
LED3=!LED3;
else if(key==KEY4_PRESS)
LED4=!LED4;
else if(key==KEY5_PRESS)
LED5=!LED5;
else if(key==KEY6_PRESS)
LED6=!LED6;
else if(key==KEY7_PRESS)
LED7=!LED7;
else if(key==KEY8_PRESS)
LED8=!LED8;
}
}
u8 key_scan(u8 mode) //加入形参mode调整单次扫描/连续扫描模式
{
static u8 key=1;
if(mode)
key=1;
if(key=1&&(KEY1==0||KEY2==0||KEY3==0||KEY4==0||KEY5==0||KEY6==0||KEY7==0||KEY8==0))
{
delay_10us(1000); //消抖
key=0;
if(KEY1==0)
return KEY1_PRESS;
else if(KEY2==0)
return KEY2_PRESS;
else if(KEY3==0)
return KEY3_PRESS;
else if(KEY4==0)
return KEY4_PRESS;
else if(KEY5==0)
return KEY5_PRESS;
else if(KEY6==0)
return KEY6_PRESS;
else if(KEY7==0)
return KEY7_PRESS;
else if(KEY8==0)
return KEY8_PRESS;
}else if(KEY1==1&&KEY2==1&&KEY3==1&&KEY4==1&&KEY5==1&&KEY6==1&&KEY7==1&&KEY8==1)
{
key=1;
}
return KEY_UNPRESS;
}
void delay_10us(u16 ten_us)
{
while(ten_us--);
}
实验结果:
按下独立按键后,对应LED灯亮起,但有时亮起后松按键即熄灭,有时亮起时按下按键LED灯亮度降低,松按键后恢复原亮度,多次调试后未查明原因。
使用教程提供的代码(仅控制2个LED灯)实验结果如预期,按下后对应灯亮起,松开后保持亮度,再次按键对应灯熄灭。。
|