实现目标
1、掌握按键应用
2、理解按键消抖的原因以及消抖原理
3、具体目标:1、按键K1按下,LED1点亮;2、按键K2按下,LED1熄灭;2、按键K3按下,LED1状态取反。
一、按键概述
1.1 按键定义
按键是一种机械开关,按下即电路导通,松开即电路断开。由于上拉电阻的存在,因此一般按下时低电平,释放时高电平。
1.2 按键分类
1.2.1 按按键布局分
1. 独立按键
独立按键的电路构成是各按键共接地,按键其它引脚接IO口,外界一个上拉电阻。当按键按下,电路导通,IO引脚读到的就是低电平;当按键松开,电路断开,IO引脚读到的就是高电平。
2. 矩阵按键
矩阵按键是指将按键通过n行m列连线成一个按键的矩阵,从而只要使用n+m个IO口就可以实现对n*m个按键进行获取。获取的方法一般通过线翻转法来检测按键的高低电平
a.使所有行线为低电平,检测所有列线是否有低电平,若有则记录列线值
b.再使所有列线为低电平,检测所有行线的值,若有则记录行线的值
c.行线和列线交叉的就是按下的按键。
1.2.2 按按键类型分
机械按键:最常见的类型,通过物理接触来闭合电路。
薄膜按键:使用柔性材料和导电油墨,通常用于低成本和薄型设计。
触摸按键:没有物理移动部件,通过电容、电阻或其他传感器技术检测触摸。
1.3 按键按击方式
- 单击:按键按下后,第一次检测到低电平,则触发动作,之后即使按键还处于低电平状态,也不会触发动作。
- 双击:必须连续按下两次,才会触发相应的动作。
- 连续按:只要按键一直被按下,即一直处于低电平状态,则会根据调用间隔不停地触发动作。
- 短按:按键按下后不会立即触发动作,而是会经过一小段时间,才会触发动作。
- 长按:按键按下后不会立即触发动作,而是会经过一长段时间,才会触发动作。
1.4 按键消抖
按下按键和松开按键的瞬间都是存在机械抖动的。这种抖动可分为前抖动(按下瞬间带来的抖动),后抖动(松开瞬间带来的抖动),如下图所示。无论是前抖动还是后抖动,持续时间大约是5~10ms。
单片机检测按键时会出现误以为按键多次按下的情况:
当按下一次按键,可能在A点检测到一次低电平,在B点检测到一次高电平,在C点又检测到一次低电平。同时抖动是随机,不可测的。那么按下一次按键,抖动可能会误以为按下多次按键。
因此我们可以通过软件延时来进行消抖。
1.5 按键应用场景
一些机械按键的应用场景:
电脑键盘:机械键盘在电脑领域广泛应用。由于机械按键提供更好的触感和键程,使得打字和游戏体验更加舒适和精准。
游戏设备:机械按键在游戏机、游戏手柄和游戏机械键盘中得到广泛应用。机械按键的触感反馈和快速响应时间有助于提高游戏的控制性能。
工业控制设备:机械按键耐用性强,适用于工业控制设备中需要频繁操作的场景,如机械控制面板、机器人控制台等。
通信设备:机械按键可以用于手机、电话、对讲机等通信设备中,提供更好的按键触感和可靠性。
音频设备:机械按键在音频设备中使用广泛,如调音台、音频控制面板、音乐键盘等。
二、原理图设计
STC89C52 单片机上电后IO默认为高电平,当按键按下(以K1为例),单片机的P31管脚就接到GND,则由原来的高电平变为低电平。
说明: STC89C52 单片机的IO(输入输出口)为双向IO,在使用的时候不需要设置输入、输出模式。
三、程序设计
3.1 按键K1按下,LED1点亮
#include <REGX52.H>
sbit LED1 = P2^0;//LED1
sbit K1 = P3^1;//按键K1
void main()
{
while(1)
{
if(K1 == 0)//如果按键K1按下
{
LED1 = 0;//点亮LED1
}
}
}
3.2 按键K2按下,LED1熄灭
#include <REGX52.H>
sbit LED1 = P2^0;//LED1
sbit K1 = P3^1;//按键K1
sbit K2 = P3^0;//按键K2
void main()
{
while(1)
{
if(K1 == 0)//如果按键K1按下
{
LED1 = 0;//点亮LED1
}
if(K2 == 0)//如果按键K2按下
{
LED1 = 1;//熄灭LED1
}
}
}
3.3 按键K3按下,LED1状态取反(两种方式处理按键抖动问题:1、延时消抖;2、松手检测)
#include <REGX52.H>
sbit LED1 = P2^0;//LED1
sbit K1 = P3^1;//按键K1
sbit K2 = P3^0;//按键K2
sbit K3 = P3^2;//按键K3
void Delay20ms();//延时函数声明
void main()
{
while(1)
{
if(K1 == 0)//如果按键K1按下
{
LED1 = 0;//点亮LED1
}
if(K2 == 0)//如果按键K1按下
{
LED1 = 1;//熄灭LED1
}
//方式1:软件延时
if(K3 == 0)//如果按键K1按下
{
Delay20ms();
if(K3 == 0)
{
LED1 = !LED1;//LED1 状态取反
}
}
//方式2:松手检测
// if(K3 == 0)//如果按键K1按下
// {
// while(!K3);//松手检测
// LED1 = !LED1;//LED1 状态取反
// }
}
}
void Delay20ms() //@11.0592MHz
{
unsigned char i, j;
i = 36;
j = 217;
do
{
while (--j);
} while (--i);
}