历史上的今天
返回首页

历史上的今天

今天是:2025年03月11日(星期二)

正在发生

2018年03月11日 | 非同于MCU的独立按键消抖动

2018-03-11 来源:eefocus

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

  一、为什么要消抖动

56

 

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

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

  (1)延时

  (2)N次低电平计数

  (3)低通滤波

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

  二、各种消抖动

  1. 模拟电路按键消抖动

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

  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


推荐阅读

史海拾趣

Hartmann Codier GmbH公司的发展小趣事

对于固态非易失性精密电位器构成的温度测量电路,网友可能关心的问题及其回答如下:

  1. 固态非易失性精密电位器的工作原理是什么?
    • 回答:固态非易失性精密电位器(如X9C102/103/104/503系列)包含有99个电阻单元的电阻阵列。滑动单元的位置由CS、U/D和INC三个输入端控制。滑动端的位置可以被存储在一个非易失性存储器中,因此在下一次上电工作时可以被重新调用。
  2. 这个电位器在温度测量中是如何应用的?
    • 回答:非易失性数控电位器在温度测量中的应用主要是通过其构成的记数式模数转换电路来实现的。这种电路能够将温度信号转换为数字信号,进而进行温度的测量和记录。
  3. 固态非易失性精密电位器的分辨率是多少?
    • 回答:分辨率取决于具体的电位器型号。例如,X9C503(50k Ω)的每个抽头间的阻值为505 Ω,这意味着其分辨率等于最大的电阻值被99除。
  4. 这个电位器的工作电压范围是多少?
    • 回答:工作电压范围通常为VCC=3V至5.5V。
  5. 固态非易失性精密电位器能否在长时间内保存数据?
    • 回答:是的,所有的Xicor非易失性存储器都设计成并经过测试能够用于持久地保存数据的应用场合。滑动端位置数据可保存100年。
  6. 这个电位器在温度测量中有什么特点或优势?
    • 回答:其特点包括低功耗、高分辨率、非易失性存储、长时间数据保存等。这些特点使得它在温度测量中具有高精度、高可靠性和长寿命的优势。
  7. 如何选择合适的固态非易失性精密电位器进行温度测量?
    • 回答:在选择电位器时,需要考虑其工作电压、电阻范围、分辨率、功耗以及数据保存能力等参数。同时,还需考虑电路设计的具体需求和限制条件。

以上回答基于参考文章中的相关信息进行整理和总结,旨在解答网友可能关心的问题。

远阳(FLYOUNG)公司的发展小趣事

为了提高生产效率与产品质量,国光新业积极引进并自主研发高效自动化生产线。公司投产了行业首条高效聚合物自动化生产线,并在此基础上不断进行技改迭代。这些生产线的建立,不仅大幅减少了人力成本,还显著提升了产品的生产效率与一致性。目前,公司正进行第三条全国产化技改技术攻关,旨在进一步提升生产线的智能化与自动化水平。

ERGOBAHCO公司的发展小趣事

为了进一步提升公司的竞争力,ERGOBAHCO公司开始积极拓展国际市场。公司组建了一支专业的国际业务团队,参加了多场国际展会,并与多家国际知名企业建立了合作关系。通过不断努力,ERGOBAHCO公司的产品成功打入了欧美、东南亚等国家和地区的市场,公司的国际化程度得到了显著提升。

BRIGHT公司的发展小趣事

近年来,BRIGHT公司积极投身于太阳能领域的发展。他们推出了一种创新的商业模式,即帮助用户免费安装太阳能面板,并随后收取服务费。这一模式类似于有线电视的收费方式,有效降低了用户安装太阳能系统的门槛。通过与私人投资者的合作,BRIGHT公司成功承担了安装成本,并致力于向全球提供优质的屋顶太阳能解决方案。这一突破性的举措使得BRIGHT公司在太阳能领域取得了显著的成绩。

鞍山圣罗佳(ASL)公司的发展小趣事

BRIGHT公司的历史可以追溯到1985年,由一群热爱音乐的年轻人和电子工程师共同创立。在1987年,他们成功推出了全球第一支无线耳机,这一创新产品迅速在市场上获得了巨大的成功。这一成就的背后,是创始人在一次偶然中被家里的电线绊倒后产生的灵感。他意识到,将有线耳机转变为无线耳机将带来巨大的便利和舒适体验。这一创新不仅改变了耳机行业的格局,也为BRIGHT公司奠定了坚实的基础。

Central Semiconductor公司的发展小趣事

随着全球电子市场的不断扩大和竞争的加剧,Central Semiconductor积极实施全球化战略,拓展国际市场。公司在全球范围内建立了完善的销售网络和供应链体系,以确保产品能够及时、准确地到达客户手中。

同时,Central还不断开拓新的业务领域,如汽车电子、工业控制、医疗电子等。通过不断的技术创新和市场拓展,Central逐渐在多个领域取得了显著的业绩和市场份额。

这五个故事分别从不同的角度展示了Central Semiconductor在电子行业中的发展历程和成就。无论是坚守与转型、创新开发、对停产产品的支持、裸片产品的开发还是全球化布局与业务拓展,Central都展现出了其敏锐的市场洞察力和强大的市场竞争力。这些故事不仅是对Central发展历史的回顾,也是对其未来发展的展望和期许。

问答坊 | AI 解惑

关于PID调节的一点资料跟大家分享下

关于PID调节的一点资料跟大家分享下,希望大家多讨论…

查看全部问答>

内置与外置天线及内置天线技术要求

内置与外置天线及内置天线技术要求 天线分为内置与外置,外置主要使用螺旋或者PCB,螺旋天线一般带宽比较好也比较常用,PCB 天线比较容易调频率易于设计,但爱立信有两项重要专利,所以在欧美市场上很少其他厂商使用。还有一种假内置天线,其实 ...…

查看全部问答>

通常说的在NORFLASH上运行的程序还需要用到RAM吗?

norflash支持片上运行,nandflash不支持。那通常所说的在norflash上运行的程序是不是可以不需要ram? 如果我想做一个最小的ARM系统,一个2440芯片+一片norflash可行吗?不用操作系统,只运行一些百K左右大的.bin文件,也不用考虑程序的运行速度。 ...…

查看全部问答>

如何实现wince多用户?

如题,各用户要有自己的注册表信息和密码等信息!…

查看全部问答>

[求教]使用单片机解决UDP传输问题

小弟使用的是C8051F020芯片 以太网接口芯片是CP2201 由于开发使用芯片自带的库文件 函数和socket有些类似 程序基本实现将从PC收到的数据再次传回去 发送发送一段时间后(10ms或100ms) 单片机将不收数据了 不知道是什么原因?…

查看全部问答>

蓝牙虚拟串口问题

已经用 RegisterDevice注册设备成功 CreateFile虚拟串口成功 现在用GetCommState和SetCommState设置串口状态时返回错误为2250,经查为\"This network connection does not exist. \" 再问一下\"PORTEMUPortParams\"的通道可以随机设定吗?…

查看全部问答>

STM32用串口调试助手收不到数据

STM32可以编译包括运行,但是收不到数据。很郁闷。 公司台式电脑没串口,用的是USB转串口,相当于虚拟串口,串口调试助手,是用COM3口。下述程序可以运行,LED也会闪,但是串口调试助手上就是收不到数据。 请帮忙看看,十分感谢! 附近 ...…

查看全部问答>

请问 2401 能用JTAG 烧写和调试吗???谢谢

             大家好,我按着TI的资料做了一块2401的板子,做出来后不要说用来做调试了,就是连都不能连上.接下来的工作根本无法进行.后来找JTAG的资料来研究,发现EUM0和EUM1是用来作为接收来自仿真器的中断 ...…

查看全部问答>

OSCtxSw函数无法的到执行

最近在移植UCOS到MCF52259中,我是新手啊,遇到个问题(如标题),我有几个疑问啊:1.书上说,在正确设置了软中断向量或TRAP向量,使之指向OSCtxSw()函数的前提下,CPU将会执行OSCtxSw函数   我想问这个正确设置的问题:我这里是这样的:#d ...…

查看全部问答>

关于320F28035实现并口的问题?<时钟问题续集>

    我用这个28035运行其他的程序能够运行,应该说明系统时钟应该能够支持系统的运行。 但是我现在在做一个28035+TOPWAY 的液晶屏的显示就是显示不出来。    以前我在MSP430F149上已经实现了。这次只是换到DSP28035上就 ...…

查看全部问答>