当前位置:   article > 正文

FPGA_消抖(光耦等开关的抖动)_fpga消抖

fpga消抖

一、按键消抖

按键消抖只是针对机械弹性开关按键,打开闭合时由于机械触点的弹性作用,一个按键在闭合后不会马上达到稳定状态,因此在闭合瞬间伴随一连串的抖动。必须对这部分抖动进行消抖处理。

按键消抖可以分为硬件消抖和软件消抖。

硬件消抖:主要用RS触发器和电容等方法消抖。(硬件消抖比较受限)

软件消抖:对按键信号延时5ms-20ms采样,也可以检测到按键稳定状态后采样。如图

 1、1

       软件消抖:这里按键稳定时间为20ms,系统晶振为50MHz,周期20ns,20ms/20ns=1000000,所以计数器最大值为999999。当检测到按键为低电平时计数器开始计数,计数到最大值时此时按键状态稳定,当系统检测到高电平时,对计数器清零,当计数器到最大值时,让计数器保持值不变,在定义一个标志信号对按键消抖的稳定状态进行采集,当计数器计数到最大值时,说明按键处于稳定状态。

在这里插入图片描述

 

  1. module key_shake
  2. #(
  3. parameter CNT_MAX = 20'd999_999//计数最大值,20ms
  4. )
  5. (
  6. input wire sys_clk ,
  7. input wire sys_rst_n ,
  8. input wire key_in ,
  9. output reg key_flag
  10. );
  11. reg [19:0] cnt;
  12. always@(posedge sys_clk or negedge sys_rst_n)
  13. if(sys_rst_n == 1'b0)
  14. cnt <= 20'd0;
  15. else if(key_in == 1'b1)
  16. cnt <= 20'd0;
  17. else if(cnt == CNT_MAX)
  18. cnt <= CNT_MAX;
  19. else
  20. cnt <= cnt + 1'b1;
  21. always@(posedge sys_clk or negedge sys_rst_n)
  22. if(sys_rst_n == 1'b0)
  23. key_flag <= 1'b0;
  24. else if(cnt == CNT_MAX)
  25. key_flag <= 1'b1;
  26. else
  27. key_flag <= 1'b0;
  28. endmodule

testbench

  1. `timescale 1ns/1ns
  2. module tb_key_shake();
  3. reg sys_clk;
  4. reg sys_rst_n;
  5. reg key_in;
  6. reg [7:0] tb_cnt;
  7. wire key_flag;
  8. initial
  9. begin
  10. sys_clk = 1'b0;
  11. sys_rst_n <= 1'b0;
  12. key_in <= 1'b1;
  13. #20
  14. sys_rst_n <= 1'b1;
  15. end
  16. always #10 sys_clk = ~sys_clk;
  17. //把按键消抖过程压缩至250个系统周期
  18. always@(posedge sys_clk or negedge sys_rst_n)
  19. if(sys_rst_n == 1'b0)
  20. tb_cnt <= 8'd0;
  21. else if(tb_cnt == 8'd249)
  22. tb_cnt <= 8'd0;
  23. else
  24. tb_cnt <= tb_cnt + 1'b1;
  25. //模拟按键抖动
  26. always@(posedge sys_clk or negedge sys_rst_n)
  27. if(sys_rst_n == 1'b0)
  28. tb_cnt <= 8'd0;
  29. else if(tb_cnt <= 8'd24 || tb_cnt >= 8'd224)
  30. key_in <= 1'b1;
  31. else if((tb_cnt <= 8'd74 && tb_cnt > 8'd24)||(tb_cnt <= 8'd224 && tb_cnt >= 8'd174))
  32. key_in <= {$random}%2;
  33. else
  34. key_in <= 1'b0;
  35. key_shake
  36. #(
  37. .CNT_MAX(70)
  38. )
  39. key_shake_inst
  40. (
  41. .sys_clk (sys_clk),
  42. .sys_rst_n (sys_rst_n),
  43. .key_in (key_in),
  44. .key_flag (key_flag)
  45. );
  46. endmodule

仿真结果把按键按下时长缩短到250个系统时钟周期。定义一个计数器tb_cnt,计数最大值为249,然后模拟按键被按下的过程。过程如下图所示。

仿真结果

在这里插入图片描述

 由仿真结果得,每一次模拟按键的稳定状态都被标志信号key_flag采集到。

1、2

还有一种软件消抖写法,同样计数时间为20ms,对按键保存当前的值进寄存器,判断下一个周期的值是否不等于上一个周期,如果不等于,对计数器赋值,下一个周期如果相等计数器递减,如果一直相等,计数器一直递减到1,输出按键有效标志位。

  1. module key_debounce(
  2. input sys_clk, //外部 50M 时钟
  3. input sys_rst_n, //外部复位信号,低有效
  4. input key, //外部按键输入
  5. output reg key_flag, //按键数据有效信号
  6. output reg key_value //按键消抖后的数据
  7. );
  8. //reg define
  9. reg [31:0] delay_cnt;
  10. reg key_reg;
  11. //*****************************************************
  12. //** main code
  13. //*****************************************************
  14. always @(posedge sys_clk or negedge sys_rst_n) begin
  15. if (!sys_rst_n) begin
  16. key_reg <= 1'b1;
  17. delay_cnt <= 32'd0;
  18. end
  19. else begin
  20. key_reg <= key;
  21. if(key_reg != key) //一旦检测到按键状态发生变化(有按键被按下或释放)
  22. delay_cnt <= 32'd1000000; //给延时计数器重新装载初始值(计数时间为 20ms)
  23. else if(key_reg == key) begin //在按键状态稳定时,计数器递减,开始 20ms 倒计时
  24. if(delay_cnt > 32'd0)
  25. delay_cnt <= delay_cnt - 1'b1;
  26. else
  27. delay_cnt <= delay_cnt;
  28. end
  29. end
  30. end
  31. always @(posedge sys_clk or negedge sys_rst_n) begin
  32. if (!sys_rst_n) begin
  33. key_flag <= 1'b0;
  34. key_value <= 1'b1;
  35. end
  36. else begin
  37. if(delay_cnt == 32'd1) begin //当计数器递减到 1 时,说明按键稳定状态维持了 20ms
  38. key_flag <= 1'b1; //此时消抖过程结束,给出一个时钟周期的标志信号
  39. key_value <= key; //并寄存此时按键的值
  40. end
  41. else begin
  42. key_flag <= 1'b0;
  43. key_value <= key_value;
  44. end
  45. end
  46. end
  47. endmodule

第一种软件消抖要比第二种软件消抖简单高效,用按键输入电平值作为判断。

1、3

光耦问题:

 实际使用PS2801-4光耦,作为开关管起到隔离作用,输出端集电极接入到FPGA中,但是开关管有5us的开关稳定时间,光耦之前一直用作PWM输出,没有单独采集过信号。所以光耦是电流驱动型里面同样也有开关抖动时间的说法。

 1、4

三极管是否有抖动:

1、5

MOSS管是否有抖动:

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/笔触狂放9/article/detail/726121
推荐阅读
相关标签
  

闽ICP备14008679号