MCU为什么要消抖动
2021-05-07

简单的说,进入了电子,不管是学纯模拟,还是学单片机,DSP、ARM等处理器,或者是我们的FPGA,一般没有不用到按键的地方。按键:人机交互控制,主要用于对系统的控制,信号的释放等。因此在这里,FPGA上应用的按键消抖动,也不得不讲!


一、为什么要消抖动


在按键被按下的短暂一瞬间,由于硬件上的抖动,往往会产生几毫秒的抖动,在这时候若采集信号,势必导致误操作,甚至系统崩溃;同样,在释放按键的那一刻,硬件上会相应的产生抖动,会产生同样的后果。因此,在模拟或者数字电路中,我们要避免在最不稳定的时候采集信号,进行操作。


对此一般产用消抖动的原理。一般可分为以下几种:


(1)延时

(2)N次低电平计数

(3)低通滤波


在数字电路中,一般产用(1)(2)种方法。后文中将详细介绍。


二、各种消抖动


1. 模拟电路按键消抖动


对于模拟电路中,一般消抖动用的是电容消抖动或者施密特触发等电路,再次不做具体介绍。 


 


2. 单片机中按键消抖动


对于单片机中的按键消抖动,本节Bingo根据自己当年写过的单片机其中的一个代码来讲解,代码如下所示:


unsigned char key_sCAN(void){if(key == 0) //检测到被按下{delay(5); //延时5ms,消抖if(key != 0)retrurn 0; //是抖动,返回退出while(!key1); // 确认被按下,等下释放delay(5); //延时5ms,消抖while(!key1); //确认被释放return 1; //返回按下信号}return 0; //没信号}


针对以上代码,消抖动的顺序如下所示:


(1)检测到信号

(2)延时5ms,消抖动

(3)继续检测信号,确认是否被按下

a) 是,则开始等待释放

b) 否,则返回0,退出

(4)延时5ms,消抖动

(5)确认,返回按下信号,退出


当然在单片机中也可以循环计数来确认是否被按下。Bingo认为如此,太耗MCU资源,因此再次不做讲述。


3. FPGA中的按键消抖动


对于FPGA中的消抖动,很多教科书上都没有讲述。但Bingo觉得这个很有必要。对于信号稳定性以及准确性分析,按键信号必须有一个稳定的脉冲,不然对系统稳定性有很大的干扰。


此处Bingo用两种方法对FPGA中按键消抖动分析。其中第一种是通过状态机的使用直接移植以上MCU的代码,这个思想在FPGA状态机中很重要。第二种,通过循环n次计数的方法来确认是否真的被按下,这种方法很实用在FPGA这种高速并行器件中。


(1)利用状态机移植MCU按键消抖动

此模块由Bingo无数次修改测试最后成型的代码,在功能上可适配n个按键,在思想上利用单片机采用了单片机消抖动的思想。具体代码实现过程请有需要的自行分析,本模块移植方便,Verilog代码如下所示:


/*************************************************

* Module Name : key_scan_jitter.v

* Engineer : Crazy Bingo

* Target Device : EP2C8Q208C8

* Tool versions : Quartus II 11.0

* Create Date : 2011-6-26

* Revision : v1.0

* Description :  

**************************************************/

module key_scan_jitter

#(

parameter KEY_WIDTH = 2

)

(

input clk,

input rst_n,

input [KEY_WIDTH-1:0] key_data,

output key_flag,

output reg [KEY_WIDTH-1:0] key_value

);

reg [19:0] cnt; //delay_5ms(249999)

reg [2:0] state;

//-----------------------------------

always @(posedge clk or negedge rst_n)

begin

if(!rst_n)

cnt <= 20'd0;

else

begin

cnt <= cnt + 1'b1;

if(cnt == 20'd249999)

cnt <= 20'd0;

end

end

//-----------------------------------

reg key_flag_r;

reg [KEY_WIDTH-1:0] key_data_r;

always@(posedge clk or negedge rst_n)

begin

if(!rst_n)

begin

key_flag_r <= 1'b0;

key_value <= {KEY_WIDTH{1'b0}};

end

else if(cnt == 20'd249999) //Delay_5ms

begin

case(state)

0:

begin

if(key_data != {KEY_WIDTH{1'b1}})

state <= 1;

else

state <= 0;

end

1:

begin

if(key_data != {KEY_WIDTH{1'b1}})

state <= 2;

else

state <= 0;

end

2:

begin

key_flag_r <= 1'b1;

key_value <= key_data; //lock the key_value

state <= 3;

end

3:

begin

key_flag_r <= 1'b0; //read the key_value

if(key_data == {KEY_WIDTH{1'b1}})

state <= 4;

else

state <= 3;

end

4:

begin

if(key_data == {KEY_WIDTH{1'b1}})

state <= 0;

else

state <= 4;

end

endcase

end

end

//---------------------------------------

//Capture the falling endge of the key_flag

reg key_flag_r0,key_flag_r1;

always@(posedge clk or negedge rst_n)

begin

if(!rst_n)

begin

key_flag_r0 <= 0;

key_flag_r1 <= 0;

end

else

begin

key_flag_r0 <= key_flag_r;

key_flag_r1 <= key_flag_r0;

end

end

assign key_flag = key_flag_r1 & ~key_flag_r0;

endmodule


信号线说明如下:

clk

系统最高时钟

rst_n

系统复位信号

Key_data

按键信号(可根据需要配置为n位)

Key_flag

按键确认信号

Key_vaule

按键返回值


雷同上述MCU按键消抖动的状态,此模块可以模拟成一下5个状态,见state machine:



(2)循环n次计数消抖动


同样,此模块也是Bingo无数次修改测试最后成型的代码,利用了更少的资源,更适用于并行高速FPGA的性能要求。具体代码实现过程请有需要的自行分析,本模块通过相关时钟的适配,n次计数来确认按键信号,Verilog代码如下所示:


/*************************************************

* Module Name : key_scan.v

* Engineer : Crazy Bingo

* Target Device : EP2C8Q208C8

* Tool versions : Quartus II 11.0

* Create Date : 2011-6-25

* Revision : v1.0

* Description :  

**************************************************/

module key_scan

#(

parameter KEY_WIDTH = 2

)

(

input clk, //50MHz

input rst_n,

input [KEY_WIDTH-1:0] key_data,

output key_flag,

output reg [KEY_WIDTH-1:0] key_value

);

//---------------------------------

//escape the jitters

reg [19:0] key_cnt; //scan counter

reg [KEY_WIDTH-1:0] key_data_r;

always @(posedge clk or negedge rst_n)

begin

if(!rst_n)

begin

key_data_r <= {KEY_WIDTH{1'b1}};

key_cnt <= 0;

end

else

begin

key_data_r <= key_data; //lock the key value

if((key_data == key_data_r) && (key_data != {KEY_WIDTH{1'b1}})) //20ms escape jitter

begin

if(key_cnt < 20'hfffff)

key_cnt <= key_cnt + 1'b1;

end

else key_cnt <= 0;

end

end

wire cnt_flag = (key_cnt == 20'hffffe) ? 1'b1 : 1'b0;//!!

//-----------------------------------

//sure the key is pressed

reg key_flag_r;

always@(posedge clk or negedge rst_n)

begin

if(!rst_n)

begin

key_flag_r <= 0;

key_value <= 0;

end

else if(cnt_flag)

begin

key_flag_r <= 1;

key_value <= key_data; //locked the data

end

else //let go your hand

key_flag_r <= 0; //lock the key_value

end

//---------------------------------------

//Capture the rising endge of the key_flag

reg key_flag_r0,key_flag_r1;

always@(posedge clk or negedge rst_n)

begin

if(!rst_n)

begin

key_flag_r0 <= 0;

key_flag_r1 <= 0;

end

else

begin

key_flag_r0 <= key_flag_r;

key_flag_r1 <= key_flag_r0;

end

end

assign key_flag = ~key_flag_r1 & key_flag_r0;

endmodule


来源:https://www.cnblogs.com/crazybingo/archive/2011/07/26/2117175.html 

声明: 本文转载自其它媒体或授权刊载,目的在于信息传递,并不代表本站赞同其观点和对其真实性负责,如有新闻稿件和图片作品的内容、版权以及其它问题的,请联系我们及时删除。(联系我们,邮箱:evan.li@aspencore.com )
0
评论
  • 【7.24 深圳】2025国际AI+IoT生态发展大会/2025全球 MCU及嵌入式技术论坛


  • 相关技术文库
  • 单片机
  • 嵌入式
  • MCU
  • STM
  • 3AT89C51单片机引脚说明及引脚图

    AT89C51是一种带4K字节闪烁可编程可擦除只读存储器的低电压,高性能CMOS8位微处理器,俗称单片机。该器件采用ATMEL高密度非易失存储器制造技术制造,与工业标准的MCS-51指令集和输出管脚相兼容。由于将多功能8位CPU...

    昨天
  • 51单片机对LCD1602液晶的驱动设计

    51单片机——LCD1602 1、1602液晶读写时序 (1)、读状态 RS=L,R/W=H,E=H。(判断忙完毕后释放总线) (2)、读数据 RS=H,R/W=H,E=H。 (3)、写指令 RS=L,R/W=L,D0~D7=指令码,E=高脉冲 (4)、写数据 RS=H,R/W=L,D0~D...

    昨天
  • 单片机串口如何接收不定长数据的?

    我们在使用其他STM32的单片机的时候,会发现有些困难,会发现常用的方法并不能用,在还没有接收完数据的时候,就解决不了。于是,只能用通用的方法来解决了。 这个通用的方法,其实原理和使用IDLE的原理一样:...

    昨天
  • ARM处理器的选型原则

    鉴于ARM微处理器的众多优点,随着国内外嵌入式应用领域的逐步发展,ARM微处理器必然会获得广泛的重视和应用。但是,由于ARM微处理器有多达十几种的内核结构,几十个芯片生产厂家,以及千变万化的内部功能配置组合,...

    前天
  • 有哪些低功耗设计方法?单片机系统低功耗设计要点介绍

    功耗,已经是一个老生常谈的话题了。对于功耗,大家多多少少有所了解。目前,很多产品的宣传里便带有低功耗噱头。为增进大家对功耗的认识,本文将基于两点介绍功耗:1.低功耗主要设计方法,2.单片机系统低功耗设计...

    前天
  • 8位32位MCU如何选择?如何选择合适的MCU?

    MCU,对于普通人而言,是一个高大上的存在。但是,在工业中,MCU确实常见产品。为增进大家对MCU的认识,本文将基于两点介绍MCU:1.8位MCU和32位MCU如何选择?2.如何选择合适的MCU。如果你对MCU具有兴趣,不妨继续往...

    07-09
  • ARM开发:一 ARM微处理器概述

    1.1ARM-Advanced RISC Machines ARM(Advanced RISC Machines),既可以认为是一个公司的名字,也可以认为是对一类微处理器的通称,还可以认为是一种技术的名字。 1991年ARM公司成立于英国剑桥,主要出售芯片设计技术...

    07-08
  • 分析C51单片机的一些误区和注意事项

    简介:常看见初学者要求使用_at_,这是一种谬误,把C当作ASM看待了。在C中变量的定位是编译器的事情,初学者只要定义变量和变量的作 用域,编译器就把一个固定地址给这个变量。怎么取得这个变量的地址?要用指针。 1) C...

    07-08
  • 51单片机几个延时程序

    简介:51单片机几个精确延时程序:在精确延时的计算当中,最容易让人忽略的是计算循环外的那部分延时,在对时间要求不高的场合,这部分对程序不会造成影响. 一. 500ms延时子程序(晶振12MHz,一个机器周期1us.) 程...

    07-08
  • 总结单片机软件抗干扰的几种办法

    简介:在提高硬件系统抗干扰能力的同时,软件抗干扰以其设计灵活、节省硬件资源、可靠性好越来越受到重视。下面以MCS-51单片机系统为例,对微机系统软件抗干扰方法进行研究。 1、软件抗干扰方法的研究 在工程实践中...

    07-08
  • 基于C51单片机实现汽车座椅自动控制系统的软硬件设计

    引言 随着人们生活水平的提高,对汽车座椅的舒适性要求也越来越高,要求对汽车座椅地调节能够更加简单、方便、快捷。目前,汽车座椅位置的调节多采用基于手动调节方式的机械和电动控制两种方式。汽车座椅位置的调节...

    07-02
  • MCS51单片机程序设计时堆栈的计算方法解析

    用C语言进行MCS51系列单片机程序设计是单片机开发和应用的必然趋势。Keil公司的C51编译器支持经典8051和8051派生产品的版本,通称为Cx51。应该说,Cx51是C语言在MCS51单片机上的扩展,既有C语言的共性,又有它自己...

    07-02
下载排行榜
更多
评测报告
更多
广告