19 数码管的动态显示
1、八段数码管
八段数码管 是一个 “ 8 ” 字型数码管,分为八段,a b c d e f g dp,其中dp为小数点。每一段为一个发光二极管,这样的 8 段称为 段选信号 。
2、实验
1、实验目标:让六位数码管 从 0 开始记数,每 0.1s 加 1 ,一直加到999_999,达到999_999之后重新开始从 0 计数。
2、程序设计
数据生成模块
`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2025/03/23 20:13:38
// Design Name:
// Module Name: data_gen
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//
module data_gen
#(
parameter CNT_MAX = 23'd4999_999 ,
parameter DATA_MAX = 20'd999_999
)
(
// clk and rst
input wire sys_clk_50 ,
input wire sys_rst_n ,
// 数码管显示的值
output reg [19:0] data ,
// 小数点显示
output wire[5:0] point ,
// 数码管使能信号
output reg seg_en ,
// 符号位,high为负
output wire sign
);
// reg define
reg [22:0] cnt_100ms ;
reg cnt_flag ;
assign point = 6'b00_0000 ;
assign sign = 1'b0 ;
// cnt_100ms 从 0 - CNT_MAX
always@( posedge sys_clk_50 or negedge sys_rst_n )
begin
if( sys_rst_n == 1'b0 )
begin
cnt_100ms <= 23'd0 ;
end
else
begin
if( cnt_100ms == CNT_MAX )
begin
cnt_100ms <= 23'd0 ;
end
else
begin
cnt_100ms <= cnt_100ms + 1'b1 ;
end
end
end
// cnt_flag
always@( posedge sys_clk_50 or negedge sys_rst_n )
begin
if( sys_rst_n == 1'b0 )
begin
cnt_flag <= 1'b0 ;
end
else
begin
if( cnt_100ms == (CNT_MAX-1'b1) )
begin
cnt_flag <= 1'b1 ;
end
else
begin
cnt_flag <= 1'b0 ;
end
end
end
//数码管显示的数据
always@( posedge sys_clk_50 or negedge sys_rst_n )
begin
if( sys_rst_n == 1'b0 )
begin
data <= 20'd0 ;
end
else
begin
if( (data == DATA_MAX) && (cnt_flag == 1'b1) )
begin
data <= 20'd0 ;
end
else if( cnt_flag == 1'b1 )
begin
data <= data + 1'b1 ;
end
else
begin
data <= data ;
end
end
end
//数码管使能信号拉高
always@( posedge sys_clk_50 or negedge sys_rst_n )
begin
if( sys_rst_n == 1'b0 )
begin
seg_en <= 1'b0 ;
end
else
begin
seg_en <= 1'b1 ;
end
end
endmodule
二进制转 BCD码模块
BCD ( Binary coded Decimal ):二进制转十进制,使用四位二进制表示一位十进制数,是一种二进制数字编码形式,用二进制编码十进制代码。根据 权值 的有无 分为 有权码 和 无权码 。
本实验采用BCD编码 为 8421码。
`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2025/03/23 21:11:12
// Design Name:
// Module Name: bcd_8421
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//
module bcd_8421
(
//clk and rst
input wire sys_clk_50 ,
input wire sys_rst_n ,
//需要转换的data
input wire [19:0] data ,
//个位,十位,百位,千位,万位,十万位 bcd码
output reg [3:0] unit ,
output reg [3:0] ten ,
output reg [3:0] hun ,
output reg [3:0] tho ,
output reg [3:0] t_tho ,
output reg [3:0] h_hun
);
//reg define
reg [4:0] cnt_shift ;
reg [43:0] data_shift ;
reg shift_flag ;
//cnt_shift: 0 - 21 的循环
always@( posedge sys_clk_50 or negedge sys_rst_n )
begin
if( sys_rst_n == 1'b0 )
begin
cnt_shift <= 5'd0 ;
end
else
begin
if( (cnt_shift == 5'd21) && (shift_flag == 1'b1) )
begin
cnt_shift <= 5'd0 ;
end
else if( shift_flag == 1'b1 )
begin
cnt_shift <= cnt_shift + 1'b1 ;
end
else
begin
cnt_shift <= cnt_shift ;
end
end
end
//data_shift:计数器为0时赋初值,1-20时移位判断操作
always@( posedge sys_clk_50 or negedge sys_rst_n )
begin
if( sys_rst_n == 1'b0 )
begin
data_shift <= 44'd0 ;
end
else
begin
if( cnt_shift == 5'd0 )
begin
data_shift <= { 24'd0,data } ;
end
else if( (cnt_shift <= 20) && (shift_flag == 1'b0) )
begin
data_shift[23:20] <= ( data_shift[23:20] > 4 )?(data_shift[23:20]+2'd3):(data_shift[23:20]) ;
data_shift[27:24] <= ( data_shift[27:24] > 4 )?(data_shift[27:24]+2'd3):(data_shift[27:24]) ;
data_shift[31:28] <= ( data_shift[31:28] > 4 )?(data_shift[31:28]+2'd3):(data_shift[31:28]) ;
data_shift[35:32] <= ( data_shift[35:32] > 4 )?(data_shift[35:32]+2'd3):(data_shift[35:32]) ;
data_shift[39:36] <= ( data_shift[39:36] > 4 )?(data_shift[39:36]+2'd3):(data_shift[39:36]) ;
data_shift[43:40] <= ( data_shift[43:40] > 4 )?(data_shift[43:40]+2'd3):(data_shift[43:40]) ;
end
else if( (cnt_shift <= 20) && (shift_flag == 1'b1) )
begin
data_shift <= data_shift<<1 ;
end
else
begin
data_shift <= data_shift ;
end
end
end
//shift_flag 移位判断标志信号
always@( posedge sys_clk_50 or negedge sys_rst_n )
begin
if( sys_rst_n == 1'b0 )
begin
shift_flag <= 1'b0 ;
end
else
begin
shift_flag <= ~shift_flag ;
end
end
//当计数器 为 20时,移位完成,对各个位数的BCD码赋值
always@( posedge sys_clk_50 or negedge sys_rst_n )
begin
if( sys_rst_n == 1'b0 )
begin
unit <= 4'b0000 ;
ten <= 4'b0000 ;
hun <= 4'b0000 ;
tho <= 4'b0000 ;
t_tho <= 4'b0000 ;
h_hun <= 4'b0000 ;
end
else
begin
if( cnt_shift == 5'd21 )
begin
unit <= data_shift[23:20] ;
ten <= data_shift[27:24] ;
hun <= data_shift[31:28] ;
tho <= data_shift[35:32] ;
t_tho <= data_shift[39:36] ;
h_hun <= data_shift[43:40] ;
end
else
begin
unit <= unit ;
ten <= ten ;
hun <= hun ;
tho <= tho ;
t_tho <= t_tho ;
h_hun <= h_hun ;
end
end
end
endmodule