51单片机--利用独立按键控制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给移不见了,所以用左移。

猜你喜欢

转载自blog.csdn.net/m0_74068921/article/details/131537766