FPGA学习——数码管显示
结构框架
数码管动态显示采用了人眼暂存的原理,即时分复用,在数码管实现动态显示。
整个实验设计流程框架如下图所示:
一、硬件设计
开发板采用共阳极数码管,即低电平点亮。
二、verilog编写
1.计数器
本实验准备设计一个定时器,6为数码管显示24小时制的时间,所以编写一个计数模块。
module counter_10
#(
parameter COUNT = 4'd9
)
(
input clk,
input rst_n,
input en,
input clr,
output reg[3:0] count,
output reg t
);
always@(posedge clk or negedge rst_n)
begin
if(rst_n == 1'b0)
begin
count <= 4'd0;
t <= 1'b0;
end
else if(clr == 1'b1)
begin
count <= 4'd0;
t <= 1'b0;
end
else if(en== 1'b1)
if(count == COUNT)
begin
count <= 4'd0;
t <= 1'b1;
end
else
begin
count <= count + 4'd1;
t <= 1'b0;
end
else
begin
count <= count;
t <= 1'b0;
end
end
endmodule
改变变量COUNT的数值,可实现不同模的计数器。
2.译码模块
module seg_decoder
(
input [3:0] bin_data,
output reg [7:0] seg_data
);
always@(*)
begin
case(bin_data)
4'd0:seg_data <= 8'b1100_0000;
4'd1:seg_data <= 8'b1111_1001;
4'd2:seg_data <= 8'b1010_0100;
4'd3:seg_data <= 8'b1011_0000;
4'd4:seg_data <= 8'b1001_1001;
4'd5:seg_data <= 8'b1001_0010;
4'd6:seg_data <= 8'b1000_0010;
4'd7:seg_data <= 8'b1111_1000;
4'd8:seg_data <= 8'b1000_0000;
4'd9:seg_data <= 8'b1001_0000;
4'ha:seg_data <= 8'b1000_1000;
4'hb:seg_data <= 8'b1000_0011;
4'hc:seg_data <= 8'b1100_0110;
4'hd:seg_data <= 8'b1010_0001;
4'he:seg_data <= 8'b1000_0110;
4'hf:seg_data <= 8'b1000_1110;
default:seg_data <= 8'b1111_1111;
endcase
end
endmodule
将计数器的十进制数按照译码准则转换为8位二进制,控制数码管的段选位。
3.数码管扫描模块
module seg_scan
#(
parameter SCAN = 13'd4999,
parameter SEG = 3'd5)
(
input clk,
input rst_n,
input [7:0] seg_data0,
input [7:0] seg_data1,
input [7:0] seg_data2,
input [7:0] seg_data3,
input [7:0] seg_data4,
input [7:0] seg_data5,
output reg[5:0] seg_sel,
output reg[7:0] seg_data
);
reg [12:0] timer;
reg [2:0] seg;
always@(posedge clk or negedge rst_n)
if(rst_n == 1'b0)
timer <= 13'd0;
else if(timer == SCAN)
timer <= 13'd0;
else
timer <= timer + 13'd1;
always@(posedge clk or negedge rst_n)
if(rst_n == 1'b0)
seg <= 3'd0;
else if(seg == SEG && timer == SCAN)
seg <= 3'd0;
else if(timer == SCAN)
seg <= seg + 3'd1;
always@(posedge clk or negedge rst_n)
if(rst_n == 1'b0)
begin
seg_sel <= 6'b0000_00;
seg_data <= 8'b0000_0000;
end
else
case(seg)
3'd0:
begin
seg_sel <= 6'b0111_11;
seg_data <= seg_data0;
end
3'd1:
begin
seg_sel <= 6'b1011_11;
seg_data <= seg_data1;
end
3'd2:
begin
seg_sel <= 6'b1101_11;
seg_data <= seg_data2;
end
3'd3:
begin
seg_sel <= 6'b1110_11;
seg_data <= seg_data3;
end
3'd4:
begin
seg_sel <= 6'b1111_01;
seg_data <= seg_data4;
end
3'd5:
begin
seg_sel <= 6'b1111_10;
seg_data <= seg_data5;
end
default:
begin
seg_sel <= 6'b1111_11;
seg_data <= 8'b1111_1111;
end
endcase
endmodule
扫描时间间隔设为0.01ms,人眼无法捕捉0.01ms的变化,进而实现6位数码管”同时“显示。文章来源:https://www.toymoban.com/news/detail-494332.html
4.顶层模块
module seg_test
#(
parameter SCAN = 13'd4999,
parameter SEG = 3'd5,
parameter BAUD = 32'd49999999
)
(
input clk,
input rst_n,
output [5:0] seg_sel,
output [7:0] seg_data
);
wire t0,t1,t2,t3,t4,t5;
wire[3:0] count0,count1,count2,count3,count4,count5;
wire[7:0] seg_data0,seg_data1,seg_data2,seg_data3,seg_data4,seg_data5;
reg t;
reg[25:0] timer;
always@(posedge clk or negedge rst_n)
if(rst_n == 1'b0)
begin
timer <= 26'd0;
t <= 1'b0;
end
else if(timer == BAUD)
begin
timer <= 26'd0;
t <= 1'b1;
end
else
begin
timer <= timer + 1'd1;
t <= 1'b0;
end
counter_10
#(
.COUNT(9)
)counter_10_0
(
.clk (clk),
.rst_n (rst_n),
.en (t),
.clr (1'b0),
.count (count0),
.t (t0)
);
counter_10
#(
.COUNT(5)
)counter_10_1
(
.clk (clk),
.rst_n (rst_n),
.en (t0),
.clr (1'b0),
.count (count1),
.t (t1)
);
counter_10
#(
.COUNT(9)
)counter_10_2
(
.clk (clk),
.rst_n (rst_n),
.en (t1),
.clr (1'b0),
.count (count2),
.t (t2)
);
counter_10
#(
.COUNT(5)
)counter_10_3
(
.clk (clk),
.rst_n (rst_n),
.en (t2),
.clr (1'b0),
.count (count3),
.t (t3)
);
counter_10
#(
.COUNT(3)
)counter_10_4
(
.clk (clk),
.rst_n (rst_n),
.en (t3),
.clr (1'b0),
.count (count4),
.t (t4)
);
counter_10
#(
.COUNT(2)
)counter_10_5
(
.clk (clk),
.rst_n (rst_n),
.en (t4),
.clr (1'b0),
.count (count5),
.t (t5)
);
seg_decoder seg_decoder_0
(
.bin_data(count0),
.seg_data(seg_data0)
);
seg_decoder seg_decoder_1
(
.bin_data(count1),
.seg_data(seg_data1)
);
seg_decoder seg_decoder_2
(
.bin_data(count2),
.seg_data(seg_data2)
);
seg_decoder seg_decoder_3
(
.bin_data(count3),
.seg_data(seg_data3)
);
seg_decoder seg_decoder_4
(
.bin_data(count4),
.seg_data(seg_data4)
);
seg_decoder seg_decoder_5
(
.bin_data(count5),
.seg_data(seg_data5)
);
seg_scan
#(
.SCAN(SCAN),
.SEG (SEG)
)seg_scan
(
.clk (clk),
.rst_n (rst_n),
.seg_data0 (seg_data0),
.seg_data1 (seg_data1),
.seg_data2 (seg_data2),
.seg_data3 (seg_data3),
.seg_data4 (seg_data4),
.seg_data5 (seg_data5),
.seg_sel (seg_sel),
.seg_data (seg_data)
);
endmodule
实验结果
文章来源地址https://www.toymoban.com/news/detail-494332.html
到了这里,关于FPGA学习—数码管显示的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!