基于基于FPGA的键盘输入的键盘输入verilog代码代码
通过对系统时钟提供的频率进行分频,分别为键盘扫描电路和弹跳消除电路提供时钟信号,键盘扫描电路通过
由键盘扫描时钟信号控制不断产生的键盘扫描信号对键盘进行行扫描,同时弹跳消除电路实时的对键盘的按键
列信号进行采集。
module key_scanf(clk,reset_n,k1,k2,k3,k4,width,prioed);
input clk;
input reset_n;
input k1,k2,k3,k4;
output[15:0] width,prioed;
reg[3:0] key_rst_n;
always @(posedge clk or negedge reset_n)
if(!reset_n) key_rst_n<=4'b1111; //an jianchushiquan1
else key_rst_n<={k4,k3,k2,k1};
reg[3:0] key_rst_n_r;
always @(posedge clk or negedge reset_n)
if(!reset_n) key_rst_n_r<=4'b1111;
else key_rst_n_r<=key_rst_n; //suo cun liang ji
//jianzhi
wire[3:0] key_an=(~key_rst_n_r)&key_rst_n; //下降沿產生高電平
reg[19:0] cnt; //20位計數寄存器
always @(posedge clk or negedge reset_n)
if(!reset_n) cnt<=20'd0;
else if(key_an) cnt<=20'd0; //按鍵按下計數器清零
else cnt<=cnt+1'b1;
//*******第一次檢測到的按鍵觸發用於清零計數器,以此用來達到當剛按下20ms后按鍵消抖的目的
reg[3:0] low_sw;
always @(posedge clk or negedge reset_n)
if(!reset_n) low_sw<=4'b1111;
else if(cnt==20'hfffff)
low_sw<={k1,k2,k3,k4}; //每20ms鎖存當前按鍵值
reg[3:0]low_sw_r;
always @(posedge clk or negedge reset_n)
if(!reset_n) low_sw_r<=4'b1111;
else low_sw_r<=low_sw; //鎖存上個週期按鍵值
wire[3:0] led_ctrl=(~low_sw_r[3:0])&low_sw[3:0];
//****第二次檢測按鍵按下用於確認按鍵按下
reg[15:0] width_r;
reg[15:0] prioed_r;
always @(posedge clk or negedge reset_n)
if(!reset_n) begin
width_r<=16'b0100000000000000;
prioed_r<=16'b1000000000100000;
end
else begin
if(led_ctrl[0]) width_r<=width_r+16'b0000100000000000;
if(led_ctrl[1]) width_r<=width_r-16'b0000100000000000;
if(led_ctrl[2]) prioed_r<=prioed_r+16'b0000100000000000;
if(led_ctrl[3]) prioed_r<=prioed_r-16'b0000100000000000;
end
assign width=width_r;
assign prioed=prioed_r;
endmodule