[X]关闭

按键去抖

文档创建者:Damon
浏览次数:11717
最后更新:2016-01-06
 
module Button(Clk,Rst,Sw,Led);// 模块接口
        input Clk;        //时钟信号
        input Rst;        //复位信号
        input [4 : 1] Sw;        //按钮SW输入,按下为0,抬起为1
        output [4 : 1] Led; // 4个led 输出
       
        reg [4 : 1] Led;
       
        reg [4 : 1] Sw1;
        reg [4 : 1] Sw1_r;
        wire [4 : 1] Sample1;
        reg [4 : 1] Sw2;
        reg [4 : 1] Sw2_r;
        wire [4 : 1] Sample2;
       
        reg [19 : 0] cnt;
       
        //第一次读取按键状态
        always @ (posedge Clk , negedge Rst)
                if(!Rst) Sw1 <= 4'b1111;
                else Sw1 <= Sw;
               
        //第一次读取的按键状态放入锁存器
        always @ (posedge Clk , negedge Rst)
                if(!Rst) Sw1_r <= 4'b1111;
                else Sw1_r <= Sw1;
               
        //Sample仅保持一个时钟周期
        assign Sample1 = Sw1_r & (!Sw1);
       
        //延时20MS后,第二次读取按键状态
        always @ (posedge Clk , negedge Rst)
                if(!Rst) Sw2 <= 4'b1111;
                else if (cnt == 20'hF_FFFF) Sw2 <= Sw;
                else Sw2 <= 4'b1111;
               
        //第二次读取的按键状态放入锁存器
        always @ (posedge Clk , negedge Rst)
                if(!Rst) Sw2_r <= 4'b1111;
                else Sw2_r <= Sw2;
       
        //Sample2仅保持一个时钟周期
        assign Sample2 = Sw2_r & (!Sw2);
       
        //计数器,定时20MS
        always @ (posedge Clk , negedge Rst)
                if(!Rst) cnt <= 0;
                else if (Sample1) cnt <= 0;
                else cnt <= cnt + 1'b1;
       
        //LED控制
        always @ (posedge Clk , negedge Rst)
                if(!Rst) Led <= 4'b0000;
                else if (Sample2) Led <= Sample2;
                else Led <= 4'b0000;
               
endmodule





求大神帮忙看看,我这个按键去抖有什么问题,我发现在sample1就出不来正确的波形。
另外,求大神讲下教程里的去抖程序,我有点看不懂。

发表评论已发布 10

贾文洋

发表于 2016-1-6 11:07:48 | 显示全部楼层

你程序是有问题的,sw你也没有用上,你两次采样之后必须判断。建议参考教程状态机那种写法!

贾文洋

发表于 2016-1-6 11:18:51 | 显示全部楼层

教程上的意思是五个状态,每10ms检测一次,如果第一次检测是低电平,第二次检测还是低电平,则说明按键被按下,low_flg置1;然后继续检测当检测到一次高电平,又隔10ms检测到高电平,则说明按键被释放,high_flag置1。即完成一次按下与释放的过程。看懂这个程序,你得熟悉状态机的写法!

Damon

发表于 2016-1-6 11:20:49 | 显示全部楼层

贾文洋 发表于 2016-1-6 11:07
你程序是有问题的,sw你也没有用上,你两次采样之后必须判断。建议参考教程状态机那种写法!

谢谢大神。
还有几个问题。
以下是第一次采样的程序。
关于你说的SW没有用的问题,这边SW用上了。

     //第一次读取按键状态
        always @ (posedge Clk , negedge Rst)
                if(!Rst) Sw1 <= 4'b1111;
                else Sw1 <= Sw;      //这边SW用上了呀。
               
        //第一次读取的按键状态放入锁存器
        always @ (posedge Clk , negedge Rst)
                if(!Rst) Sw1_r <= 4'b1111;
                else Sw1_r <= Sw1;
               
        //Sample仅保持一个时钟周期
        assign Sample1 = Sw1_r & (!Sw1);
仿真出来的波形,也是到sample1就没有了 ,貌似是   assign Sample1 = Sw1_r & (!Sw1);没有执行的样子。
   

Damon

发表于 2016-1-6 11:21:21 | 显示全部楼层

这是仿真出来的波形,大神可以参考下。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x

贾文洋

发表于 2016-1-6 11:31:38 | 显示全部楼层

你这样写的话,也正确,但不可能没有sample1.你这程序我仔细看了一下没有问题,仿真没出波形?

Damon

发表于 2016-1-6 11:34:45 | 显示全部楼层

贾文洋 发表于 2016-1-6 11:31
你这样写的话,也正确,但不可能没有sample1.你这程序我仔细看了一下没有问题,仿真没出波形?

对的,而且是前仿真,就是sample1出不来,好像assign不运行。
而且SW1,SW1_R都有,就是在他们2个有差异的时钟周期,没有sample1.

贾文洋

发表于 2016-1-6 14:06:01 | 显示全部楼层

本帖最后由 贾文洋 于 2016-1-6 14:14 编辑

你试试把前两个always语句合并一下!

Damon

发表于 2016-1-6 14:28:44 | 显示全部楼层

贾文洋 发表于 2016-1-6 14:06
你试试把前两个always语句合并一下!

还是不行,仿真出来的,跟之前的一样。

贾文洋

发表于 2016-1-6 15:47:41 | 显示全部楼层

QQ上回复我,给你解决一下!
12下一页
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则