查看: 10636
回复: 2
蓝桥杯练习(二)按键的使用和延时消抖

主题

回复
发表于2019-01-30 21:22:12 | 只看该作者
1# 电梯直达

蓝桥杯练习(二)按键的使用和延时消抖。

通常我们使用的按键均为微动按键,在按键按下时内部的金属簧片触点在发生振动,发出轻微的撞击声响并产生抖动电压这种现象称为按键的抖动。按键的抖动实际上是一种接触不良现象如果不进行有效的处理,按键抖动会影响用户体验并且降低系统运行的稳定性,所以进行按键延时消抖是非常有必要的,对按键消抖通常可以采用软件消抖和硬件消抖两种方式。

讲解按键抖动就需要知道按键按下这个过程中的电平变换的波形图,如图1-1所示。从图中我们可以看到按键按下分为三个过程:按下过程中的抖动、按键完全按下之后为稳定接通状态、松手都的抖动。消抖的本质目的就是屏蔽按下和松手时候抖动的这个不稳定的状态,使按键按下和松手的波形可以变为类似图1-2所示的波形。

图1-1

图1-2

硬件消抖:通过采用外加零件来消除干扰抖动杂脉冲波,通常采用电容滤波、单稳延时电路等等,例如通过RC电路进行硬件消抖,如下图2所示。


图2

原理:通过电容的充放电延时。采用并联电容连接法也可以达到延时消抖的效果。

软件消抖:通过延时的作用屏蔽按键按下和松手过程中电平不稳定的时间,只采集电平稳定时候的电平状态。

延时消抖:按键连接在单片机的I/O与地之间,利用单片机I/O口高电平的易失性实现按键的输入。单片机运行过程中,由于按键按下产生的抖动持续的时间很短,按键按下后程序先不对按键检测处理,可延时一段时间跳过按键的抖动时间,当按键按下达到稳定状态时再对按键的状态检测,从而实现按键的消抖。

按键按下抬起有效(以控制LED灯进行说明)

不同的人对键按键按下的时间长短有很大差别,按键按下抬起有效控制方式主要是为了避免按键按下所停留(粘滞)时间对控制结果的影响。程序设计时,按键按下抬起有效需控制编程需要注意几个方面:

首先,按键抖动时间一般在10ms左右,按键按下需要消除抖动;

第二,按键按下不管时间有多长,LED不受控制;

第三,按键抬起一瞬间LED状态才发生改变;


void delay(unsigned int x)   			//延时函数  
{ 
	while(x--);
}
void key(void)                                          //按键函数
{
	if(key1 == 0)					//如果按键按下导通产生低电平
	{
		delay(300);				//延时消除按键抖动,大约20毫秒
		while(key1 == 0);			//如果按键真的按下,等待按键抬起,松手检测。
		LED0 = ~LED0;                           //LED灯取反操作,一次达到LED灯亮灭的目的。
	}
}


按键长按连加(定时器方案)

中断进行扫描的时候行扫时还可以片机的资源,当用户如果一直按着按键的时候,此时按键相当于又一次的被按下,,不用进行松手检测减少单片机源的浪费。

上程序,此函数要放在中断子函数里面进行按键扫描


if(key1 == 0 && set_temp != 80)	//延时大于40ms可能稳定   此按键扫描函数放在中断里,延时时间=定时器定的时间*80
	{                                                       
		set_temp++;					   //在按键按下的时候在中断里进行判断进而起延时的作用
								  //
		if(key1 == 0 && set_temp == 80)                 //符合条件可以进行进入想要执行的指令
		{
			flash1 = 1;                           //自己定义的标志位
			set_temp = 0;                        //一定要清零,否则的可能导致下一个按键的失灵 
		}                                            
	}

在系统对时间要求不是很精确的情况下,延时时间可通过运行一个延时函数得到,如项目中所用到的延时函数delay(unsigned int x),我们可以在Keil软件的调试过程观察延时时间的与确定的x大致关系。受C语言编译效率、系统执行速度等因素影响,利用确定的x去设置延时时间误差一般很大。

按键定时器方案离不开定时器的配置,上程序


void timer0_init()
{
	AUXR &= 0x7F;		//定时器时钟12T模式
	TMOD &= 0xF0;		//设置定时器模式清除TMOD寄存器低四位的数据--定时器0的配置
	TMOD |= 0x01;		//设置定时器模式--16位装载 0-65536
	TL0 = 0xCD;		//设置定时初值2ms
	TH0 = 0xF8;		//设置定时初值
	ET0 = 1;		//打开定时器0的开关
	TR0 = 1;		//定时器0开始计时
	EA = 1;                 //中断总开关
}

void timer0() interrupt 1            //中断服务子函数
{
	TL0 = 0xCD;		//设置定时初值2ms
	TH0 = 0xF8;		//设置定时初值
	cp++;
	if(cp == 250)
	{
		cp = 0;
		flag = 1;
	}	
	key();		
}


附程序:

1 单个按键的源代码单个按键.zip(WR=0,拉低P4^2端口)







主题

回复
发表于2021-06-24 10:18:16   |  只看该作者
2#
谢谢分享,学习学习。

主题

回复
  • 温馨提示: 标题不合格、重复发帖、发布广告贴,将会被删除帖子或禁止发言。 详情请参考: 社区发帖规则
  • 您当前输入了 0 个文字。还可以输入 8000 个文字。 已添加复制上传图片功能,该功能目前仅支持chrome和火狐

禁言/删除

X
请选择禁言时长:
是否清除头像:
禁言/删除备注:
昵 称:
 
温馨提示:昵称只能设置一次,设置后无法修改。
只支持中文、英文和数字。

举报

X
请选择举报类型:
请输入详细内容:

顶部