查看: 1092|回复: 0

[资料] 蓝桥杯练习(二)按键的使用和延时消抖

[复制链接]

该用户从未签到

发表于 2021-9-2 15:19:25 | 显示全部楼层 |阅读模式
分享到:
蓝桥杯练习(二)按键的使用和延时消抖。

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

讲解按键抖动就需要知道按键按下这个过程中的电平变换的波形图,如图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 (27.73 KB, 下载次数: 1)
回复

使用道具 举报

您需要登录后才可以回帖 注册/登录

本版积分规则

关闭

站长推荐上一条 /3 下一条



手机版|小黑屋|与非网

GMT+8, 2025-1-11 23:49 , Processed in 0.120047 second(s), 16 queries , MemCache On.

ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

苏公网安备 32059002001037号

Powered by Discuz! X3.4

Copyright © 2001-2024, Tencent Cloud.