fpga verilog的按键消抖问题

fpga verilog的按键消抖问题,第1张

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

问题出在

else if(swt != 3'b111)

begin

swt <= {key_a,key_b,key_c}; //取键值

flag <= 1; //开始按下,不管处于抖动与否

end

由于swt的值复位后就是3'b111了,一直没改变,所以 if(swt != 3'b111)不会成立

先进行分频,如果的fpga是50MHZ的,那么

always @(posedge clk)

begin

if(count==18'b111110100000000000)

begin clk25=~clk25;count<=25'b0; end

else

count<=count+1;

end

下面的时钟都用clk25,进行十进制转换,比如,

always @(posedge clk25)

begin if(a1==4'd9) begin a1<=0; a2<a2+1;else a1<=a1+1;

if(a2==4'd9) begin a2<=0;a3<=a3+1;

以此类推,就可实现4位动态显示(数是在0~9内),一个一个字打的,不容易,采纳啊。。。

FPGA的逻辑门翻转速度非常快,而按键的电平能够稳定下来需要上百个毫秒。这两个时间根本不在一个数量级,所以,建议你增加一个延时的判断,也就是抓到下降沿后延时100个毫秒再输出结果,这样后面的功能就不会抖了。

以上就是关于fpga verilog的按键消抖问题全部的内容,包括:fpga verilog的按键消抖问题、FPGA按键消抖问题、设计一个FPGA计时器程序等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zz/9781411.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-01
下一篇 2023-05-01

发表评论

登录后才能评论

评论列表(0条)

保存