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

推荐订阅源

Martin Fowler
Martin Fowler
Engineering at Meta
Engineering at Meta
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
阮一峰的网络日志
阮一峰的网络日志
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
量子位
Jina AI
Jina AI
Microsoft Azure Blog
Microsoft Azure Blog
博客园_首页
L
LangChain Blog
A
About on SuperTechFans
人人都是产品经理
人人都是产品经理
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
美团技术团队
博客园 - 三生石上(FineUI控件)
N
Netflix TechBlog - Medium
D
DataBreaches.Net
P
Proofpoint News Feed
小众软件
小众软件
Vercel News
Vercel News
T
The Blog of Author Tim Ferriss
WordPress大学
WordPress大学
雷峰网
雷峰网
G
Google Developers 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-04-02 · via 博客园 - yf.x
  1. DE10-Lite数码管:0点亮,1熄灭。

image

image

image

  1. 代码逻辑

按键计数需要处理1:按键消抖,2计数。

按键消抖:用2个按键KEY0和KEY1分别表示加计数和减计数的控制信号,检测按下的有效边沿,把按键输入key_in打两拍给key_buff2,然后用key_buff2去判断按键的状态,由按键的状态再打两拍来判断边沿。

按键边沿检测核心代码:

always @(posedge clk,negedge rst_n)
        begin
            if(!rst_n)
                begin
                    key_buff1 <= 0;
                    key_buff2 <= 0;
                end
            else
                begin
                    key_buff1 <= key_in;
                    key_buff2 <= key_buff1;
                end
        end
        
    always @(posedge clk,negedge rst_n)
        begin
            if(!rst_n)
                begin
                    state <= 0;
                    cnt <= 0;
                    key_out <= 1; //按键未按下
                end
            else
                begin
                    case(state)
                        0: begin
                                if(!key_buff2) // 按下
                                    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_buff2) // 松开
                                    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    
                end
        end
        
    reg key_out_buff1,key_out_buff2;
    
    always @(posedge clk,negedge rst_n)
        begin
            if(!rst_n)
                begin
                    key_out_buff1 <= 1;
                    key_out_buff2 <= 1;
                end
            else
                begin
                    key_out_buff1 <= key_out;
                    key_out_buff2 <= key_out_buff1;
                end
        end
    
    assign pose_flag = key_out_buff1 & ~key_out_buff2;
    assign nege_flag = ~key_out_buff1 & key_out_buff2;

计数:有符号的计数器,符合位的处理,补码的逆运算,减1再取反。

有符号计数器核心代码:

always @(posedge clk,negedge rst_n)
        begin
            if(!rst_n)
                temp_a <= 0;
            else
                if(add_flag && temp_a < 5'sd15 && !sub_flag)
                    temp_a <= temp_a + 1;
                else
                    if(sub_flag && temp_a > -5'sd15 && !add_flag)
                        temp_a <= temp_a - 1;
                    else
                        temp_a <= temp_a;
        end
        
    assign symbol = temp_a[4] ? 1'b1 : 1'b0;
    
    wire [3:0] temp_b;
    
    assign temp_b = ~(temp_a[3:0] - 1);
    
    assign data = temp_a[4] ? temp_b : temp_a[3:0];
    

整体设计:连线,按键边沿检测—计数—bin转bcd—数码管驱动。

顶层核心代码:

key_filter k1(
        .clk(clk),
        .rst_n(rst_n),
        .key_in(key_add),
        .nege_flag(add_flag),
        .pose_flag()
    );
    
    key_filter k2(
        .clk(clk),
        .rst_n(rst_n),
        .key_in(key_sub),
        .nege_flag(sub_flag),
        .pose_flag()
    );
    //--------------------------
    wire [3:0] key_data;
    wire [3:0] symbol;
    
    key_num_signed k3(
        .clk(clk),
        .rst_n(rst_n),
        .add_flag(add_flag),
        .sub_flag(sub_flag),
        .data(key_data),
        .symbol(symbol)
        );
    //--------------------------
    wire [7:0] key_bcd;
    
    bin2bcdv3 #(.BIN_WIDTH(4),.BCD_WIDTH(8))
                b1(
                    .bin(key_data),
                    .bcd(key_bcd)
                    );
    //------------------------------------                
    
    seg s0(.din(key_bcd[3:0]),.dout(seg_out0));    
    seg s1(.din(key_bcd[7:4]),.dout(seg_out1));    
    seg s2(.din(4'd0),.dout(seg_out2));    
    seg s3(.din(4'd0),.dout(seg_out3));
    seg s4(.din(4'd0),.dout(seg_out4));    
    seg s5(.din(symbol),.dout(seg_out5));