×
嵌入式 > 技术百科 > 详情

按键消抖-脉冲边缘检测法

发布时间:2020-06-20 发布时间:
|
就是建立2个寄存器,形成二级寄存器,在时钟触发中,首先把数据送入第一个寄存器中,然后在下一个时钟上沿到来时,将第一个寄存器中的数据存入第二个寄存器,也就是说第二个寄存器中的数据始终比第一个寄存器晚一个周期,即晚一个数据,然后再将第一个寄存器中的数据取反与第二个寄存器的数据相与,产生的数存入一个新的寄存器里,这样产生的结果是当第一个寄存器中的数据由1变为0时,就会在新的寄存器里产生一个高电平,并维持一个周期。
    

例1:

reg[2:0] key_rst;

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

reg[2:0] key_rst_r;  //每个时钟周期的上升沿将low_sw信号锁存到low_sw_r中

always @ ( posedge clk  or negedge rst_n )
if (!rst_n) key_rst_r <= 3'b111;
else key_rst_r <= key_rst;
//当寄存器key_rst由1变为0时,led_an的值变为高,维持一个时钟周期
wire[2:0] key_an = key_rst_r & ( ~key_rst);

 

例2:

//说明:当三个独立按键的某一个被按下后,相应的LED被点亮;

//      再次按下后,LED熄灭,按键控制LED亮灭

 module sw_debounce(

            clk,rst_n,

            sw1_n,sw2_n,sw3_n,

            led_d1,led_d2,led_d3

            );

input   clk;    //主时钟信号,50MHz

input   rst_n;  //复位信号,低有效

input   sw1_n,sw2_n,sw3_n; //三个独立按键,低表示按下

output  led_d1,led_d2,led_d3;   //发光二极管,分别由按键控制 

//--------------------------------------------------------

reg[2:0] key_rst;  

 always @(posedge clk  or negedge rst_n)

    if (!rst_n) key_rst <= 3`b111;

    else key_rst <= {sw3_n,sw2_n,sw1_n};

reg[2:0] key_rst_r;       //每个时钟周期的上升沿将low_sw信号锁存到low_sw_r中 

always @ ( posedge clk  or negedge rst_n )

    if (!rst_n) key_rst_r <= 3`b111;

    else key_rst_r <= key_rst;   

//当寄存器key_rst由1变为0时,led_an的值变为高,维持一个时钟周期 

wire[2:0] key_an = key_rst_r & ( ~key_rst); 

//-----------------------------------------------------------------

reg[19:0]  cnt; //计数寄存器 

always @ (posedge clk  or negedge rst_n)

    if (!rst_n) cnt <= 20`d0;   //异步复位

    else if(key_an) cnt <=20`d0;

    else cnt <= cnt + 1`b1; 

reg[2:0] low_sw;

always @(posedge clk  or negedge rst_n)

    if (!rst_n) low_sw <= 3`b111;

    else if (cnt == 20`hfffff) //满20ms,将按键值锁存到寄存器low_sw中  cnt == 20'hfffff

      low_sw <= {sw3_n,sw2_n,sw1_n};     

//---------------------------------------------------------------

reg  [2:0] low_sw_r;       //每个时钟周期的上升沿将low_sw信号锁存到low_sw_r 

always @ ( posedge clk  or negedge rst_n )

    if (!rst_n) low_sw_r <= 3`b111;

    else low_sw_r <= low_sw;   

 //当寄存器low_sw由1变为0时,led_ctrl的值变为高,维持一个时钟周期 

wire[2:0] led_ctrl = low_sw_r[2:0] & ( ~low_sw[2:0]);

 reg d1;

reg d2;

reg d3;

  always @(posedge clk or negedge rst_n)

    if (!rst_n)

         begin

        d1 <= 1'b0;

        d2 <= 1'b0;

        d3 <= 1'b0;         end

    else

          begin           //某个按键值变化时,LED将做亮灭翻转

        if ( led_ctrl[0] ) d1 <= ~d1;   

        if ( led_ctrl[1] ) d2 <= ~d2;

        if ( led_ctrl[2] ) d3 <= ~d3;

     end

assign led_d3 = d1 ? 1`b1 : 1`b0;       //LED翻转输出

assign led_d2 = d2 ? 1`b1 : 1`b0;

assign led_d1 = d3 ? 1`b1 : 1`b0;

 endmodule




『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
无人机新突破:或将利用手机发射塔追踪无人机