基于FPGA的数码管动态扫描程序与按键消抖程序
数码管动态扫描程序
module seg_scan(
input clk ,
input rst_n ,
output reg [ 5:0] seg_sel ,
output reg [ 7:0] seg_bin ,
input [ 4:0] seg_date_0 ,
input [ 4:0] seg_date_1 ,
input [ 4:0] seg_date_2 ,
input [ 4:0] seg_date_3 ,
input [ 4:0] seg_date_4 ,
input [ 4:0] seg_date_5
);
reg [ 7:0] seg_bin_0 ;
reg [ 7:0] seg_bin_1 ;
reg [ 7:0] seg_bin_2 ;
reg [ 7:0] seg_bin_3 ;
reg [ 7:0] seg_bin_4 ;
reg [ 7:0] seg_bin_5 ;
parameter SCAN_CLK = 1000 ;
parameter SYS_CLK = 50000000 ;
parameter SCAN_COUNT = SYS_CLK / SCAN_CLK - 1;
reg [31:0] scan_time ;
reg [ 3:0] scan_sel ;
always@(posedge clk or negedge rst_n)begin
if(rst_n == 1'b0)begin
scan_time <= 32'd0;
scan_sel <= 4'd0;
end
else if(scan_time >= SCAN_COUNT)begin
scan_time <= 32'd0;
if(scan_sel == 4'd5)
scan_sel <= 4'd0;
else
scan_sel <= scan_sel + 4'd1;
end
else begin
scan_time <= scan_time + 32'd1;
end
end
always@(posedge clk or negedge rst_n)begin
if(rst_n == 1'b0)begin
seg_sel <= 6'b111111;
seg_bin <= 8'hff;
end
else begin
case(scan_sel)
4'd0:begin
seg_sel <= 6'b11_1110;
seg_bin <= seg_bin_0;
end
4'd1:begin
seg_sel <= 6'b11_1101;
seg_bin <= seg_bin_1;
end
4'd2:begin
seg_sel <= 6'b11_1011;
seg_bin <= seg_bin_2;
end
4'd3:begin
seg_sel <= 6'b11_0111;
seg_bin <= seg_bin_3;
end
4'd4:begin
seg_sel <= 6'b10_1111;
seg_bin <= seg_bin_4;
end
4'd5:begin
seg_sel <= 6'b01_1111;
seg_bin <= seg_bin_5;
end
default:begin
seg_sel <= 6'b11_1111;
seg_bin <= 8'hff;
end
endcase
end
end
always@(*)begin
case(seg_date_0)
5'd0 :seg_bin_0 <= 8'b1100_0000;
5'd1 :seg_bin_0 <= 8'b1111_1001;
5'd2 :seg_bin_0 <= 8'b1010_0100;
5'd3 :seg_bin_0 <= 8'b1011_0000;
5'd4 :seg_bin_0 <= 8'b1001_1001;
5'd5 :seg_bin_0 <= 8'b1001_0010;
5'd6 :seg_bin_0 <= 8'b1000_0010;
5'd7 :seg_bin_0 <= 8'b1111_1000;
5'd8 :seg_bin_0 <= 8'b1000_0000;
5'd9 :seg_bin_0 <= 8'b1001_0000;
5'd10 :seg_bin_0 <= 8'b1000_1000;
5'd11 :seg_bin_0 <= 8'b1000_0011;
5'd12 :seg_bin_0 <= 8'b1100_0110;
5'd13 :seg_bin_0 <= 8'b1010_0001;
5'd14 :seg_bin_0 <= 8'b1000_0110;
5'd15 :seg_bin_0 <= 8'b1000_1110;
5'd16 :seg_bin_0 <= 8'b1011_1111;
5'd17 :seg_bin_0 <= 8'b1111_0111;
5'd31 :seg_bin_0 <= 8'b1111_1111;
default:seg_bin_0 <= 8'b1111_1111;
endcase
end
always@(*)begin
case(seg_date_1)
5'd0 :seg_bin_1 <= 8'b1100_0000;
5'd1 :seg_bin_1 <= 8'b1111_1001;
5'd2 :seg_bin_1 <= 8'b1010_0100;
5'd3 :seg_bin_1 <= 8'b1011_0000;
5'd4 :seg_bin_1 <= 8'b1001_1001;
5'd5 :seg_bin_1 <= 8'b1001_0010;
5'd6 :seg_bin_1 <= 8'b1000_0010;
5'd7 :seg_bin_1 <= 8'b1111_1000;
5'd8 :seg_bin_1 <= 8'b1000_0000;
5'd9 :seg_bin_1 <= 8'b1001_0000;
5'd10 :seg_bin_1 <= 8'b1000_1000;
5'd11 :seg_bin_1 <= 8'b1000_0011;
5'd12 :seg_bin_1 <= 8'b1100_0110;
5'd13 :seg_bin_1 <= 8'b1010_0001;
5'd14 :seg_bin_1 <= 8'b1000_0110;
5'd15 :seg_bin_1 <= 8'b1000_1110;
5'd16 :seg_bin_1 <= 8'b1011_1111;
5'd17 :seg_bin_1 <= 8'b1111_0111;
5'd31 :seg_bin_0 <= 8'b1111_1111;
default:seg_bin_1 <= 8'b1111_1111;
endcase
end
always@(*)begin
case(seg_date_2)
5'd0 :seg_bin_2 <= 8'b1100_0000;
5'd1 :seg_bin_2 <= 8'b1111_1001;
5'd2 :seg_bin_2 <= 8'b1010_0100;
5'd3 :seg_bin_2 <= 8'b1011_0000;
5'd4 :seg_bin_2 <= 8'b1001_1001;
5'd5 :seg_bin_2 <= 8'b1001_0010;
5'd6 :seg_bin_2 <= 8'b1000_0010;
5'd7 :seg_bin_2 <= 8'b1111_1000;
5'd8 :seg_bin_2 <= 8'b1000_0000;
5'd9 :seg_bin_2 <= 8'b1001_0000;
5'd10 :seg_bin_2 <= 8'b1000_1000;
5'd11 :seg_bin_2 <= 8'b1000_0011;
5'd12 :seg_bin_2 <= 8'b1100_0110;
5'd13 :seg_bin_2 <= 8'b1010_0001;
5'd14 :seg_bin_2 <= 8'b1000_0110;
5'd15 :seg_bin_2 <= 8'b1000_1110;
5'd16 :seg_bin_2 <= 8'b1011_1111;
5'd17 :seg_bin_2 <= 8'b1111_0111;
5'd31 :seg_bin_0 <= 8'b1111_1111;
default:seg_bin_2 <= 8'b1111_1111;
endcase
end
always@(*)begin
case(seg_date_3)
5'd0 :seg_bin_3 <= 8'b1100_0000;
5'd1 :seg_bin_3 <= 8'b1111_1001;
5'd2 :seg_bin_3 <= 8'b1010_0100;
5'd3 :seg_bin_3 <= 8'b1011_0000;
5'd4 :seg_bin_3 <= 8'b1001_1001;
5'd5 :seg_bin_3 <= 8'b1001_0010;
5'd6 :seg_bin_3 <= 8'b1000_0010;
5'd7 :seg_bin_3 <= 8'b1111_1000;
5'd8 :seg_bin_3 <= 8'b1000_0000;
5'd9 :seg_bin_3 <= 8'b1001_0000;
5'd10 :seg_bin_3 <= 8'b1000_1000;
5'd11 :seg_bin_3 <= 8'b1000_0011;
5'd12 :seg_bin_3 <= 8'b1100_0110;
5'd13 :seg_bin_3 <= 8'b1010_0001;
5'd14 :seg_bin_3 <= 8'b1000_0110;
5'd15 :seg_bin_3 <= 8'b1000_1110;
5'd16 :seg_bin_3 <= 8'b1011_1111;
5'd17 :seg_bin_3 <= 8'b1111_0111;
5'd31 :seg_bin_0 <= 8'b1111_1111;
default:seg_bin_3 <= 8'b1111_1111;
endcase
end
always@(*)begin
case(seg_date_4)
5'd0 :seg_bin_4 <= 8'b1100_0000;
5'd1 :seg_bin_4 <= 8'b1111_1001;
5'd2 :seg_bin_4 <= 8'b1010_0100;
5'd3 :seg_bin_4 <= 8'b1011_0000;
5'd4 :seg_bin_4 <= 8'b1001_1001;
5'd5 :seg_bin_4 <= 8'b1001_0010;
5'd6 :seg_bin_4 <= 8'b1000_0010;
5'd7 :seg_bin_4 <= 8'b1111_1000;
5'd8 :seg_bin_4 <= 8'b1000_0000;
5'd9 :seg_bin_4 <= 8'b1001_0000;
5'd10 :seg_bin_4 <= 8'b1000_1000;
5'd11 :seg_bin_4 <= 8'b1000_0011;
5'd12 :seg_bin_4 <= 8'b1100_0110;
5'd13 :seg_bin_4 <= 8'b1010_0001;
5'd14 :seg_bin_4 <= 8'b1000_0110;
5'd15 :seg_bin_4 <= 8'b1000_1110;
5'd16 :seg_bin_4 <= 8'b1011_1111;
5'd17 :seg_bin_4 <= 8'b1111_0111;
5'd31 :seg_bin_0 <= 8'b1111_1111;
default:seg_bin_4 <= 8'b1111_1111;
endcase
end
always@(*)begin
case(seg_date_5)
5'd0 :seg_bin_5 <= 8'b1100_0000;
5'd1 :seg_bin_5 <= 8'b1111_1001;
5'd2 :seg_bin_5 <= 8'b1010_0100;
5'd3 :seg_bin_5 <= 8'b1011_0000;
5'd4 :seg_bin_5 <= 8'b1001_1001;
5'd5 :seg_bin_5 <= 8'b1001_0010;
5'd6 :seg_bin_5 <= 8'b1000_0010;
5'd7 :seg_bin_5 <= 8'b1111_1000;
5'd8 :seg_bin_5 <= 8'b1000_0000;
5'd9 :seg_bin_5 <= 8'b1001_0000;
5'd10 :seg_bin_5 <= 8'b1000_1000;
5'd11 :seg_bin_5 <= 8'b1000_0011;
5'd12 :seg_bin_5 <= 8'b1100_0110;
5'd13 :seg_bin_5 <= 8'b1010_0001;
5'd14 :seg_bin_5 <= 8'b1000_0110;
5'd15 :seg_bin_5 <= 8'b1000_1110;
5'd16 :seg_bin_5 <= 8'b1011_1111;
5'd17 :seg_bin_5 <= 8'b1111_0111;
5'd31 :seg_bin_0 <= 8'b1111_1111;
default:seg_bin_5 <= 8'b1111_1111;
endcase
end
endmodule
按键消抖程序
module key_filter(
input clk ,
input rst_n ,
input key_in ,
output reg key_fs
);
reg key_flag ;
reg key_state ;
reg [ 3:0] state ;
reg [19:0] cnt_20ms ;
reg en_cnt ;
reg key_tmpa, key_tmpb ;
wire pedge, nedge ;
reg cnt_full ;
reg key_in_sa,key_in_sb ;
localparam
IDEL = 4'b0001,
FILTER0 = 4'b0010,
DOWN = 4'b0100,
FILTER1 = 4'b1000;
always@(posedge clk or negedge rst_n)
if(rst_n == 1'b0)begin
key_in_sa <= 1'b0;
key_in_sb <= 1'b0;
end
else begin
key_in_sa <= key_in;
key_in_sb <= key_in_sa;
end
always@(posedge clk or negedge rst_n)begin
if(rst_n == 1'b0)begin
key_tmpa <= 1'b0;
key_tmpb <= 1'b0;
end
else begin
key_tmpa <= key_in_sb;
key_tmpb <= key_tmpa;
end
end
assign nedge = key_tmpa & (!key_tmpb);
assign pedge = !key_tmpa & key_tmpb ;
always@(posedge clk or negedge rst_n)begin
if(rst_n == 1'b0)begin
en_cnt <= 1'b0;
state <= IDEL;
key_flag <= 1'b0;
key_state <= 1'b1;
end
else begin
case(state)
IDEL :begin
key_flag <= 1'b0;
if(nedge)begin
state <= FILTER0;
en_cnt <= 1'b1;
end
else
state <= IDEL;
end
FILTER0:begin
if(cnt_full)begin
key_flag <= 1'b1;
key_state <= 1'b0;
en_cnt <= 1'b0;
state <= DOWN;
end
else if(pedge)begin
state <= IDEL;
en_cnt <= 1'b0;
end
else
state <= FILTER0;
end
DOWN :begin
key_flag <= 1'b0;
if(pedge)begin
state <= FILTER1;
en_cnt <= 1'b1;
end
else
state <= DOWN;
end
FILTER1:begin
if(cnt_full)begin
key_flag <= 1'b1;
key_state <= 1'b1;
en_cnt <= 1'b0;
state <= IDEL;
end
else if(nedge)begin
en_cnt <= 1'b0;
state <= DOWN;
end
else
state <= FILTER1;
end
default:begin
state <= IDEL;
en_cnt <= 1'b0;
key_flag <= 1'b0;
key_state <= 1'b1;
end
endcase
end
end
always@(posedge clk or negedge rst_n)begin
if(rst_n == 1'b0)begin
key_fs <= 0;
end
else begin
key_fs <= key_flag && (!key_state);
end
end
always@(posedge clk or negedge rst_n)begin
if(rst_n == 1'b0)
cnt_20ms <= 20'd0;
else if(en_cnt)
cnt_20ms <= cnt_20ms + 1'b1;
else
cnt_20ms <= 20'd0;
end
always@(posedge clk or negedge rst_n)begin
if(rst_n == 1'b0)
cnt_full <= 1'b0;
else if(cnt_20ms == 999_999)
cnt_full <= 1'b1;
else
cnt_full <= 1'b0;
end
endmodule