一、数码管动态显示
用动态扫描的显示方式实现数码管的动态显示(利用人眼的视觉暂留以及数码管的余晖效应)

二、数码管动态显示实现
1、实验目标
0~999999循环计数,每个计数的间隔为0.1s

2、visio视图

(1)总体视图

根据视图可以看出,数码管的动态显示主要由三部分

openresty 动态模块_动态显示

(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,当数码管位有效的高电平时,数码管可以正常的显示,当为低电平时数码管不工作

openresty 动态模块_嵌入式_02

openresty 动态模块_数码管_03

程序

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