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
评论
热门推荐
  • 注册Cadence中国区用户大会,领2020+2021论文集


    注册成功且通过审核的用户可获得Cadence 2020和2021年用户大会优秀论文集锦。一年一度Cadence全球巡回用户大会;中国IC设计工程师最大的技术方案分享会;40多位不同IC公司的工程师实际案例分享;涵盖最完整的先进技术交流平台!

  • 相关技术文库
  • 单片机
  • 嵌入式
  • MCU
  • STM
  • ARM Cortex系列处理器知识点汇总

    最近因为要为芯片选定核,所以就在了解哪些核合适且性价比好,这是一个需要结合产品各类技术、市场分析的活,看似简单却还是需要一些储备的,今天选了一篇ARM Cortex系列的科普文章与大家分享。 众所周知,英国的ARM公司是嵌入式微处理器世界当中的佼佼者。AR

    05-11
  • 你的CPU属于哈佛结构还是冯诺依曼结构?

    现代的CPU基本上归为冯诺伊曼结构(也称普林斯顿结构)和哈佛结构。 冯洛伊曼结构就是我们所说的X86架构,而哈佛结构就是ARM架构。一个广泛用于桌面端(台式/笔记本/服务器/工作站等),一个雄踞移动领域,我们的手持设备(平板\手机用的大多就是他了)。 01

    05-10
  • 如何批量修改MCU封装管脚定义

    在做产品开发时,为了缩短研发周期,我们一般都是直接找来参考设计做参考。这些参考资料要么是来自原厂的,要么是来自方案商的。  接触过这么多的参考设计资料,发现大部分的资料都有一个通病,就是不少MCU的PIN脚定义都只是标出IO口的定义,其它复用​​​​功能

    05-08
  • 51单片机的ISP下载知识

    本文详细介绍了串口、51单片机的ISP下载等基础知识,已经学过单片机的也可以看看,加强一下对这方面的了解。 串口 串行接口简称串口,也称串行通信接口,是采用串行通信方式的扩展接口。 我们比较熟悉的USB接口,全名通用串行总线(Universal Serial BUS),就

    05-06
  • 硬件开发如何选择合适的MCU

    点击上方关注我们! 我在做硬件开发时,如果遇到的是一个新产品,新项目,之前没有做过的,没有任何的经验,在选MCU时,我一般是这样操作的。 首先,根据产品的需求,整理出一份硬件规格。比如,电源管理,传感器接口,人机交互接口等。 然后,整理出整个原理

    05-06
  • 单片机的功耗怎么算的?

    单片机的功耗是非常难算的,而且在高温下,单片机的功耗还是一个特别重要的参数。暂且把单片机的功耗按照下面的划分。 暂且把单片机的功耗按照下面的划分。 1.内部功耗(与频率有关) 2.数字输入输出口功耗 2.1输入口 2.2输出高 2.3输出低 3.模拟输入口功耗从

    05-07
  • 嵌入式工程师必备工具:I2C和SPI总线协议

    IIC vs SPI 现今,在低端数字通信应用领域,我们随处可见IIC (Inter-Integrated Circuit) 和 SPI (Serial Peripheral Interface)的身影。原因是这两种通信协议非常适合近距离低速芯片间通信。Philips(for IIC)和Motorola(for SPI) 出于不同背景和市场需求

    04-30
  • 嵌入式面试注意事项

    找工作也是一门技能,有的人很快就找到自己喜欢的工作,有的人找了很久也没找到合适的工作。 下面给大家分享几点找工作过程中存在的“潜规则”内容。 1、面试的本质不是考试,而是告诉面试官你会做什么 经验不够的小伙伴特别容易犯的一个错误,不清楚面试官到

    04-29
  • 为什么需要RTOS?

    很多单片机初学者都是从裸机开始的,裸机确实也能开发出好的产品,但作为一个嵌入式软件工程师,如果只能用裸机开发产品,那肯定是不够的。 要从裸机的思维转变到RTOS的思维,其实需要一个过程,而且开始的一段时间会很痛苦。但过一段时间理解了一些内容,能

    04-28
  • 使用RTOS的8个理由

    嵌入式系统中,有很多方式实现任务调度。功能有限的小系统中,无限循环足够实现系统功能。当软件设计变得庞大且复杂时,设计师应该考虑使用实时操作系统。 下面给大家分享使用RTOS的8个理由: 1.硬实时响应 基于优先级抢占的RTOS,根据任务的实时需求,执行优

    04-26
  • 单片机延时程序,Keil C编译器实现

    应用单片机的时候,经常会遇到需要短时间延时的情况。需要的延时时间很短,一般都是几十到几百微妙(us)。有时候还需要很高的精度,比如用单片机驱动 DS18B20的时候,误差容许的范围在十几us以内,不然很容易出错。这种情况下,用计时器往往有点小题大做。而

    04-26
  • STM32 在超低功耗所做的设计思路

    对于给定的制造工艺和晶片区域,微控制器的功耗主要取决于两个因素(动态可控):电压和频率。ST公司L系列超低功耗芯片为130nm超低泄漏工艺,在超低功耗所做的设计思路如下: 1. 围绕Cortex-M3内核构建,具有领先的处理性能和代码密度,其处理性能使得运行模

    04-25
下载排行榜
更多
广告
X
广告