FPGA学习之按键控制
这几天状态不是很好。效率很低。
之前又忙于给本科生做毕设,有关于生理信号的检测的一个东西,感觉很头疼。最近一段时间感觉又可以把这个放下一段时间了。
根据之前的计划,暂时补充一个简单的按键控制数码管显示的程序,程序经过验证,也经过了消抖
本想通过状态机进行消抖,但是暂时还是通过简单的20ms的delay,其实是一样的。
程序很简单,主要实现的功能就是按键控制数码管从0到9进行循环显示。但是今天晚上也是调试了我好长一段的时间。
module Key_Smg(
input clk,rst_n,
input Keyin,
output smgen,
output [7:0] KeyData
);
assign smgen = 0;
wire Key_S;
reg Key_D;
wire Key_down;
always @(posedge clk or negedge rst_n)
if(!rst_n)
begin
Key_D <= 1'b1;
end
else
Key_D <= Keyin;
reg Key_D_t;
always @(posedge clk or negedge rst_n)
if(!rst_n)
begin
Key_D_t <= 1'b1;
end
else
Key_D_t <= Key_D;
assign Key_S = Key_D_t && (~Key_D); //检测按键的按下
reg [15:0] delay_r;
reg [4:0] delay_cnt_r;
always @(posedge clk or negedge rst_n)
if(!rst_n)
begin
delay_r <= 16'd0;
end
else if(Key_S)
delay_r <= 16'd0;
else if(delay_r == 16'hC350)
delay_r <= 16'd0;
else
delay_r <= delay_r + 1'b1;
always @(posedge clk or negedge rst_n)
if(!rst_n)
begin
delay_cnt_r <= 5'd0;
end
else
if(Key_S || (delay_cnt_r == 5'd20)) delay_cnt_r <= 5'd0;
else
if(delay_r == 16'hC350)
delay_cnt_r <= delay_cnt_r + 1'b1;
else
delay_r <= delay_r;
reg Key_D2;
always @(posedge clk or negedge rst_n)
if(!rst_n)
Key_D2 <= 1'b1;
else if(delay_cnt_r == 5'd20)
Key_D2 <= Keyin;
reg Key_D2_t;
always @(posedge clk or negedge rst_n)
if(!rst_n)
Key_D2_t <= 1'b1;
else
Key_D2_t <= Key_D2;
assign Key_down = Key_D2_t && (~Key_D2); //消抖后确定有键按下
// 数码管显示控制部分//////////////////////////////
reg [3:0] Smgbit;
always @(posedge clk or negedge rst_n)
if(!rst_n)
begin
Smgbit <= 4'd0;
end
else if(Key_down)
if(Smgbit == 4'd9)
Smgbit <= 4'd0;
else
Smgbit <= Smgbit + 1'b1;
else
Smgbit <= Smgbit;
reg [7:0] timedata_r;
assign KeyData = timedata_r;
always @(posedge clk or negedge rst_n)
if(!rst_n)
begin
timedata_r <= 8'hff;
end
else
case(Smgbit)
4'b0000 : timedata_r <= 8'hC0; //0
4'b0001 : timedata_r <= 8'hF9; //1
4'b0010 : timedata_r <= 8'hA4; //2
4'b0011 : timedata_r <= 8'hB0; //3
4'b0100 : timedata_r <= 8'h99; //4
4'b0101 : timedata_r <= 8'h92; //5
4'b0110 : timedata_r <= 8'h82; //6
4'b0111 : timedata_r <= 8'hF8; //7
4'b1000 : timedata_r <= 8'h80; //8
4'b1001 : timedata_r <= 8'h90; //9
4'b1010 : timedata_r <= 8'hBF; //-
default : timedata_r <= 8'hff;
endcase
endmodule