您当前的位置:五五电子网电子知识单片机-工控设备源码-程序非同于MCU的独立按键消抖动 正文
非同于MCU的独立按键消抖动

非同于MCU的独立按键消抖动

点击数:7342 次   录入时间:03-04 12:02:40   整理:http://www.55dianzi.com   源码-程序

  简单的说,进入了电子,不管是学纯模拟,还是学单片机,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

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



www.55dianzi.com

  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 :

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



www.55dianzi.com

  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;

[1] [2]  下一页


本文关键字:暂无联系方式源码-程序单片机-工控设备 - 源码-程序

《非同于MCU的独立按键消抖动》相关文章>>>