STM32F103ZET6【标准库函数开发】------02.1 按键的不同展示方法(非中断的形式)

本文介绍了如何通过按键控制LED灯的状态,并通过代码优化实现不同的控制逻辑。从基本的按键按下点亮/熄灭LED,到考虑按键松开状态的控制,再到利用按键松开标志位实现LED状态切换,详细阐述了按键检测和消抖处理的过程,展示了嵌入式系统中简单交互功能的实现方法。
摘要由CSDN通过智能技术生成

一、按键的形式

按键的状态只有按下和按下两种,而刚好电平也只有高电平和低电平两种。
所以对应的GPIO口的状态也有两种
一种是未按下为高电平,按下为低电平(需要将IO设置为上拉输入)

图1
图2

一种是未按下为低电平,按下为高电平(需要将IO设置为下拉输入)

图1
图2

二、分析代码对应的实际效果

 int main(void)
 {  
 	LED_Init();			//LED端口初始化
	KEY_Init();         //初始化与按键连接的硬件接口
	LED0=1;				//LED熄灭
	while(1)
	{		  
		if(KEY0==0) //按键按下
		{
			delay_ms(10);//消抖
			if(KEY0==0) //按键按下
			LED0=0;//LED点亮
		}
	}	 
}

上面代码实现的效果是,开机LED0熄灭,KEY0按下,则LED0点亮。代码结束,那么KEY0松开之后,对不起,代码没写,所以KEY0松开之后LED0还是点亮的。

于是有了升级版,增加一个松开的判断语句

 int main(void)
 {  
 	LED_Init();			//LED端口初始化
	KEY_Init();         //初始化与按键连接的硬件接口
	LED0=1;				//LED熄灭
	while(1)
	{		  
		if(KEY0==0) //按键按下
		{
			delay_ms(10);//消抖
			if(KEY0==0) //按键按下
			LED0=0;//LED点亮
		}
		else
		{ 
			LED0=1;//LED熄灭
		}		
	}	 
}

上面代码实现的效果是,开机LED0熄灭,KEY0按下,则LED0点亮。当KEY0松开之后,LED0熄灭。看上去好像没问题,但实际使用起来就会发现不协调的地方,如果我想让LED0常亮,我岂不是要用手一直按着,这也太反人类了吧。
好吧,再升级一下。

int main(void)
 {
	delay_init();	    	 //延时函数初始化	  
 	LED_Init();			     //LED端口初始化
	KEY_Init();          //初始化与按键连接的硬件接口
	LED0=1;
	while(1)
	{		  
		if(KEY0==0) //按键按下
		{
			delay_ms(10);//消抖
			if(KEY0==0) //按键按下			
			LED0=~LED0;//电平翻转
			while(KEY0==0);//按键按下,则一直进入死循环;除非松开
		}
	}	 
}

上面代码实现的效果是,
开机LED0熄灭,
KEY0按下,则LED0点亮。
当KEY0保持按下状态,LED0处于点亮状态;
当KEY0松开之后,LED0处于点亮状态;
当KEY0按下,则LED0熄灭;
当KEY0保持按下状态,LED0处于熄灭状态;
当KEY0松开之后,LED0处于熄灭状态;
KEY0按下则LED0点亮,重复上述状态……

然后将while(KEY0==0);位置提前,代码改为

 int main(void)
 {
	delay_init();	    	 //延时函数初始化	  
 	LED_Init();			     //LED端口初始化
	KEY_Init();          //初始化与按键连接的硬件接口
	LED0=1;
	while(1)
	{		  
		if(KEY0==0) //按键按下
		{
			delay_ms(10);//消抖
			if(KEY0==0) //按键按下	
			while(KEY0==0);//按键按下,则一直进入死循环;除非松开
			LED0=~LED0;//电平翻转			
		}
	}	 
}

开机LED0熄灭,
KEY0按下,则LED0熄灭。
当KEY0保持按下状态,LED0处于熄灭状态;
当KEY0松开之后,LED0处于点亮状态;
当KEY0按下,则LED0处于点亮状态;
当KEY0保持按下状态,LED0处于点亮状态;
当KEY0松开之后,LED0处于熄灭状态;
KEY0按下则LED0熄灭,重复上述状态……

上面两个程序的区别为,一个为先执行动作,再进入死循环;一个为先进入死循环,再执行动作。

通过下面的的按键松开标志位也可以实现上面的效果,按键的瞬间进行led翻转

 int main(void)
 {
	int a=1;//按键松开标志位,0是按键按下,1是按键松开
	delay_init();	    	 //延时函数初始化	  
 	LED_Init();			     //LED端口初始化
	KEY_Init();          //初始化与按键连接的硬件接口
	LED0=1;
	while(1)
	{		  
		if(KEY0==0) //按键按下
		{
			delay_ms(10);//消抖
			if(KEY0==0&&a==1) //按键按下瞬间	
			LED0=~LED0;
			a=0;			
		}
		else
		{a=1;}
	}	 
}
刚开机, KEY0=1,a=1,LED处于熄灭状态
按键按下,KEY0=0, a=1,LED翻转,即LED点亮
按键保持按下状态,KEY0=0  a=0,无动作,LED处于点亮状态
按键松开,KEY0=1  a=1,无动作,LED处于点亮状态

按键按下,KEY0=0  a=1  LED翻转,即LED熄灭
按键保持按下状态,KEY0=0  a=0,无动作,LED处于熄灭状态
按键松开,KEY0=1  a=1,无动作,LED处于熄灭状态

按键按下,KEY0=0, a=1,LED翻转,即LED点亮
按键保持按下状态,KEY0=0  a=0,无动作,LED处于点亮状态
按键松开,KEY0=1  a=1,无动作,LED处于点亮状态
…………………………
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值