按键的防抖动处理

您所在的位置:网站首页 verilog按键防抖动 按键的防抖动处理

按键的防抖动处理

2023-08-27 07:20| 来源: 网络整理| 查看: 265

index 说明参考资料 翻译资料当软件消抖不合适时,如何对开关和继电器实施硬件消抖什么是开关抖动?软件与硬件反跳硬件对带有RC网络的SPST交换机进行防抖用SR闩锁消除SPDT开关用专用设备对SPST开关进行反跳结论 Debounce Switche Use of R-C circuit按钮硬件消抖方法(一)问题 硬件消抖(二)RC防抖电路(三)什么是开关弹跳?软件与硬件反跳结论 软件防抖

说明

在Arduino的使用过程中建议使用软件防抖动。若使用外部中断如何处理

参考资料 https://electrosome.com/switch-debouncing/https://www.circuitbasics.com/switch-debouncing/https://circuitdigest.com/electronic-circuits/what-is-switch-bouncing-and-how-to-prevent-it-using-debounce-circuit 翻译资料

原文网址:https://www.digikey.sg/en/articles/how-to-implement-hardware-debounce-for-switches-and-relays

当软件消抖不合适时,如何对开关和继电器实施硬件消抖

2021-02-09

在电气和电子工程的上下文中,开关是可以“接通”或“断开”电路,从而中断电流或将电流从一个导体转移到另一个导体的组件。工程师可以证明,有许多不同类型的开关,包括拨动开关,翘板开关,按钮开关,微型和限位开关,磁性和簧片开关以及继电器。所有人都有一个共同点:抖动。这就是他们所做的。

通常,这种抖动对电路影响很小或没有影响,但是如果数字电路足够快以检测和响应多次抖动,则可能会导致严重的后果。工程师的任务是避免或减轻这种抖动的影响,或“消除”开关的影响。尽管该行业长期实践硬件去抖动,但最近已转向基于软件的去抖动方法。但是,在某些情况下,硬件去抖动是更好的选择。

本文介绍了反跳,并讨论了消抖的软件和硬件方法。然后在显示如何实现之前,先指出一些实例,其中硬件去抖动是更好的选择。通过NKK开关,安森美半导体,德州仪器,Maxim Integrated和LogiSwitch的示例介绍了示例开关设备和硬件去抖动组件。

什么是开关抖动?

当开关或继电器被拨动或拨动时,每次设备改变状态时,人们都认为这是瞬时的单个响应,实际上可能涉及100个或更多的通断动作,这些动作持续几千分之一秒才最终接触解决到位。

例如,考虑一个单刀单掷(SPST)常开(NO)面板安装拨动开关,例如NKK的M2011SS1W01。假设此开关的一侧(可以视为输入)接地(0伏),而另一侧(在本例中为输出)连接至5伏电源(显示为+ ve )通过一个上拉电阻(R1)(图1)。 在这里插入图片描述

图1:对于SPST-NO拨动开关,在激活和禁用该开关时都可能发生跳动。(图片来源:Max Maxfield)

请注意,当开关被激活(关闭)和被停用(打开)时,开关抖动都可能发生。有时抖动可能会在电源接通期间一直变化,在这里被认为是逻辑0和1状态。在这种情况下,这些是“干净的”反弹。相比之下,如果信号仅达到中间电压,则将其称为“脏污”反弹。

如果是单刀双掷(SPDT)面板安装拨动开关(如NKK的M2012SS1W01-BC),则在常开(NO)和常闭(NC)端子上都可能发生跳动(图2)。在这种情况下,为简单起见,仅显示了“干净”的反弹。

在这里插入图片描述 图2:对于SPDT拨动开关,在激活和禁用该开关时,NO和NC端子上都可能发生跳动。(图片来源:Max Maxfield)

在许多情况下,该信号抖动持续时间不会产生任何影响。当开关连接到足够快以检测并响应多次跳动的电子设备上时,就会出现问题。所需要的是一种在电子设备作用之前对来自开关的信号进行去抖动的方法。

软件与硬件反跳

在1960年代和1970年代,使用各种硬件技术来实现开关去抖,从与SPST开关一起使用的简单电阻-电容器(RC)延迟电路到更复杂的设置/复位(SR)锁存功能。

最近,由于许多系统都具有微处理器单元(MPU)或微控制器单元(MCU),因此使用软件技术对来自任何开关的信号进行去抖动已变得司空见惯。但是,软件去抖动并不总是最好的方法。在某些应用中,小型、低性能、受内存限制的处理器具有有限的代码空间和/或时钟周期,可用于实现防抖动例程。在这些情况下,硬件实施可能是更好的解决方案。

同样,许多软件开发人员也不熟悉开关的物理特性,例如,除了从一种激活变化到另一种激活之外,开关的反弹特性还可能受到诸如温度和湿度之类的环境条件的影响。

由于现有的有关开关弹跳的文献常常令人困惑和自相矛盾,这加剧了软件开发人员缺乏开关专业知识的问题。例如,通常会看到一个开关在激活或停用后的1毫秒(ms)内将停止跳动。但是,著名的嵌入式系统专家Jack Ganssle对各种开关类型进行了经验测试,每个开关被激活300次,并记录了触点打开和闭合的最小和最大跳动量。他报告平均弹跳时间为1.6毫秒,最大弹跳时间为6.2毫秒。一些工业和军事上的“最佳实践”建议在首次激活后等待20 ms,然后再假设开关已停止弹跳。

此外,有许多简单的非基于处理器的系统也需要对开关进行去抖动处理。这种系统的一些示例是二进制计数器,该计数器驱动七段显示器,对来自继电器的脉冲进行计数。555单次定时器的触发输入被用作门或门的电机控制;以及使用键控输入的基于寄存器的有限状态机(FSM)。还有一些电子微调电位器(电位计),它们的值使用开关输入(上,下,有时存储)来修改,这会引起开关跳动。

所有这些示例都清楚地表明,一些有关如何执行硬件去抖动的知识可能对任何设计人员或开发人员都是有用的。

硬件对带有RC网络的SPST交换机进行防抖

最简单的基于硬件的开关去抖动解决方案之一是将电阻-电容器(RC)网络与SPST开关结合使用。这种电路有许多变体。一种更通用的实现方式涉及两个电阻和一个二极管(图3)。

在这里插入图片描述 图3:使用RC网络对SPST开关进行去抖动处理(顶部)时,二极管(D1)的加入迫使电容器(C1)通过电阻器R1充电,并通过电阻器R2放电。(图片来源:Max Maxfield)

当开关被激活(闭合)时,电容器C1通过电阻R2放电。如果在该电路中省略了二极管D1,则在停用(断开)开关时,C1将通过电阻器(R1 + R2)充电。但是,D1的存在意味着C1仅通过R1充电。

在某些情况下,只有开关的激活才有意义(即触发动作发生),在这种情况下,可以省略D1。但是,如果要在激活和停用开关时都触发动作,并且考虑最小化延迟,则建议添加D1。

观察电容器电压V C呈现的指数充电和放电曲线。将这个信号直接馈送到下游数字逻辑功能的输入不是一个好主意,因为看到一个信号徘徊在“良好”逻辑0和逻辑1值之间的未定义区域中,这是不希望的。取而代之的是,该信号通过施密特触发器输入被馈送到缓冲器的输入。此外,通常使用反相缓冲器,例如得克萨斯仪器(Texas Instruments)的CD74HC14M96的一个通道,因为反相功能的转换速度比非反相功能更快。

用SR闩锁消除SPDT开关

对于SPDT开关,常见的硬件去抖动解决方案是采用SR锁存器。自从IBM等公司使用这种技术对他们的大型机大约20世纪60年代的开关面板,这种做法被视为上流社会的名流的简单的硬件去抖的解决方案。可以使用两个背对背的两个输入与非门来形成这种锁存器。例如,通过使用德州仪器(TI)的SN74HC00DR四通道双输入NAND IC的两个通道(图4)。

在这里插入图片描述 图4:使用基于NAND的SR锁存器去抖动SPDT开关是一种非常有效的硬件去抖动解决方案。(图片来源:Max Maxfield)

当开关的NC端子接地时,如图4的上半部分所示,这将门g2的输出强制为逻辑1。反过来,门g1的输入上的两个逻辑1s将其输出强制为逻辑0。相比之下,如图4的下半部分所示,当开关的NO端子接地时,这会将门g1的输出强制为逻辑1。反过来,门g2的输入上的两个逻辑1将强制其g1的输出为逻辑1。输出到逻辑0。

该电路运行良好的原因是,当其两个输入均处于无效逻辑1状态时,SR锁存器会记住其先前的值。请记住,如图2所示,当拨动SPDT开关时,其端子中的任何一个都接地(在该时刻)首先反弹。由于这些跳动介于其原始值(逻辑0)和新值(逻辑1)之间,因此它们对SR锁存器的当前状态没有影响。只有在该终端停止跳动之后,它的对应对象才开始跳动,这时SR锁存器更改其状态。

用专用设备对SPST开关进行反跳

先前解决方案的一个问题是,许多设计人员更喜欢使用SPST开关,因为它们的成本通常低于SPDT。有许多在市场上公知的专用SPST去抖动设备,如的MC14490DWG从安森美半导体和MAX6818EAP + T向Maxim Integrated。

另一家制造商LogiSwitch以通孔和表面贴装器件(SMD)封装提供一套三通道,六通道和九通道去抖动解决方案。例如,考虑使用LogiSwitch LS18-S器件的电路(图5)。

在这里插入图片描述 图5:使用专用的三通道LS18-S芯片去抖SPDT开关(也提供六通道和九通道设备)。(图片来源:Max Maxfield)

像LogiSwitch系列的所有成员一样,LS18-S支持2.5至5.5伏的工作电压范围(电源电压的值不影响设备的响应时间)。此外,不同于其他专用集成电路解决方案的,LogiSwitch去抖设备并没有要求任何另外的组分如外部时钟,RC计时网络,或者在输入或输出上拉电阻。

LS18-S使用LogiSwitch的专有自适应NoBounce技术,具有很高的抗噪能力。禁止小于或等于20 ms持续时间的噪声尖峰开始或终止一个周期,并且无论最终触发时间如何,在激活和释放最后一次开关反弹之后,输出都会延迟20 ms的时间。

结论

有许多不同类型的开关,包括拨动开关,翘板开关和按钮开关,所有这些开关可能会弹跳。如果不缓解,开关弹跳可能导致微处理器和其他电子电路将单个开关激活视为包含多个事件。

通常使用微控制器中运行的软件来消除来自开关的跳动信号。如图所示,尽管这是一种低成本的解决方案,但它并非在所有情况下都是最佳选择,包括基于性能和内存受限的微控制器的系统,缺乏与开关相关问题的专业知识的软件开发人员,或未使用微控制器实现的系统。

作为替代,可以使用从电阻器-电容器网络到SR锁存器再到专用集成电路的各种方法在硬件中执行去抖动。

Debounce Switche Use of R-C circuit 按钮硬件消抖方法(一)

原文:https://blog.csdn.net/tigerrui/article/details/82735721 在这里插入图片描述

问题

arduino代码:

#define BUTTON 12 //定义按钮在 12号引脚,连接一个下拉电阻 int val = 0; //变量val 存储按钮的状态 int old_val = 0; //暂存val变量的上一个时间状态 int state = 0; //打印到串口的数据,按钮每被按下一次,state自增1 void setup() { pinMode(BUTTON, INPUT); Serial.begin(9600); //用于串口输出 } void loop() { //读取输入数值并且存储 val = digitalRead(BUTTON); //检查按钮的变化情况 if ((val == HIGH); ; (old_val == LOW)) { printState(); } //val现在是旧的了,让我们暂存一下 old_val = val; } void printState() { state++; Serial.println(state); }

代码解析: 实现的效果是,当按钮被按下并抬起时,向串口打印一个整数。这个是完全没有添加消抖的原始代码。 上传代码之后,会出现,明明只按了一下按钮,串口却会打印出多个整数。 这便是由于按钮的机械结构所造成的“”抖动”(想了解更详细请参考百度百科)。 “消抖正式开始”

硬件消抖(二)

代码和原始的代码一样(未添加任何消抖代码)。 电路图如下: 在这里插入图片描述

唯一的区别是:添加上了一个陶瓷电容(100nf),和下拉电阻并联,利用电容的快速充放电特性来过滤掉按钮的抖动(100nf是测试得来的数值,小伙伴门可以自己尝试)。 优点:需要更改代码,简单快捷 缺点:增加额外元件# 当软件反跳不合适时,如何对开关和继电器实施硬件反跳

克莱夫·“马克斯”·麦克斯菲尔德

由Digi-Key的北美编辑提供

2021-02-09

在电气和电子工程的上下文中,开关是可以“接通”或“断开”电路,从而中断电流或将电流从一个导体转移到另一个导体的组件。工程师可以证明,有许多不同类型的开关,包括拨动开关,翘板开关,按钮开关,微型和限位开关,磁性和簧片开关以及继电器。所有人都有一个共同点:反弹。这就是他们所做的。

通常,这种反弹对电路影响很小或没有影响,但是如果数字电路足够快以检测和响应多次反弹,则可能会导致严重的后果。工程师的任务是避免或减轻这种反弹的影响,或“消除”开关的影响。尽管该行业长期实践硬件去抖动,但最近已转向基于软件的去抖动方法。但是,在某些情况下,硬件去抖动是更好的选择。

本文介绍了反跳,并讨论了反跳的软件和硬件方法。然后在显示如何实现之前,先指出一些实例,其中硬件去抖动是更好的选择。通过NKK开关,安森美半导体,德州仪器,Maxim Integrated和LogiSwitch的示例介绍了示例开关设备和硬件去抖动组件。

RC防抖电路(三)

SR电路很常见,但电路体积庞大,因此很少使用它,而且SPDT开关比SPST(单刀单掷)开关更昂贵。防抖动的另一种方法是使用RC电路。这种电路的基本思想是使用电容器来滤除开关信号中的快速变化。 在这里插入图片描述

上面显示了用于去抖动的基本RC电路。该电路使用两个电阻器、电容器、施密特触发器六角逆变器(例如:7414)、SPST开关。

如果开关断开,则电容器两端的电压最初为零,现在通过R1和R2充电至Vcc。Vin的电压高,因此施密特反相触发器的输出低(逻辑0)如果开关闭合,则电容器放电至零,因此Vin的电压为’0’,施密特反相触发器的输出为高(逻辑1) 在弹跳状态期间,当电容器达到Vcc或Gnd时,电容器将停止Vin处的电压。

每个人都会有一个疑问,为什么不使用标准逆变器? 在这里插入图片描述 在这里插入图片描述

我们在这里不能使用标准的逆变器门。当施加的电压在0到0.8之间时,TTL定义为零输入。在某些情况下,输出变得不可预测。因此,我们使用Scmitt触发十六进制逆变器。即使输入发生变化或抖动,输出仍保持稳定,并且由于其滞后特性,还可以防止输出切换。

为了提高电路速度,我们可以在R2两端连接一个二极管,从而减少电容器的充电时间,因为当开关断开时,电容器仅通过R1充电。

什么是开关弹跳?

当开关或继电器被拨动或拨动时,每次设备改变状态时,人们都认为这是瞬时的单个响应,实际上可能涉及100个或更多的通断动作,这些动作持续几千分之一秒才最终接触解决到位。

例如,考虑一个单刀单掷(SPST)常开(NO)面板安装拨动开关,例如NKK的M2011SS1W01。假设此开关的一侧(可以视为输入)接地(0伏),而另一侧(在本例中为输出)连接至5伏电源(显示为+ ve )通过一个上拉电阻(R1)(图1)。

[[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-unGjiR62-1617239093699)(C:%5CUsers%5CAdministrator%5CPictures%5Ctypora%5Carticle-2021february-how-to-implement-hardware-fig1.jpg)]](https://www.digikey.sg/-/media/Images/Article Library/TechZone Articles/2021/February/How to Implement Hardware Debounce for Switches and Relays/article-2021february-how-to-implement-hardware-fig1_fullsize.jpg?la=en&ts=fe043efa-d706-4ab8-923c-445e7658b97a)图1:对于SPST-NO拨动开关,在激活和禁用该开关时都可能发生跳动。(图片来源:Max Maxfield)

请注意,当开关被激活(关闭)和被停用(打开)时,开关弹跳都可能发生。有时反弹可能会在电源轨之间一直过渡,在这里被认为是逻辑0和1状态。在这种情况下,这些是“干净的”反弹。相比之下,如果信号仅达到中间电压,则将其称为“脏污”反弹。

如果是单刀双掷(SPDT)面板安装拨动开关(如NKK的M2012SS1W01-BC),则在常开(NO)和常闭(NC)端子上都可能发生跳动(图2)。在这种情况下,为简单起见,仅显示了“干净”的反弹。

[[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FYiJsxKL-1617239093729)(C:%5CUsers%5CAdministrator%5CPictures%5Ctypora%5Carticle-2021february-how-to-implement-hardware-fig2.jpg)]](https://www.digikey.sg/-/media/Images/Article Library/TechZone Articles/2021/February/How to Implement Hardware Debounce for Switches and Relays/article-2021february-how-to-implement-hardware-fig2_fullsize.jpg?la=en&ts=dee2ee60-c15e-415c-90af-4884a5740960)图2:对于SPDT拨动开关,在激活和禁用该开关时,NO和NC端子上都可能发生跳动。(图片来源:Max Maxfield)

在许多情况下,该信号反弹持续时间不会产生任何影响。当开关连接到足够快以检测并响应多次跳动的电子设备上时,就会出现问题。所需要的是一种在电子设备作用之前对来自开关的信号进行去抖动的方法。

软件与硬件反跳

在1960年代和1970年代,使用各种硬件技术来实现开关去抖,从与SPST开关一起使用的简单电阻-电容器(RC)延迟电路到更复杂的设置/复位(SR)锁存功能。

最近,由于许多系统都具有微处理器单元(MPU)或微控制器单元(MCU),因此使用软件技术对来自任何开关的信号进行去抖动已变得司空见惯。但是,软件去抖动并不总是最好的方法。在某些应用中,小型,低性能,受内存限制的处理器具有有限的代码空间和/或时钟周期,可用于实现防抖动例程。在这些情况下,硬件实施可能是更好的解决方案。

同样,许多软件开发人员也不熟悉开关的物理特性,例如,除了从一种激活变化到另一种激活之外,开关的反弹特性还可能受到诸如温度和湿度之类的环境条件的影响。

由于现有的有关开关弹跳的文献常常令人困惑和自相矛盾,这加剧了软件开发人员缺乏开关专业知识的问题。例如,通常会看到一个开关在激活或停用后的1毫秒(ms)内将停止跳动。但是,著名的嵌入式系统专家Jack Ganssle对各种开关类型进行了经验测试,每个开关被激活300次,并记录了触点打开和闭合的最小和最大跳动量。他报告平均弹跳时间为1.6毫秒,最大弹跳时间为6.2毫秒。一些工业和军事上的“最佳实践”建议在首次激活后等待20 ms,然后再假设开关已停止弹跳。

此外,有许多简单的非基于处理器的系统也需要对开关进行去抖动处理。这种系统的一些示例是二进制计数器,该计数器驱动七段显示器,对来自继电器的脉冲进行计数。555单次定时器的触发输入被用作门或门的电机控制;以及使用键控输入的基于寄存器的有限状态机(FSM)。还有一些电子微调电位器(电位计),它们的值使用开关输入(上,下,有时存储)来修改,这会引起开关跳动。

所有这些示例都清楚地表明,一些有关如何执行硬件去抖动的知识可能对任何设计人员或开发人员都是有用的。

结论

有许多不同类型的开关,包括拨动开关,翘板开关和按钮开关,所有这些开关可能会弹跳。如果不缓解,开关弹跳可能导致微处理器和其他电子电路将单个开关激活视为包含多个事件。

通常使用微控制器中运行的软件来消除来自开关的跳动信号。如图所示,尽管这是一种低成本的解决方案,但它并非在所有情况下都是最佳选择,包括基于性能和内存受限的微控制器的系统,缺乏与开关相关问题的专业知识的软件开发人员,或未使用微控制器实现的系统。

作为替代,可以使用从电阻器-电容器网络到SR锁存器再到专用集成电路的各种方法在硬件中执行去抖动。

软件防抖 https://www.arduino.cc/zh/Tutorial/Debouncehttps://playground.arduino.cc/Learning/SoftwareDebounce 使用硬件开关时,您可能希望以一种或另一种方式消除输入的抖动。无论是硬件还是软件,您都不会在嘈杂的边缘过渡时多次触发。以下是一种简单可靠的软件反跳算法,旨在对输入线进行定期采样。 在这里插入图片描述 code / * SoftwareDebounce * *在从LOW到HIGH或从HIGH到LOW的每个转换中, *通过 在几毫秒内的*多次读取中进行采样来对输入信号进行去抖动。 在新状态下, 直到对输入信号 *进行了至少“ debounce_count”(10)*毫秒的采样为止,才认为输入*为高电平或低电平。 * *注意: *调整debounce_count以反映时间尺度 *输入信号在达到 稳定状态之前可能会反弹 * *基于: * https://www.arduino.cc/zh/Tutorial/Debounce * https://playground.arduino.cc/Learning/SoftwareDebounce * / int inPin = 7; // the number of the input pin int outPin = 13; // the number of the output pin int counter = 0; // how many times we have seen new value int reading; // the current value read from the input pin int current_state = LOW; // the debounced input value // the following variable is a long because the time, measured in milliseconds, // will quickly become a bigger number than can be stored in an int. long time = 0; // the last time the output pin was sampled int debounce_count = 10; // number of millis/samples to consider before declaring a debounced input void setup() { pinMode(inPin, INPUT); pinMode(outPin, OUTPUT); digitalWrite(outPin, current_state); // setup the Output LED for initial state } void loop() { // If we have gone on to the next millisecond if (millis() != time) { reading = digitalRead(inPin); if (reading == current_state && counter > 0) { counter--; } if (reading != current_state) { counter++; } // If the Input has shown the same value for long enough let's switch it if (counter >= debounce_count) { counter = 0; current_state = reading; digitalWrite(outPin, current_state); } time = millis(); } }


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3