单片机第二课——按键控制LED#普中单片机

欢迎来到LL工作室。

        上一次我们学习了如何点亮LED,但这种办法点亮的LED是不可控的。你是否思考过如何让LED的亮灭能在我们的掌控中呢?今天,我们就来学习按键,按键操控LED是一个简单易上手的方式!

所需材料清单:

软件:Keil uVision5(这是程序编写软件)

        stc-isp(这是一个烧录软件)

硬件:普中单片机开发板

        USB数据线(用于供电和编程)

 

 

ONE:按键原理

结构组成

        机械按键通常由一个活动的金属弹片或导电橡胶、一个固定的金属接触点(或导电垫片)以及一个外壳组成。如图1.1。

139323b6ee5c433a80000742c4ac0e61.png

图1.1

工作原理

        当按键未被按下时,活动金属弹片与固定接触点之间是断开的,电路处于断开状态,没有信号输出。当按键被按下时,活动金属弹片与固定接触点接触,电路闭合,形成电流回路,产生信号输出,如向微控制器发送一个低电平信号。释放按键后,弹片弹回原位,电路再次断开,信号消失。

(如果理解不了的就暂时理解成按键按下及开关开时按键置0,按键松开及开关关时按键置1)

按键原理图:

        根据普中科技单片机开发版原理图(图1.2),我们可以看到 按键K1到K4分别对应着引脚P3.1到P3.3(K2对应着引脚P3.0)。

b14a72baea0b4d40862702c1aa5da1f1.png

图1.2

按键抖动:

adf66acc9d744a4596c76af954815b33.png

图1.3

        如图1.3,按键抖动是指在按下或释放按钮时,由于机械元件的特性,导致开关频繁打开和关闭,产生短暂的波动信号。这种现象通常发生在机械弹性开关中,因为当机械触点断开或闭合时,由于触点的弹性作用,开关不会马上稳定地接通或断开,而是会在闭合及断开的瞬间伴随有一连串的抖动,通常我们使用软件消抖来解决按键抖动。

按键消抖

消抖原理:检测到按键按下后,执行一个延时(通常为5ms~20ms),让抖动消失后再检测按键状态,如果仍保持闭合状态电平,则确认为真正有键按下。

方法1:延时函数消抖

步骤1:打开 stc-isp

步骤2:找到软件延时计算器

efb9ddcc9daf4e618a9abc6357152f7f.png

步骤3:并按图设置配置,生成 c代码,然后复制代码。注意系统频率需选择11.0592MHz,8051指令集需选择STC-Y1(STC-Y1对应STC89/STC90系列的单片机,如使用其他类型的单片机则应选择好对应的指令集)

2103702e90eb43c9823f6adc6313aab8.png

步骤4:将原代码做如下更改,使得改延时函数变成万用的(想延时多久只需在更改数字)

void Delay(unsigned char xms)	//@11.0592MHz
{
	unsigned char data i, j;
	while(xms)      //注意这里的更改             
	{
		i = 2;
		j = 239;
		do
		{
			while (--j);
		} while (--i);
		xms--;                        
	}

步骤5:使用以下代码实现延时函数消抖

void Delay(unsigned char xms)	//@11.0592MHz
{
	unsigned char data i, j;
	while(xms)
	{
		i = 2;
		j = 239;
		do
		{
			while (--j);
		} while (--i);
		xms--;
	}
}if(P3_1==0)    				//P3.0,P3.1,P3.2,P3.3
	{
		Delay(20);
		while(P3_1==0);		//P3.0,P3.1,P3.2,P3.3
		Delay(20);
	}

Delay(20),此处的20表示使用Delay函数延时20毫秒,若想延时25毫秒只需更改数字,如Delay(25)。

做到这里就完成了使用按键的代码编写。

方法2:定时器消抖

        按键采用中断驱动方式,当按键按下后触发按键中断,在按键中断中开启一个定时器,定时周期为20ms,当定时时间到了以后触发定时器中断,在定时器中断处理函数中读取按键的值,如果按键值还是按下状态,则表示这是一次有效的按键。(定时器在往后的文章中会提及,此处为了解即可)

TWO:按键控制LED灯

1.首先新建工程(不知道的请回单片机第一课的文章)

2.按键控制LED亮灭

(1)无消抖:

#include <REGX52.H>
void main()
{
	while(1)
	{
		if(P3_1==0)       //当按键k1按下
		{
			P2_1=0;//led1亮
		}
		else		        //当按键k1按下
		{
			P2_0=1;//led1灭
		}
	}
}

 这段代码通过设置P3.1端口电平来控制P2.1端口的电平,来控制LED的亮灭。当按键K1被按下时P3.0端口 为0,LED灯亮 ,松开手时P3.0端口为1,LED灯灭。

效果展示:

08d06fc713d44441b5d37ac6efdbc621.gif

(2)消抖:

#include <REGX52.H>
void Delay(unsigned char xms)	//@11.0592MHz
{
	unsigned char data i, j;
	while(xms)	
{
		i = 2;
		j = 239;
		do
		{
			while (--j);
		} while (--i);
		xms--;
	}

void main()
{
	while(1)
	{
		if(P3_1==0)//按键k1按下
		{
			Delay(20);
			while(P3_1==0);
			Delay(20);
			P2_1=~P2_1;//led1状态取反
		}
	}
}

 

这段代码中当按键K1按下1次后(即按下后又松开)Led灯常亮,当按键再次按下后LED灭。只按下不松开LED无反应。

对比:

通过这两段代码,我们发现当不使用按键消抖时,按下按键即为开,松开按键即为关。当我们使用按键消抖时按一次按键(即按下后又松开)为开,再按一次按键(即按下后又松开)为关。

3.LED闪烁

#include <REGX52.H>
void Delay(unsigned char xms)	//@11.0592MHz
{
	unsigned char data i, j;
	while(xms)
	{
		i = 2;
		j = 239;
		do
		{
			while (--j);
		} while (--i);
		xms--;
	}
void main()
{
	while(1)
	{
		if(P3_1==0)//按键k1按下
		{
			Delay(250);
			P2_1=~P2_1;//led1状态取反
		}
	}
}

 

这段代码中我们发现当按下按键时,LED灯闪烁 ,松开按键时不再有变化 。

4.按键控制led移位/流水灯

(1)led移位

#include <REGX52.H>
void Delay(unsigned int xms);

unsigned char LEDNum;

void main()
{
	P2=~0x01;				//上电默认LED1点亮
	while(1)
	{
		if(P3_1==0)			//如果K1按键按下
		{
			Delay(20);
			while(P3_1==0);
			Delay(20);
			
			LEDNum++;		//LEDNum自增
			if(LEDNum>=8)	//限制LEDNum自增范围
				LEDNum=0;
			P2=~(0x01<<LEDNum);	//LED的第LEDNum位点亮
		}
		if(P3_0==0)			//如果K2按键按下
		{
			Delay(20);
			while(P3_0==0);
			Delay(20);
			
			if(LEDNum==0)	//LEDNum减到0后变为7
				LEDNum=7;
			else			//LEDNum未减到0,自减
				LEDNum--;
			P2=~(0x01<<LEDNum);	//LED的第LEDNum位点亮
		}
	}
}

void Delay(unsigned int xms)
{
	unsigned char i, j;
	while(xms--)
	{
		i = 2;
		j = 239;
		do
		{
			while (--j);
		} while (--i);
	}
}

这段代码中,我们将LED流水灯拆分为一步一步,并且通过两个按键 ,实现LED灯移位的方向 ,从而显示为 led 的移位。(按键消抖)。

(2)led流水灯

#include <REGX52.H>
void Delay(unsigned int xms);

unsigned char LEDNum;

void main()
{
	P2=~0x01;				//上电默认LED1点亮
	while(1)
	{
		if(P3_1==0)			//如果K1按键按下
		{

			Delay(100);
			
			LEDNum++;		//LEDNum自增
			if(LEDNum>=8)	//限制LEDNum自增范围
				LEDNum=0;
			P2=~(0x01<<LEDNum);	//LED的第LEDNum位点亮
		}
		if(P3_0==0)			//如果K2按键按下
		{

			Delay(100);
			
			if(LEDNum==0)	//LEDNum减到0后变为7
				LEDNum=7;
			else			//LEDNum未减到0,自减
				LEDNum--;
			P2=~(0x01<<LEDNum);	//LED的第LEDNum位点亮
		}
	}
}

void Delay(unsigned int xms)
{
	unsigned char i, j;
	while(xms--)
	{
		i = 2;
		j = 239;
		do
		{
			while (--j);
		} while (--i);
	}
}

这段代码中我们没有使用按键消抖,我们发现当我们一直按下按键时,LED灯一直移位,形成流水灯现象 。

 

总结

在技术的世界里,每一步的探索都是对未知的挑战,每一次的成功都是对自我的超越。今天,我们通过单片机点亮LED的教程,不仅学习了一项技能,更是点燃了对电子世界的热爱。让我们一起回顾这次旅程,并激励自己继续在技术的道路上不断前行。

按键及所谓的开关,通过使用按键消抖和无按键消抖,我们发现按键有很多种用法。那么你又能想到哪种新奇的现象?那快用代码来实现吧 !

 

 

LL工作室第四篇文章,感谢大家的支持!(作者:小布)

若文章有出现纰漏还请大佬指正(因为我还是小菜鸡,嘻嘻~多多包涵呀)

 

 

作者:LL工作室

物联沃分享整理
物联沃-IOTWORD物联网 » 单片机第二课——按键控制LED#普中单片机

发表回复