二、19【FPGA】数码管动态显示实验

本文介绍了一种基于FPGA的六位数码管动态显示设计,包括二进制到BCD码转换、动态扫描原理及其实现方法。设计能够实现0至999999的计数显示。

前言

学习说明此文档为本人的学习笔记,注重实践,关于理论部分会给出相应的学习链接。

学习视频:是根据野火FPGA视频教程——第二十二讲
https://www.bilibili.com/video/BV1nQ4y1Z7zN?p=3

理论学习

1、数码管动态显示

“天下武功唯快不破”  “看到的不一定为真”

眼睛的视觉暂留:光信号传入大脑需要短暂时间,只要变化的频率大于传输的的频率,那么你看到的事物将是一直存在的,并不会出现闪动,这就是视觉的暂留现象。

数码管的余晖效应:当停止向发光二极管亮度仍然维持一段时间。

动态扫描,当数码管的闪烁时间间隔为1ms时,眼睛将不会察觉有闪烁感。以6ms为一个周期,每个数码管显示1ms,循环显示方法。

2、二进制转BCD码

BCD 码(Binary-Coded Decimal),又称二 - 十进制码,使用 4 位二进制数来表示 1 位十进制数中的 0~9 10 个数码,是一种二进制的数字编码形式,用二进制编码的十进制代码。

分为:有权码和无权码

 将其每位二进制数乘以它的权值然后相加。十进制 5 8421BCD 码为 0101,即:1×1 + 0×2 + 1×4+ 0×8 = 5,每4位代表一个十进制数

 十进制:234            二进制:1110_1010           BCD:0010_0011_0100

如何通过二进制求出每一位的十进制数:

  • stp1:在相应二进制前面补(十进制位数*4),如10则补8位0,234则补12位
  • stp2:判断每四位二进制数(一位十进制数)是否大于4,当>4时每四位二进制数加3(+0011)
  • stp3:向左移1位
  • stp4:循环stp2和stp3
  • stp5:直到将输入二进制数全都移位完成。需要移的位数就是二进制码的位数,得到BCD码每四位的十进制数就是需要显示的数。

实战演练

一、设计规划

1.1 实验要求

让6位数码管显示从十进制数0开始计数,每次0.1s加1,一直加到十进制数999999。到达999999之后回到0开始重新计数。

1.2 硬件资源

和静态显示的硬件资源相同

二、模块框图绘制

2.1 功能模块框图

2.2 Data_gen 数据生成模块

  • 波形图

  • 程序代码 
module data_gen
#(
    parameter CNT_MAX = 23'd4999999,
    parameter DATA_MAX = 20'd999999             
)
(
    input wire sys_clk,
    input wire sys_rst_n,
    output reg [19:0] data,
    output wire [5:0] point,
    output reg seg_en,
    output wire sign
    );
    reg [22:0] cnt_100ms;
    reg  cnt_flag;
    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;
    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;    
    always@(posedge sys_clk or negedge sys_rst_n)
        if(sys_rst_n == 1'b0)
            data <= 20'd0;
        else if(data == DATA_MAX && cnt_100ms == CNT_MAX)
            data <= 20'd0;
        else if(cnt_flag == 1'b1)
            data <= data + 1'b1;
        else 
            data <= data;   
    assign point = 6'b000000;
    assign sign  = 1'b0;
    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;
    
    initial begin
        sys_clk = 1'b1;
        sys_rst_n <= 1'b0;
        #20
        sys_rst_n <= 1'b1;
    end 
    always #10 sys_clk = ~sys_clk;


    data_gen
    #(
        .CNT_MAX (9),
        .DATA_MAX(5)             
    )
    data_gen_inst
    (
        .sys_clk  (sys_clk  ),
        .sys_rst_n(sys_rst_n)    
    );
endmodule
  • 仿真波形

通过与绘制的波形对比,可知绘制波形图是正确的

2.3 bcd_8421二进制转十进制模块

  • 波形图

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

追逐者-桥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值