独立按键的原理
独立按键是一种基本的电子元件,它通常由一个按钮和两个引脚组成。在单片机中,我们可以将按键的一个引脚连接到某个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给移不见了,所以用左移。