惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

MongoDB | Blog
MongoDB | Blog
B
Blog
Y
Y Combinator Blog
大猫的无限游戏
大猫的无限游戏
aimingoo的专栏
aimingoo的专栏
B
Blog RSS Feed
博客园 - Franky
V
V2EX
IT之家
IT之家
WordPress大学
WordPress大学
博客园 - 三生石上(FineUI控件)
J
Java Code Geeks
F
Fortinet All Blogs
I
InfoQ
云风的 BLOG
云风的 BLOG
腾讯CDC
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
月光博客
月光博客
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
N
Netflix TechBlog - Medium
宝玉的分享
宝玉的分享
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
P
Proofpoint News Feed
Microsoft Security Blog
Microsoft Security Blog

博客园 - yf.x

超声波测距#倒车雷达#DE10-Lite 按键计数器#DE10-Lite 流水呼吸灯v2#DE10-Lite 流水呼吸灯-v1#DE10-Lite 呼吸灯-#DE10-Lite 流水灯#DE10-Lite#Verilog HDLBits_review 2015fsm 补码FSM-HDLbits 串行数据流输出其中的数据位-HDLbits 串行数据接收判断-HDLbits 输出PS2数据流-HDLbits PS2数据流检测状态机-HDLbits 独热码状态机-HDLbits 旅鼠4-HDLbits 旅鼠游戏3-HDLbits 旅鼠游戏2-HDLbits 旅鼠游戏--HDLbits 水库水位控制问题-HDLbits 康威生命游戏-hdlbits
按键消抖#DE10-Lite
yf.x · 2026-03-31 · via 博客园 - yf.x

按键消抖方法:

  1. 滤波电容;
  2. 延时;
  3. 持续重采样;

2个状态:0-未按下;1-按下。

仿真结果:

image

代码逻辑:

  1. 复位,10ms延时计数清零,进入按键没按下状态0,按键值为1;
  2. 按键按下,先消前抖。在状态0分别判断,如果按下时间小于10ms,就保持状态0,按键值也保持不变,如果按下持续达到10ms,就进入按下的状态1,按键值变成0,延时计数器清0备用。如果完全没按,就什么都不变。
  3. 按键松开,消后抖。在状态1分别判断,如果松开时间小于10ms,就保持状态1,按键值也保持不变,如果松开持续达到10ms,就进入松开的状态0,按键值变成1,延时计数器清0备用。如果没松开过,就全不变。
  4. if(!rst_n)
                    begin
                        state <= 0;
                        cnt <= 0;
                        key_out <= 1; //按键未按下
                    end
                else
                    begin
                        case(state)
                            0: begin
                                    if(!key_in) // 按下
                                        begin
                                            if(cnt < T - 1)    // < 10ms
                                                begin
                                                    cnt <= cnt+1;    //延时计数
                                                    state <= 0; //状态保持没按下
                                                    key_out <= 1;    
                                                end
                                            else    //按下持续达到10ms
                                                begin
                                                    cnt <= 0;    
                                                    state <= 1;    //进入按下状态
                                                    key_out <= 0;
                                                end
                                        end
                                    else    //没按下
                                        begin
                                            cnt <= 0;
                                            state <= 0;
                                            key_out <= 1;
                                        end
                                end
                            1: begin
                                    if(key_in) // 松开
                                        begin
                                            if(cnt < T - 1)    //延时判断
                                                begin
                                                    cnt <= cnt+1;
                                                    state <= 1; //不够10ms延时,状态不变
                                                    key_out <= 0;
                                                end
                                            else    // 延时足够,状态转换,按键拉高
                                                begin
                                                    cnt <= 0;
                                                    state <= 0;
                                                    key_out <= 1;
                                                end
                                        end
                                    else    //按键按住不松
                                        begin
                                            cnt <= 0;
                                            state <= 1;
                                            key_out <= 0;
                                        end
                                end
                            default: state <= 0;    
                        endcase
  5. 测试代码:简单重复按键按下,松开的连续高低电平变化,每个状态时长小于仿真的有效状态1000ns,通过仿真结果可以看到:在按键持续拉低或拉高的计数达到49之后,按键值key_out有效。
  6. defparam dut.T = 50;
        
        key_filter dut(
            .clk(clk),
            .rst_n(rst_n),
            .key_in(key_in),
            .key_out(key_out)
        );
        
        initial begin
            clk = 0; rst_n = 0;
            key_in = 1;
            #200.1 rst_n = 1;
            #487 key_in = 0;
            #487 key_in = 1;
            #487 key_in = 0;
            #487 key_in = 1;
            #487 key_in = 0;
            #487 key_in = 1;
            #487 key_in = 0;
            #487 key_in = 1;
            #487 key_in = 0;
            #2000 key_in = 1;
            #487 key_in = 0;
            #487 key_in = 1;
            #487 key_in = 0;
            #487 key_in = 1;
            #487 key_in = 0;
            #487 key_in = 1;
            #487 key_in = 0;
            #487 key_in = 1;
            #487 key_in = 0;
            #487 key_in = 1;
            #2000 $stop;
        end
        
        always #10 clk = ~clk;