FPGA入门(6):数码管静态/动态显示(一)

简介: FPGA入门(6):数码管静态/动态显示

第22讲:数码管静态显示

数码管是一种半导体发光器件,其基本单元是发光二极管。

低电平点亮,高电平熄灭



模块设计

组合如下:

seg_static波形图绘制:

seg_static.v

`timescale  1ns/1ns
module  seg_static
(
    input   wire            sys_clk     ,   //系统时钟,频率50MHz
    input   wire            sys_rst_n   ,   //复位信号,低电平有效
    output  reg     [5:0]   sel         ,   //数码管位选信号
    output  reg     [7:0]   seg             //数码管段选信号
);
//parameter define
parameter   CNT_WAIT_MAX  =  25'd24_999_999;   //计数器最大值(0.5s)
//十六进制数显示编码
parameter   SEG_0 = 8'b1100_0000,   SEG_1 = 8'b1111_1001,
            SEG_2 = 8'b1010_0100,   SEG_3 = 8'b1011_0000,
            SEG_4 = 8'b1001_1001,   SEG_5 = 8'b1001_0010,
            SEG_6 = 8'b1000_0010,   SEG_7 = 8'b1111_1000,
            SEG_8 = 8'b1000_0000,   SEG_9 = 8'b1001_0000,
            SEG_A = 8'b1000_1000,   SEG_B = 8'b1000_0011,
            SEG_C = 8'b1100_0110,   SEG_D = 8'b1010_0001,
            SEG_E = 8'b1000_0110,   SEG_F = 8'b1000_1110;
parameter   IDLE  = 8'b1111_1111;   //不显示状态
//reg   define
reg             add_flag    ;   //数码管数值+1标志信号
reg     [24:0]  cnt_wait    ;   //时钟分频计数器
reg     [3:0]   num         ;   //数码管显示的十六进制数
//cnt_wait:0.5秒计数
always@(posedge sys_clk or  negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        cnt_wait    <=  25'd0;
    else    if(cnt_wait == CNT_WAIT_MAX)
        cnt_wait    <=  25'd0;
    else
        cnt_wait    <=  cnt_wait + 1'b1;
//add_flag:0.5s拉高一个标志信号
always@(posedge sys_clk or  negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        add_flag    <=  1'b0;
    else    if(cnt_wait == CNT_WAIT_MAX)
        add_flag    <=  1'b1;
    else
        add_flag    <=  1'b0;
//num:从 4'h0 加到 4'hf 循环
always@(posedge sys_clk or  negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        num <=  4'd0;
    else    if(add_flag == 1'b1)
        num <=  num + 1'b1;
    else
        num <=  num;
//sel:选中六个数码管
always@(posedge sys_clk or  negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        sel <=  6'b000000;
    else
        sel <=  6'b111111;
//给要显示的值编码
always@(posedge sys_clk or  negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        seg    <=  IDLE;
    else    case(num)
        4'd0:   seg    <=  SEG_0;
        4'd1:   seg    <=  SEG_1;
        4'd2:   seg    <=  SEG_2;
        4'd3:   seg    <=  SEG_3;
        4'd4:   seg    <=  SEG_4;
        4'd5:   seg    <=  SEG_5;
        4'd6:   seg    <=  SEG_6;
        4'd7:   seg    <=  SEG_7;
        4'd8:   seg    <=  SEG_8;
        4'd9:   seg    <=  SEG_9;
        4'd10:  seg    <=  SEG_A;
        4'd11:  seg    <=  SEG_B;
        4'd12:  seg    <=  SEG_C;
        4'd13:  seg    <=  SEG_D;
        4'd14:  seg    <=  SEG_E;
        4'd15:  seg    <=  SEG_F;
        default:seg    <=  IDLE ;  //闲置状态,不显示
    endcase
endmodule


hc595_ctrl模块

hc595_ctrl.v

`timescale  1ns/1ns
module  hc595_ctrl
(
    input   wire            sys_clk     ,   //系统时钟,频率50MHz
    input   wire            sys_rst_n   ,   //复位信号,低有效
    input   wire    [5:0]   sel         ,   //数码管位选信号
    input   wire    [7:0]   seg         ,   //数码管段选信号
    
    output  reg             stcp        ,   //数据存储器时钟
    output  reg             shcp        ,   //移位寄存器时钟
    output  reg             ds          ,   //串行数据输入
    output  wire            oe              //使能信号,低有效
);
//reg   define
reg     [1:0]   cnt_4   ;   //分频计数器
reg     [3:0]   cnt_bit ;   //传输位数计数器
//wire  define
wire    [13:0]  data    ;   //数码管信号寄存
//将数码管信号寄存
assign  data = {seg[0],seg[1],seg[2],seg[3],seg[4],seg[5],seg[6],seg[7],sel};
//将复位取反后赋值给其即可
assign oe = ~sys_rst_n;
//分频计数器:0~3循环计数
always@(posedge sys_clk or  negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        cnt_4 <=  2'd0;
    else    if(cnt_4 == 2'd3)
        cnt_4 <=  2'd0;
    else
        cnt_4 <=  cnt_4 +   1'b1;
//cnt_bit:每输入一位数据加一
always@(posedge sys_clk or  negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        cnt_bit   <=  4'd0;
    else    if(cnt_4 == 2'd3 && cnt_bit == 4'd13)
        cnt_bit   <=  4'd0;
    else    if(cnt_4  ==  2'd3)
        cnt_bit   <=  cnt_bit   +   1'b1;
    else
        cnt_bit   <=  cnt_bit;
//stcp:14个信号传输完成之后产生一个上升沿
always@(posedge sys_clk or  negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        stcp    <=  1'b0;
    else    if(cnt_bit == 4'd13 && cnt_4 == 2'd3)
        stcp    <=  1'b1;
    else
        stcp    <=  1'b0;
//shcp:产生四分频移位时钟
always@(posedge sys_clk or  negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        shcp    <=  1'b0;
    else    if(cnt_4 >= 4'd2)
        shcp    <=  1'b1;
    else
        shcp    <=  1'b0;
//ds:将寄存器里存储的数码管信号输入即
always@(posedge sys_clk or  negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        ds  <=  1'b0;
    else    if(cnt_4 == 2'd0)
        ds  <=  data[cnt_bit];
    else
        ds  <=  ds;
endmodule

seg_595_static.v

`timescale  1ns/1ns
module  seg_595_static
(
    input   wire            sys_clk     ,   //系统时钟,频率50MHz
    input   wire            sys_rst_n   ,   //复位信号,低有效
    output  wire            stcp        ,   //输出数据存储寄时钟
    output  wire            shcp        ,   //移位寄存器的时钟输入
    output  wire            ds          ,   //串行数据输入
    output  wire            oe              //输出使能信号
);
//wire  define
wire    [5:0]   sel;
wire    [7:0]   seg;
//---------- seg_static_inst ----------
seg_static  seg_static_inst
(
    .sys_clk     (sys_clk   ),   //系统时钟,频率50MHz
    .sys_rst_n   (sys_rst_n ),   //复位信号,低电平有效
    .sel         (sel       ),   //数码管位选信号
    .seg         (seg       )    //数码管段选信号
);
//---------- hc595_ctrl_inst ----------
hc595_ctrl  hc595_ctrl_inst
(
    .sys_clk     (sys_clk  ),   //系统时钟,频率50MHz
    .sys_rst_n   (sys_rst_n),   //复位信号,低有效
    .sel         (sel      ),   //数码管位选信号
    .seg         (seg      ),   //数码管段选信号
    .stcp        (stcp     ),   //输出数据存储寄时钟
    .shcp        (shcp     ),   //移位寄存器的时钟输入
    .ds          (ds       ),   //串行数据输入
    .oe          (oe       )    //输出使能信号
);
endmodule

仿真:tb_seg_595_static.v

`timescale  1ns/1ns
module  tb_seg_595_static();
//wire  define
wire    stcp    ;   //输出数据存储寄时钟
wire    shcp    ;   //移位寄存器的时钟输入   
wire    ds      ;   //串行数据输入
wire    oe      ;   //输出使能信号
//reg   define
reg     sys_clk     ;
reg     sys_rst_n   ;
//对sys_clk,sys_rst_n赋初始值
initial
    begin
        sys_clk     =   1'b1;
        sys_rst_n   <=  1'b0;
        #100
        sys_rst_n   <=  1'b1;
    end
//clk:产生时钟
always  #10 sys_clk <=  ~sys_clk;
//重新定义参数值,缩短仿真时间
defparam    seg_595_static_inst.seg_static_inst.CNT_WAIT_MAX    =   10;
//-------------seg_595_static_inst-------------
seg_595_static  seg_595_static_inst
(
    .sys_clk     (sys_clk   ),  //系统时钟,频率50MHz
    .sys_rst_n   (sys_rst_n ),  //复位信号,低电平有效
    .stcp        (stcp      ),   //输出数据存储寄时钟
    .shcp        (shcp      ),   //移位寄存器的时钟输入
    .ds          (ds        ),   //串行数据输入
    .oe          (oe        )    //输出使能信号
);
endmodule


第23讲:数码管动态显示


模块设计

系统框图绘制

data_gen波形图绘制

FPGA入门(6):数码管静态/动态显示(二)+https://developer.aliyun.com/article/1556562

目录
相关文章
|
6月前
|
芯片 异构计算
【FPGA】高云FPGA之数字钟实验->HC595驱动数码管(一)
【FPGA】高云FPGA之数字钟实验->HC595驱动数码管
159 2
|
6月前
|
芯片 异构计算
【FPGA】高云FPGA之数字钟实验->HC595驱动数码管(三)
【FPGA】高云FPGA之数字钟实验->HC595驱动数码管
152 4
|
测试技术 异构计算
【FPGA基础入门实践】Verilog 基本项目操作逐步演示
【FPGA基础入门实践】Verilog 基本项目操作逐步演示
218 0
|
4月前
|
异构计算
FPGA入门(6):数码管静态/动态显示(二)
FPGA入门(6):数码管静态/动态显示(二)
60 10
|
4月前
|
缓存 异构计算
FPGA入门(7):IP核调用(二)
FPGA入门(7):IP核调用(二)
47 0
|
4月前
|
异构计算
FPGA入门(7):IP核调用(一)
FPGA入门(7):IP核调用(一)
82 0
|
4月前
|
异构计算
FPGA入门(5):控制LED灯
FPGA入门(5):控制LED灯
50 0
|
4月前
|
异构计算
FPGA入门(4):时序逻辑(二)
FPGA入门(4):时序逻辑(二)
37 0
|
4月前
|
存储 异构计算
FPGA入门(4):时序逻辑(一)
FPGA入门(4):时序逻辑
45 0
|
4月前
|
存储 异构计算
FPGA入门(3):组合逻辑
FPGA入门(3):组合逻辑
47 0

热门文章

最新文章