打印

各位大神帮帮忙看下这个程序

[复制链接]
1878|6
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
gongwh244|  楼主 | 2013-4-19 19:59 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本人初学,看了教程后写的这个按键消抖程序,有个地方十分想不明白

module sw_debounce(
                                        clk,rst_n,sw1_n,sw2_n,sw3_n,
                                        led1_p,led2_p,led3_p
                                        );
input clk;//时钟50M
input rst_n;//复位低有效
input sw1_n,sw2_n,sw3_n;//开关低有效
output led1_p,led2_p,led3_p;//LED灯高有效


reg [2:0] high1;
reg [2:0] high2;

always @(posedge clk or negedge rst_n)begin
        if(!rst_n)        high1<=3'b111;
        else high1<={sw1_n,sw2_n,sw3_n};
        end

always @(posedge clk or negedge rst_n)begin//前一个周期和后一个周期按键信息进行与操作
        if(!rst_n)        high2<=3'b111;
        else high2<=high1;
        end
wire [2:0]low_en=(~high1)&high2;//一旦检测到有震荡,low_en由0变为1
reg [19:0] cnt;


always @(posedge clk or negedge rst_n)begin
        if(!rst_n)        cnt<=20'h00000;
        else if(low_en)        cnt<=20'h00000;//一旦按键有震荡,计数器清0
                else        cnt<=cnt+1'b1;
        end


reg [2:0] low1;
reg [2:0] low2;

always @(posedge clk or negedge rst_n)begin
        if(!rst_n)        low1<=3'b111;
        else if(cnt==20'hfffff)low1<={sw1_n,sw2_n,sw3_n};//这里low1每当计数器数到20ms时保存下按键状态
        end

always @(posedge clk or negedge rst_n)begin//这里low2每个周期保存下low1上个周期状态
        if(!rst_n)        low2<=3'b111;
        else low2<=low1;
        end
wire [2:0] led_en=(~low1[2:0])&low2[2:0];
reg led1_pn;
reg led2_pn;
reg led3_pn;       
always @(posedge clk or negedge rst_n)begin
        if(!rst_n)       
                begin
                led1_pn<=0;
                led2_pn<=0;
                led3_pn<=0;
                end
        else
                begin
                        if (led_en[2])        led1_pn<=~led1_pn;
                        if (led_en[1])        led2_pn<=~led2_pn;
                        if (led_en[0])        led3_pn<=~led3_pn;
                end
       
        end
assign led1_p=led1_pn?1:0;
assign led2_p=led2_pn?1:0;
assign led3_p=led3_pn?1:0;
       
endmodule

问题来了,就是红色字体部分,如果计数器cnt恰好数到20'hfffff的时候来了个低电平的杂波且少于20ms,那岂不是误触发了led_en导致LED翻转而点亮?

多谢了,分不多

相关帖子

沙发
gongwh244|  楼主 | 2013-4-19 20:00 | 只看该作者
沙发自己坐

使用特权

评论回复
板凳
yuxiao2117| | 2013-4-20 17:16 | 只看该作者
按键的初始值是1,有震荡是指的的由1变到0,只有检测到下降沿之后cnt才开始计数,切当一直为低电平时才能计数到ffff,如果中间有滤波,又会从新计数,不会出现你说的那种情况  不知道我说不对不对  也是刚刚学

使用特权

评论回复
地板
lu-永| | 2013-4-20 18:45 | 只看该作者
求解?

使用特权

评论回复
5
gongwh244|  楼主 | 2013-4-21 18:58 | 只看该作者
yuxiao2117 发表于 2013-4-20 17:16
按键的初始值是1,有震荡是指的的由1变到0,只有检测到下降沿之后cnt才开始计数,切当一直为低电平时才能计 ...

这个cnt应该是程序一开始就不停计数的,只是一旦检测到震荡会置零,我不理解的是led_en也是不停检测的,如果恰好是FFFFFF时被它检测到震荡,岂不是就错了

使用特权

评论回复
6
yghanwuji| | 2013-5-6 19:21 | 只看该作者
消抖是这样的,信号进来的频率肯定比你计数的频率慢,当有信号进来后,它开始计数,如果在计数N的时间内一直是一个电平的话,这表明这个信号有效,如果中间有毛刺则重新开始计数,直到达到你的计数N,一般消抖时间为数据位宽的四分之一就可以了。

使用特权

评论回复
7
GoldSunMonkey| | 2013-5-6 21:03 | 只看该作者
yghanwuji 发表于 2013-5-6 19:21
消抖是这样的,信号进来的频率肯定比你计数的频率慢,当有信号进来后,它开始计数,如果在计数N的时间内一 ...

感谢您的分享啊

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

3

主题

14

帖子

0

粉丝