一、数码管动态显示
用动态扫描的显示方式实现数码管的动态显示(利用人眼的视觉暂留以及数码管的余晖效应)
二、数码管动态显示实现
1、实验目标
0~999999循环计数,每个计数的间隔为0.1s
2、visio视图
(1)总体视图
根据视图可以看出,数码管的动态显示主要由三部分
(2)模块的作用
top_seg_595
是总模块,输入2路信号,输出4路信号 输出的信号接到595芯片上面
data_gen
主要用于产生要显示的数据,data[ n: 0] 可以对此模块进行扩展,从而使其输出小数点、符号位以及使能信号。
seg_595_dynamic
为动态显示模块,其里面又有
seg_dynamic动态显示驱动模块:主要用于生成段选信号和位选信号
hc595_ctrl 595控制模块(与静态显示的595控制模块一样,可以直接调用):主要是将段选和位选信号转换为4路信号传入到595芯片中间
3、数据生成模块
①对动态显示模块进行扩展,因此在数据生成模块中多出几个扩展接口
可能会进行温湿度的测量会有小数点,所以添加一个小数点的输入point[5:0],因为有6个数码管宽度定义为6位宽度
②还可能用于电压的测量,所以添加一个符号位sign,符号位可以进行负数的显示 即 “-”
③为了更好的控制数码管动态显示模块,增加一个使能端口seg_en,当数码管位有效的高电平时,数码管可以正常的显示,当为低电平时数码管不工作
程序
module data_gen
#(
parameter CNT_MAX = 23'd4999_999, //100ms计数值
parameter DATA_MAX= 20'd999_999 //显示的最大值
)
(
input wire sys_clk , //系统时钟,频率50MHz
input wire sys_rst_n , //复位信号,低电平有效
output reg [19:0] data , //数码管要显示的值
output wire [5:0] point , //小数点显示,高电平有效
output reg seg_en , //数码管使能信号,高电平有效
output wire sign //符号位,高电平显示负号
);
//reg define
reg [22:0] cnt_100ms ; //100ms计数器
reg cnt_flag ; //100ms标志信号
//不显示小数点以及负数
assign point = 6'b000_000;
assign sign = 1'b0;
//cnt_100ms:用50MHz时钟从0到4999_999计数即为100ms
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
cnt_100ms <= 23'd0;
else if(cnt_100ms == CNT_MAX)
cnt_100ms <= 23'd0;
else
cnt_100ms <= cnt_100ms + 1'b1;
//cnt_flag:每100ms产生一个标志信号
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
cnt_flag <= 1'b0;
else if(cnt_100ms == CNT_MAX - 1'b1)
cnt_flag <= 1'b1;
else
cnt_flag <= 1'b0;
//数码管显示的数据:0-999_999
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
data <= 20'd0;
else if((data == DATA_MAX) && (cnt_flag == 1'b1))
data <= 20'd0;
else if(cnt_flag == 1'b1)
data <= data + 1'b1;
else
data <= data;
//数码管使能信号给高即可
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
seg_en <= 1'b0;
else
seg_en <= 1'b1;
endmodule
测试程序
`timescale 1ns/1ns
module tb_data_gen();
reg sys_clk;
reg sys_rst_n;
wire [19:0] data;
wire [5:0] point;
wire sign;
wire seg_en;
always #10 sys_clk = ~sys_clk;
initial
begin
sys_clk = 1'b0;
sys_rst_n <= 1'b0;
#20
sys_rst_n <= 1'b1;
end
data_gen
#(
.CNT_MAX (23'd9),
.DATA_MAX (20'd9)
)
data_gen_inst
(
.sys_clk (sys_clk) ,
.sys_rst_n (sys_rst_n) ,
.data (data) ,
.point (point) ,
.seg_en (seg_en) ,
.sign (sign )
);
endmodule