实验要求:
1.全部点亮LED,数码管,LED点阵,持续三秒钟
2.全部熄灭LED,数码管,LED点阵
3.按下KEY1时,LED G16点亮,数码管从左到右循环滚动显示“HELLO”(速度为1秒)
4.按一下KEY2时,LED G15点亮,数码管滚动显示速度加快
5.按一下KEY3时,LED J15点亮,数码管滚动显示速度变慢
6.按一下KEY4时,LED K15点亮,数码管暂停滚动,保持当前状态
7.按一下KEY5时,LED K16点亮,16*16液晶点阵分时显示“重”“庆”二字,重和庆都分别显示一秒,之后反复循环显示“重”“庆”二字,不再熄灭
8.按一下KEY6时,熄灭数码管和16*16液晶点阵,8个LED灯进行闪烁显示(间隔0.5s)
1.1 开发环境
本次实验所涉及的开发软件为notepad++、QuartusII。硬件为“Spirit_V4开发板”,使用的语言为verilog语言
1.2 程序设计
module dynamic
(
input wire clk ,
input wire key_1,
input wire key_2,
input wire key_3,
input wire key_4,
input wire key_5,
input wire key_6,
output wire [5:0] sel,
output reg [7:0] seg,
output reg [7:0] led,
output reg shcp,
output reg stcp,
output wire oe ,
output reg ds ,
output reg [3:0] data_38
);
parameter CNT_MAX1 = 16'd49_999;
parameter CNT_MAX2 = 20'd999_999;
parameter CNT_MAX3 = 26'd49_999_999;
parameter CNT_MAX4 = 25'd24_999_999;
reg [15:0] cnt_1ms ;
reg [24:0] cnt_05s ;
reg [25:0] cnt_1s ;
reg [25:0] cnt_1s_2 ;
reg [2:0] cnt_4 ;
reg [2:0] cnt_5 ;
reg [3:0] cnt_15 ;
reg [2:0] cnt_num ;
reg [3:0] unit ;
reg [3:0] ten ;
reg [3:0] hun ;
reg [3:0] tho ;
reg [3:0] wan ;
reg [3:0] swan ;
reg [5:0] sel1 ;
reg [15:0] data_595;
initial
begin
cnt_1ms = 16'd0 ;
cnt_5 = 3'd0 ;
sel1 = 6'b000_000 ;
seg = 8'b1111_1111;
data_595 = 16'b1111_1111_1111_1111;
unit = 4'd0 ;
ten = 4'd0 ;
hun = 4'd0 ;
tho = 4'd0 ;
wan = 4'd0 ;
swan = 4'd0 ;
shcp = 1'b0 ;
stcp = 1'b0 ;
ds = 16'd0 ;
data_38 = 4'd0 ;
key5 = 1'b0 ;
cnt_05s = 25'd0 ;
key6 = 1'b0;
end
reg key1;
reg key2;
reg key3;
reg key4;
reg key5;
reg key6;
//设置按键信号, 当按键按下时,按键信号拉高,且按键低电平有效
always@(*)
if(key_2 == 1'b0 || key_3 == 1'b0 || key_4 == 1'b0 || key_5 == 1'b0 || key_6 == 1'b0)
key1 <= 1'b0;
else if(key_1 == 1'b0)
key1 <= 1'b1;
else
key1 <= key1;
always@(*)
if(key_1 == 1'b0 || key_3 == 1'b0 || key_4 == 1'b0 || key_5 == 1'b0 || key_6 == 1'b0)
key2 <= 1'b0;
else if(key_2 == 1'b0)
key2 <= 1'b1;
else
key2 <= key2;
always@(*)
if(key_2 == 1'b0 || key_1 == 1'b0 || key_4 == 1'b0 || key_5 == 1'b0 || key_6 == 1'b0)
key3 <= 1'b0;
else if(key_3 == 1'b0)
key3 <= 1'b1;
else
key3 <= key3;
always@(*)
if(key_2 == 1'b0 || key_3 == 1'b0 || key_1 == 1'b0 || key_5 == 1'b0 || key_6 == 1'b0)
key4 <= 1'b0;
else if(key_4 == 1'b0)
key4 <= 1'b1;
else
key4 <= key4;
always@(*)
if(key_2 == 1'b0 || key_3 == 1'b0 || key_4 == 1'b0 || key_1 == 1'b0 || key_6 == 1'b0)
key5 <= 1'b0;
else if(key_5 == 1'b0)
key5 <= 1'b1;
else
key5 <= key5;
always@(*)
if(key_2 == 1'b0 || key_3 == 1'b0 || key_4 == 1'b0 || key_1 == 1'b0 || key_5 == 1'b0)
key6 <= 1'b0;
else if(key_6 == 1'b0)
key6 <= 1'b1;
else
key6 <= key6;
parameter CNT_3S = 50'd149_999_999;
reg [50:0] cnt_3s;
//设置3s和0.5s计数器
always@(posedge clk)
if(cnt_3s > CNT_3S)
cnt_3s <= cnt_3s;
else
cnt_3s <= cnt_3s + 1'b1;
always@(posedge clk)
if((cnt_05s == CNT_MAX4) && (key6 == 1'b1))
cnt_05s <= 25'd0;
else if(key6 == 1'b1)
cnt_05s <= cnt_05s + 1'd1;
reg num;
//num用于key6按下时,led灯每0.5s间隔闪烁
always@(posedge clk)
if((cnt_05s == CNT_MAX4)&&(num == 1'b1))
num <= 1'b0;
else if(cnt_05s == CNT_MAX4)
num <= num + 1'b1;
//led代码模块
always@(posedge clk)
if(cnt_3s == CNT_3S)
led <= 8'b0000_0000;
else if(key1 == 1'b1)
led <= 8'b0111_1111;
else if(key2 == 1'b1)
led <= 8'b1011_1111;
else if(key3 == 1'b1)
led <= 8'b1101_1111;
else if(key4 == 1'b1)
led <= 8'b1110_1111;
else if(key5 == 1'b1)
led <= 8'b1111_0111;
else if((num == 1'b1)&&(key6 == 1'b1))
led <= 8'b0000_0000;
else if((num == 1'b0)&&(key6 == 1'b1))
led <= 8'b1111_1111;
else if(cnt_3s > CNT_3S)
led <= 8'b1111_1111;
always@(negedge clk)
if(cnt_1ms == CNT_MAX1)
cnt_1ms <= 16'd0;
else
cnt_1ms <= cnt_1ms + 1'd1;
parameter CNT_MAX = 24'd24_999_999;
//key2按下时,1秒计数时间加快,故设置为+100s,key3按下时速度变慢即返回原本速度
always@(negedge clk)
if(key2 == 1'b1)
cnt_1s <= cnt_1s + 100;
else if(cnt_1s >= CNT_MAX3)
cnt_1s <= 26'd0;
else if(key3 == 1'b1 && cnt_1s == CNT_MAX3)
cnt_1s <= 26'd0;
else if(key4 == 1'b1)
cnt_1s <= cnt_1s;
else if(key1 == 1'b1 || key2 == 1'b1 || key3 == 1'b1 || key4 == 1'b1 || key5 == 1'b1)
cnt_1s <= cnt_1s + 1'd1;
always@(negedge clk)
if(cnt_5 == 3'd5 && cnt_1ms == CNT_MAX1 - 1)
cnt_5 <= 3'd0;
else if(cnt_1ms == CNT_MAX1 - 1)
cnt_5 <= cnt_5 + 1'd1;
else;
//点阵条件
//四分频计数
always@(negedge clk)
if(cnt_4 == 3'd3)
cnt_4 <= 3'd0;
else
cnt_4 <= cnt_4 + 1'd1;
always@(posedge clk)
if(cnt_4 == 2'd3 && cnt_15 == 4'd15)
cnt_15 <= 4'd0;
else if(cnt_4 == 2'd3)
cnt_15 <= cnt_15 + 1'd1;
else;
//cnt_num控制点阵,当3s之后或者key6有效时不显示,1s计数完成后显示重庆二字
always@(negedge clk)
if(key6 == 1'b1 || cnt_3s == CNT_3S)
cnt_num <= 2'b1;
else if(cnt_1s == CNT_MAX3 - 1 && cnt_num == 2'd3)
cnt_num <= 2'd2;
else if(cnt_1s == CNT_MAX3 - 1 && key5 == 1'b1)
cnt_num <= cnt_num + 1'd1;
else if(cnt_1s == CNT_MAX3 - 1 )
cnt_num <= 2'd1;
else if((cnt_3s > CNT_3S)&&(key1==1'b0)&&(key2==1'b0)&&(key3==1'b0)&&(key4==1'b0)&&(key5==1'b0)&&(key6==1'b0))
cnt_num <= 2'b1;
//595驱动模块
always@(posedge clk)
if(cnt_4 >= 2'd2)
shcp <= 1'b1;
else
shcp <= 1'b0;
always@(posedge clk)
if(cnt_4 == 2'd3 && cnt_15 ==4'd15)
stcp <= 1'b1;
else if(cnt_4 == 2'd3 && cnt_15 == 4'd0)
stcp <= 1'b0;
else;
always@(posedge clk)
if(cnt_4 == 2'd0)
ds <= data_595[cnt_15];
else;
assign oe = 1'b0;
//动态扫描模块
always@(posedge clk)
if(data_38 == 4'd15 && cnt_1ms == CNT_MAX1 - 1)
data_38 <= 4'd0;
else if(cnt_1ms == CNT_MAX1 - 1)
data_38 <= data_38 + 1'd1;
else;
//位选信号
assign sel = ~sel1;
always@(negedge clk)
if(cnt_1ms == CNT_MAX1 - 1 && cnt_5 == 3'd0)
sel1 <= 6'b100_000;
else if(cnt_1ms == CNT_MAX1 - 1)
sel1 <= sel1 >> 1;
else;
//数码管动态显示
reg [10:0] data;
always@(negedge clk)
if(cnt_1s == CNT_MAX3 - 1 && data == 11'd11)
data <= 11'd6;
else if(cnt_1s == CNT_MAX3 - 1)
data <= data + 1'd1;
else;
//HELLO循环显示
always@(negedge clk)
if(cnt_3s <= CNT_3S)
begin
swan <= 4'd6;
wan <= 4'd6;
tho <= 4'd6;
hun <= 4'd6;
ten <= 4'd6;
unit <= 4'd6;
end
else if(key6 == 1'b1)
begin
swan <= 4'd0;
wan <= 4'd0;
tho <= 4'd0;
hun <= 4'd0;
ten <= 4'd0;
unit <= 4'd0;
end
else if(data == 11'd0)
begin
swan <= 4'd0;
wan <= 4'd0;
tho <= 4'd0;
hun <= 4'd0;
ten <= 4'd0;
unit <= 4'd0;
end
else if(data == 11'd1)
begin
swan <= 4'd5;
wan <= 4'd0;
tho <= 4'd0;
hun <= 4'd0;
ten <= 4'd0;
unit <= 4'd0;
end
else if(data == 11'd2)
begin
swan <= 4'd4;
wan <= 4'd5;
tho <= 4'd0;
hun <= 4'd0;
ten <= 4'd0;
unit <= 4'd0;
end
else if(data == 11'd3)
begin
swan <= 4'd3;
wan <= 4'd4;
tho <= 4'd5;
hun <= 4'd0;
ten <= 4'd0;
unit <= 4'd0;
end
else if(data == 11'd4)
begin
swan <= 4'd2;
wan <= 4'd3;
tho <= 4'd4;
hun <= 4'd5;
ten <= 4'd0;
unit <= 4'd0;
end
else if(data == 11'd5)
begin
swan <= 4'd1;
wan <= 4'd2;
tho <= 4'd3;
hun <= 4'd4;
ten <= 4'd5;
unit <= 4'd0;
end
else if(data == 11'd6)
begin
swan <= 4'd0;
wan <= 4'd1;
tho <= 4'd2;
hun <= 4'd3;
ten <= 4'd4;
unit <= 4'd5;
end
else if(data == 11'd7)
begin
swan <= 4'd5;
wan <= 4'd0;
tho <= 4'd1;
hun <= 4'd2;
ten <= 4'd3;
unit <= 4'd4;
end
else if(data == 11'd8)
begin
swan <= 4'd4;
wan <= 4'd5;
tho <= 4'd0;
hun <= 4'd1;
ten <= 4'd2;
unit <= 4'd3;
end
else if(data == 11'd9)
begin
swan <= 4'd3;
wan <= 4'd4;
tho <= 4'd5;
hun <= 4'd0;
ten <= 4'd1;
unit <= 4'd2;
end
else if(data == 11'd10)
begin
swan <= 4'd2;
wan <= 4'd3;
tho <= 4'd4;
hun <= 4'd5;
ten <= 4'd0;
unit <= 4'd1;
end
else if(data == 11'd11)
begin
swan <= 4'd1;
wan <= 4'd2;
tho <= 4'd3;
hun <= 4'd4;
ten <= 4'd5;
unit <= 4'd0;
end
else if(key6 == 1'b1)
begin
swan <= 4'd0;
wan <= 4'd0;
tho <= 4'd0;
hun <= 4'd0;
ten <= 4'd0;
unit <= 4'd0;
end
else if(cnt_3s > CNT_3S)
begin
swan <= 4'd0;
wan <= 4'd0;
tho <= 4'd0;
hun <= 4'd0;
ten <= 4'd0;
unit <= 4'd0;
end
always@(negedge clk)
if(sel == 6'b011_111)
case(swan)
4'd0 : seg <= 8'b1111_1111;//不显示
4'd1 : seg <= 8'b1001_0001;//H
4'd2 : seg <= 8'b0110_0001;//E
4'd3 : seg <= 8'b1110_0011;//L
4'd4 : seg <= 8'b1110_0011;//L
4'd5 : seg <= 8'b0000_0011;//O
4'd6 : seg <= 8'b0000_0000;//全亮
endcase
else if(sel == 6'b101_111)
case(wan)
4'd0 : seg <= 8'b1111_1111;
4'd1 : seg <= 8'b1001_0001;
4'd2 : seg <= 8'b0110_0001;
4'd3 : seg <= 8'b1110_0011;
4'd4 : seg <= 8'b1110_0011;
4'd5 : seg <= 8'b0000_0011;
4'd6 : seg <= 8'b0000_0000;
endcase
else if(sel == 6'b110_111)
case(tho)
4'd0 : seg <= 8'b1111_1111;
4'd1 : seg <= 8'b1001_0001;
4'd2 : seg <= 8'b0110_0001;
4'd3 : seg <= 8'b1110_0011;
4'd4 : seg <= 8'b1110_0011;
4'd5 : seg <= 8'b0000_0011;
4'd6 : seg <= 8'b0000_0000;
endcase
else if(sel == 6'b111_011)
case(hun)
4'd0 : seg <= 8'b1111_1111;
4'd1 : seg <= 8'b1001_0001;
4'd2 : seg <= 8'b0110_0001;
4'd3 : seg <= 8'b1110_0011;
4'd4 : seg <= 8'b1110_0011;
4'd5 : seg <= 8'b0000_0011;
4'd6 : seg <= 8'b0000_0000;
endcase
else if(sel == 6'b111_101)
case(ten)
4'd0 : seg <= 8'b1111_1111;
4'd1 : seg <= 8'b1001_0001;
4'd2 : seg <= 8'b0110_0001;
4'd3 : seg <= 8'b1110_0011;
4'd4 : seg <= 8'b1110_0011;
4'd5 : seg <= 8'b0000_0011;
4'd6 : seg <= 8'b0000_0000;
endcase
else if(sel == 6'b111_110)
case(unit)
4'd0 : seg <= 8'b1111_1111;
4'd1 : seg <= 8'b1001_0001;
4'd2 : seg <= 8'b0110_0001;
4'd3 : seg <= 8'b1110_0011;
4'd4 : seg <= 8'b1110_0011;
4'd5 : seg <= 8'b0000_0011;
4'd6 : seg <= 8'b0000_0000;
endcase
//点阵数据显示模块
always@(posedge clk)
if(cnt_num == 2'd0)
case(data_38)
4'd0 :data_595 <= 16'b0000_0000_0000_0000;
4'd2 :data_595 <= 16'b0000_0000_0000_0000;
4'd4 :data_595 <= 16'b0000_0000_0000_0000;
4'd6 :data_595 <= 16'b0000_0000_0000_0000;
4'd8 :data_595 <= 16'b0000_0000_0000_0000;
4'd10 :data_595 <= 16'b0000_0000_0000_0000;
4'd12 :data_595 <= 16'b0000_0000_0000_0000;
4'd14 :data_595 <= 16'b0000_0000_0000_0000;
4'd1 :data_595 <= 16'b0000_0000_0000_0000;
4'd3 :data_595 <= 16'b0000_0000_0000_0000;
4'd5 :data_595 <= 16'b0000_0000_0000_0000;
4'd7 :data_595 <= 16'b0000_0000_0000_0000;
4'd9 :data_595 <= 16'b0000_0000_0000_0000;
4'd11 :data_595 <= 16'b0000_0000_0000_0000;
4'd13 :data_595 <= 16'b0000_0000_0000_0000;
4'd15 :data_595 <= 16'b0000_0000_0000_0000;
endcase
else if(cnt_num==2'd1)
case(data_38)
4'd0 :data_595 <= 16'b1111_1111_1111_1111;
4'd2 :data_595 <= 16'b1111_1111_1111_1111;
4'd4 :data_595 <= 16'b1111_1111_1111_1111;
4'd6 :data_595 <= 16'b1111_1111_1111_1111;
4'd8 :data_595 <= 16'b1111_1111_1111_1111;
4'd10 :data_595 <= 16'b1111_1111_1111_1111;
4'd12 :data_595 <= 16'b1111_1111_1111_1111;
4'd14 :data_595 <= 16'b1111_1111_1111_1111;
4'd1 :data_595 <= 16'b1111_1111_1111_1111;
4'd3 :data_595 <= 16'b1111_1111_1111_1111;
4'd5 :data_595 <= 16'b1111_1111_1111_1111;
4'd7 :data_595 <= 16'b1111_1111_1111_1111;
4'd9 :data_595 <= 16'b1111_1111_1111_1111;
4'd11 :data_595 <= 16'b1111_1111_1111_1111;
4'd13 :data_595 <= 16'b1111_1111_1111_1111;
4'd15 :data_595 <= 16'b1111_1111_1111_1111;
endcase
else if(cnt_num == 2'd2)
case(data_38)
4'd0 :data_595 <= 16'hFFF7;
4'd2 :data_595 <= 16'hFFE0;
4'd4 :data_595 <= 16'h03FF;
4'd6 :data_595 <= 16'h7FFF;
4'd8 :data_595 <= 16'h0080;
4'd10 :data_595 <= 16'h7FFF;
4'd12 :data_595 <= 16'h07F0;
4'd14 :data_595 <= 16'h77F7;
4'd1 :data_595 <= 16'h07F0;
4'd3 :data_595 <= 16'h77F7;
4'd5 :data_595 <= 16'h07F0;
4'd7 :data_595 <= 16'h7FFF;
4'd9 :data_595 <= 16'h03E0;
4'd11 :data_595 <= 16'h7FFF;
4'd13 :data_595 <= 16'h0080;
4'd15 :data_595 <= 16'hFFFF;
endcase
else if(cnt_num == 2'd3)
case(data_38)
4'd0 :data_595 <= 16'h7FFF;
4'd2 :data_595 <= 16'hFFFE;
4'd4 :data_595 <= 16'h0380;
4'd6 :data_595 <= 16'hFBFF;
4'd8 :data_595 <= 16'hFBFE;
4'd10 :data_595 <= 16'hFBFE;
4'd12 :data_595 <= 16'hFBFE;
4'd14 :data_595 <= 16'h0BC0;
4'd1 :data_595 <= 16'hFBFE;
4'd3 :data_595 <= 16'h7BFD;
4'd5 :data_595 <= 16'h7BFD;
4'd7 :data_595 <= 16'hBBFB;
4'd9 :data_595 <= 16'hBDFB;
4'd11 :data_595 <= 16'hDDF7;
4'd13 :data_595 <= 16'hEEEF;
4'd15 :data_595 <= 16'hF79F;
endcase
endmodule
1.3绑定引脚
文章来源:https://www.toymoban.com/news/detail-555512.html
注:本文章设计还存在一定问题,仅供参考文章来源地址https://www.toymoban.com/news/detail-555512.html
到了这里,关于FPGA动态显示——点阵的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!