热度 1
2022-7-20 06:09
2592 次阅读|
8 个评论
1.简介 按键为何消抖,原因是当按键按下和松开时,由于弹片回弹抖动,而导致按键对应管脚误判为多次按下和松开。 从以下动图对比可以看出: 2.原理 如图,我们认为的按键波形是理想的,然而其实正真的实际波形是每次按下和弹起都是由回弹的,如图实际波形其实也是理想化的,为了方便理解。 既然有回弹,那么怎么避免呢?一般采用方式为延时法。C语言最直接直接一个delay就完事了,简单粗暴。在FPGA里,使用延时+判断的方式,既延时完后再次判断是否已经稳定。 3.源代码 3.1状态机转移图 3.2实现 3.2.1延时模块 //计数延迟5ms always @( posedge clk or negedge rst_n ) begin if ( rst_n == 1'b0 ) delay_cnt <= 20'd0 ; else if ( cnt_start == 1'b1 ) delay_cnt <= delay_cnt + 20'd1 ; else delay_cnt <= 20'd0 ; end always @( posedge clk or negedge rst_n ) begin if ( rst_n == 1'b0 ) cnt_finish <= 1'b0 ; else if ( delay_cnt == 20'd499999 ) cnt_finish <= 1'b1 ; else cnt_finish <= 1'b0 ; end //FSM for the key always @( posedge clk or negedge rst_n ) begin if ( rst_n == 1'b0 ) begin state <= IDLE ; cnt_start <= 1'b0 ; key_o_r <= 1'b1 ; end else case ( state ) IDLE : begin if ( key_neg == 1'b1 ) begin cnt_start <= 1'b1 ; state <= FILTER0 ; end else state <= IDLE ; end FILTER0 : begin if ( cnt_finish == 1'b1 ) begin cnt_start <= 1'b0 ; key_o_r <= 1'b0 ; state <= DOWN ; end else if ( key_pos == 1'b1 ) begin state <= IDLE ; cnt_start <= 1'b0 ; end else begin state <= FILTER0 ; end end DOWN : begin if ( key_pos == 1'b1 ) begin state <= FILTER1 ; cnt_start <= 1'b1 ; end else begin state <= DOWN ; end end FILTER1 : begin if ( cnt_finish == 1'b1 ) begin cnt_start <= 1'b0 ; state <= IDLE ; key_o_r <= 1'b1 ; end else if ( key_neg == 1'b1 ) begin state <= DOWN ; cnt_start <= 1'b0 ; end else begin state <= FILTER1 ; end end default : begin state <= IDLE ; key_o_r <= 1'b1 ; cnt_start <= 1'b0 ; end endcase end