FPGA第二个实验---按键消抖实验

module k_xd(                //定义模块的输入输出端口,三个输入信号,系统时钟信号s_clk
    input s_clk,            //复位信号rst_n,按键输入信号k
    input rst_n,            //两个输出信号,按键数据有效信号k_flag,按键消抖后的数据k_value
    input k,
    output reg k_flag,
    output reg k_value 
);
reg [31:0] delay_c;         //定义两个寄存器变量,delay_c用于延时计数
reg k_reg;                  //k_reg用于存储按键k的状态
always @(posedge s_clk or negedge rst_n)   //为时序逻辑电路,在s_clk上升沿,或rst_n下降沿触发
begin                                      //如果复位信号有效,初始化定义的寄存器变量k_reg
    if(!rst_n)                             //delay_c
        k_reg <= 1'b1;                     //复位信号无效时,把按键k的状态值赋给k_reg
        delay_c <= 32'd0;                  //当按键值发生变化时(按键按下一次),给延时变量
    end                                    //delay_c赋初值,延时时间为20ms        
    else begin                             //当按键稳定时,delay_c递减,延时20ms 
        k_reg <= k;
        if(k_reg != k)
            delay_c <= 32'd1000_0000;
        else if(k_reg == k) begin
            if(delay_c > 32'd0)
                delay_c <= delay_c - 1'b1;
            else
                delay_c <= delay_c;
            end
        end
end
always @(posedge s_clk or negedge rst_n)    //s_clk上升沿或者rst_n下降沿触发
begin
    if(!rst_n) begin                        //如果复位信号有效,标志变量k_falg置0,
        k_flag <= 1'b0;                     //k_value置1
        k_value <= 1'b1;                    //当延时20ms时,标志信号k_flag置1
    end                                     //此时按键值为有效值,赋予变量k_value
    else begin
        if(delay_c == 32'd1) begin          //没有到达延时时间时,标志位k_flag,变量值k_value
            k_flag <= 1'b1;                 //不变
            k_value <= k;
        end
        else begin
            k_flag <= 1'b0;
            k_value <= k_value
        end
    end
end
endmodule
        
        

         学习过单片机一段时间,按键消抖一般采用延时消抖,当按键按下时,先延时一段时间,等按键稳定时,再读取此时按键的值。

         本实验为按键控制蜂鸣器发音,蜂鸣器高电平发音,按一次键可以改变蜂鸣器的发音状态。

module b_c(            //按键控制蜂鸣器模块的端口定义,时钟信号s_clk,复位信号rst_n
    input s_clk,       //按键有效信号k_flag,按键状态信号k_value
    input rst_n,       //蜂鸣器输出b
    input k_flag,
    input k_value,
    output reg b
);
always @(posedge s_clk or negedge rst_n)    //程序很简单,当复位信号有效,蜂鸣器变量初始化置1
begin   
    if(!rst_n)                              //当k_falg有效时,此时为消抖后的按键状态
        b <= 1'b1;                          //蜂鸣器变量发生反转
    else if(k_flag or (~k_value))
        b <= ~b;
    end
endmodule

        编写一个主程序调用上述两个模块。

module k_b(
    input s_clk,
    input rst_n,
    input k,
    output b
);
wire k_value;
wire k_flag;
k_xd u_k_xd(
    .s_clk (s_clk),
    .rst_n (rst_n),
    .k (k),
    .k_flag (k_flag),
    .k_value (k_value)
);
b_c u_b_c(
    .s_clk (s_clk),
    .rst_n (rst_n),
    .k_falg (k_flag),
    .k_value (k_value),
    .b (b)
);

 

  • 0
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值