文章目录
- 独立按键的原理
- 独立按键控制LED灯的状态
- 按键抖动
- 控制LED灯的状态
- 独立按键控制二进制
- 独立按键控制移位
独立按键的原理
独立按键是一种基本的电子元件,它通常由一个按钮和两个引脚组成。在单片机中,我们可以将按键的一个引脚连接到某个IO口,并通过相应的程序来监视按键的状态。
我们可以看到,一个独立按键一脚接地,另一脚连接到单片机寄存器上;
k1键由P31控制,K2由P30控制,这是由于设计师的疏忽,所以当我们要写程序时,要记住要将这两个反过来写。
上图是与单片机对应的引脚接口,RXD表示接收数据,TXD表示发送数据;独立按键默认是高电平,即没有按下去为高电平,按下去为低电平。
接下来看一个例子:
#include <REGX52.H>
int main()
{
while(1)
{
if(P3_1==0)
{
P2_3=0;
}
else
{
P2_3=1;
}
}
}
P3_1表示第一个按键,在循环里面,当它处于低电平时,也就是我们按下去
时,那么第三个LED灯将会亮起,松手就会熄灭;倘若没有在循环里面,我
们只有在复位之前一直按住按键,那么LED灯将会一直亮起,如果复位前没
有按下去,那么LED灯将会一直不亮。
独立按键控制LED灯的状态
按键抖动
在这里,独立按键为机械弹性开关,当按键的触点闭合,断开时,由于弹性作用,独立按键没有办法立刻保持稳定,需要等待一定时间才能保持稳定,一般来说,这个抖动在10-20ms左右。
为了保持这种稳定,我们就需要消除这种抖动,一般来说有两种办法,一种是通过硬件:在电路上连个电容;另一种是软件消抖,根据经验增加10ms的延时。对于我们来说,可以通过程序来进行消抖。
控制LED灯的状态
在这里,我们要做的是利用独立按键,按下去一下就开灯,再按一下就熄灭,如此往复。就像在一个电脑网页上,在右上角按下去鼠标左键,松手之后就会关闭网页一样。所以,我们这里还有一个问题,每个人多久松手我们是不知道的,但我们知道倘若没有松手,那么按键将会一直保持低电平的状态,那么我们可以利用一个循环来确定是否松手。
代码如下:
#include <REGX52.H>
void Delay(unsigned int x) //@11.0592MHz
{
unsigned char i, j;
while(x--)
{
i = 2;
j = 199;
do
{
while (--j);
} while (--i);
}
}
void main()
{
while(1)
{
if(P3_1==0)
{
Delay(20);//抖动消除
while(P3_1==0);//检测松手
Delay(20);//抖动消除
P2_0=~P2_0;//按位取反
}
}
}
Delay是一个以ms为单位的延迟函数,可以输入参数来确定时间长短;当用户
按下去时也就是P3_1==0时,我们要先做的是抖动消除,接着是检测松手,
没有松手就一直保持低电平状态,当松手之后,又会产生抖动,故又需要抖
动消除。~是二进制中按位取反的意思,如果是0,按位取反之后就是1,如
果是1,按位取反后就是0,这刚好就是能改变独立按键高低电平的状态。
独立按键控制二进制
代码如下:
#include <REGX52.H>
void Delay(unsigned int x) //@11.0592MHz
{
unsigned char i, j;
while(x--)
{
i = 2;
j = 199;
do
{
while (--j);
} while (--i);
}
}
void main()
{
unsigned char num=0;
while(1)
{
if(P3_1==0)
{
Delay(20);//消除抖动
while(P3_1==0);//检测松手
Delay(20);//消除抖动
num++;
P2=~num;
}
}
}
num初始化为0,每当独立按键按一次,num依次增加1,由于LED灯是低电
平才显示(与二进制中的数字反过来),所以要用按位取反;
独立按键控制移位
代码如下:
#include <REGX52.H>
void Delay(unsigned int x) //@11.0592MHz
{
unsigned char i, j;
while(x--)
{
i = 2;
j = 199;
do
{
while (--j);
} while (--i);
}
}
void main()
{
unsigned char num=0;
P2=~0x01;//默认在第一个LED灯上
while(1)
{
//第一按键控制左移
if(P3_1==0)
{
Delay(20);//抖动消除
while(P3_1==0);//检测松手
Delay(20);//抖动消除
num++;
num%=8;
P2=~(0x01<<num);
}
//第二按键控制右移
if(P3_0==0)
{
Delay(20);//抖动消除
while(P3_0==0);//检测松手
Delay(20);//抖动消除
num--;
num+=8;
num%=8;
P2=~(0x01<<num);
}
}
}
先看左移的,由于只有8个LED灯,所以当num++超过8之后,就要回到初始
位置,那么可以利用对8取模限制只在0~7中走动;然后对0x01(0000 0001)
进行左移,num是多少,二进制中的1就向左移动多少,最后再按位取反即可。
接下里看右移的,以num的大小为基准,每向右移动一位,num就减少1,与
左移正好相反。num+=8是为了当处于初始位置向右移动时,使它正好处于
末尾位置;然后取模限制在0~7内,最后对0x01(0000 0001)左移,按位取
反即可。
这里不使用右移是因为为了以num为基准,且当LED灯处于初始位置亮时,
向右移时将会把二进制中的1给移不见了,所以用左移。