找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 27351|回复: 15
打印 上一主题 下一主题
收起左侧

51单片机按键消抖方法介绍

  [复制链接]
跳转到指定楼层
楼主
ID:591559 发表于 2019-8-11 09:52 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
由于在单片机在应用系统中,更多的会用到独立键盘,加之两者的检测原理基本相似,所以这一节里我主要讲解独立键盘的检测原理及程序实现的方法。
1、 按键的检测原理
按键与单片机的连接如图5所示,按键的一端与地相连,另一端直接与单片机的I/O口相连。此时我们在程序中先给I/O口赋值高电平,然后不断的检测I/O口电平的变化。当按键没有被按下时,此I/O口的电平一直为高;当按键被按下时,由于按键的另一端直接与地相连,相当于低电平,此时我们从I/O口读出的即为高电平,程序一旦检测到I/O口由高电平变为低电平时,说明按键被按下,此时马上执行相应的动作,这就是按键检测的原理。

图5 按键与单片机连接图
2、 按键的抖动与消除
由于机械触点的弹性作用,一个按键开关在闭合时不会马上稳定地接通,在断开时也不会一下子断开。因而在闭合及断开的瞬间均伴随有一连串的抖动,与单片机I/O口相接的一端的电压会出现相应的变化,如图6所示。
图6 按键按下时电压的变化情况
从图6中我们可以看出,实际的电压波形在按下松手的时候都会出现一定的抖动,经过实验知道,这个一时间大概在5-10ms。所在在做单片机与按键相关的系统时必须考虑消抖的环节。按键消抖的方法有两种,一个是硬件方法   一个是软件的方法,而从节约成本和尽量简化硬件电路的角度出发,一般是采用在程序中加上消抖的方法实现,通常是采用延时的方法。具体的作法是:
检测出键闭合后执行一个延时程序,产生5ms~10ms的延时,让前沿抖动消失后再一次检测键的状态,如果仍保持闭合状态电平,则确认为真正有键按下。当检测到按键释放后,也要给5ms~10ms的延时,待后沿抖动消失后才能转入该键的处理程序。后面会结合到程序进行讲解。
下面我写一个简单的程序,功能为:当一个键按下时,让一个发光二极管发光,我们先看下按键模块在实验板上的原理图,如图7和图8所示。
图7 发光二极管模块原理图
图8 按键模块原理图
例1 按键检测程序
//功能:当按下S8键时,L1灯发光,松手后,L1灯熄灭。相应程序如例1.
#include <reg52.h>
#define uint unsigned int
#define uchar unsigned char

sbit D1=P1^0;
sbit S1=P3^4;

void main()
{
       P3=0xff;
       while(1)
       {
             if(S1==0)  //第一次检测按键是否按下
delay(20);  //消除按下时的抖动
if(S1==0)  //再次确定是否按下状态
{
                 D1=0;   //如果是按下状态,执行操作     
    while(!S1);    //检测是否是按键弹起
                 delay(20);    //消除松开时的抖动
}
              else
                     D1=1;           
       }
}

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏6 分享淘帖 顶1 踩
回复

使用道具 举报

沙发
ID:598462 发表于 2019-8-12 09:33 | 只看该作者
不错的技巧,学习了
回复

使用道具 举报

板凳
ID:109646 发表于 2019-8-12 09:55 | 只看该作者
这种程序在实际应用中,最好不要用
回复

使用道具 举报

地板
ID:208849 发表于 2019-8-12 14:47 | 只看该作者
用delay真的可以吗?
回复

使用道具 举报

5#
ID:370779 发表于 2019-8-30 17:24 | 只看该作者
较大的程序使用过多的delay,会占用单片机大量时间,建议采用定时器中断或状态机来消除抖动。
回复

使用道具 举报

6#
ID:600919 发表于 2019-8-30 21:28 | 只看该作者
使用延时会导致输出信号的频率不稳定,之前用过
回复

使用道具 举报

7#
ID:605321 发表于 2019-8-30 22:43 | 只看该作者
谢谢!
回复

使用道具 举报

8#
ID:605321 发表于 2019-8-30 22:44 | 只看该作者
非常感谢分享!
回复

使用道具 举报

9#
ID:385637 发表于 2019-8-31 10:53 | 只看该作者
新手都是这样教的用delay,做多几个项目就感觉这样延时的弊端了
回复

使用道具 举报

10#
ID:415088 发表于 2019-11-8 12:13 | 只看该作者
你的while()检测在实际项目中是不行的,浪费CPU
回复

使用道具 举报

11#
ID:472300 发表于 2020-8-15 14:50 | 只看该作者
duanyazhou 发表于 2019-8-12 09:55
这种程序在实际应用中,最好不要用

你好,能给说下原因么。是因为耽误主程序循环时间么
回复

使用道具 举报

12#
ID:808286 发表于 2020-8-16 14:58 | 只看该作者
奔儿霸 发表于 2020-8-15 14:50
你好,能给说下原因么。是因为耽误主程序循环时间么

我也在学习51单片机 delay在实际工程中是不适用的 我记得是使用delay的话 其他状态会受影响,就是如果程序中间加了这种 delay 延时操作后,很可能某一事件发生了,但是我们程序还在进行 delay 延时操作中,当这个事件发生完了,程序还在 delay 操作中,当我们 delay 完事再去检查的时候,已经晚了,已经检测不到那个事件了。
我用的方法是位检测,也是软件检测,就是对按键不断地扫描 当八位全是1/0时,表示按键的弹起/按下。
回复

使用道具 举报

13#
ID:66287 发表于 2020-8-18 08:36 | 只看该作者
作为了解按键原理,程序可以用。但实际工程中不能使用delay(),程序傻傻的等待,什么正事干不了。建议用状态机方式,准确高效。
回复

使用道具 举报

14#
ID:887235 发表于 2021-3-2 14:33 | 只看该作者
初学者表示学到了,谢谢楼主分享,也感谢评论中的前辈们的回复。
回复

使用道具 举报

15#
ID:1080941 发表于 2023-5-30 18:00 | 只看该作者
初学者表示学到了,谢谢楼主分享,也感谢评论中的前辈们的回复。
回复

使用道具 举报

16#
ID:140489 发表于 2023-5-31 08:19 | 只看该作者
这种程序在开发板上玩玩就行了,不要用到项目中去
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表