请选择 进入手机版 | 继续访问电脑版

集成电路技术分享

 找回密码
 我要注册

QQ登录

只需一步,快速开始

搜索
查看: 2577|回复: 1

FPGA快速入门-数码管显示

[复制链接]
lxw 发表于 2019-6-22 17:47:56 | 显示全部楼层 |阅读模式
先来了解一下数码管的工作原理。如图1所示,这是一个典型的带小数点的一位数码管。如果忽略小数点,我们通常称它为7段数码管(即便有小数点,我们也习惯的称呼为7段数码管),所谓7段,是指着7个发光二极管而言的。任意一个0-9的阿拉伯数字的显示,只要通过这7个发光二极管进行亮或灭的组合都可以实现。例如,我们要显示数字0,那么只要让发光二极管a、b、c、d、e、f点亮(g和dot熄灭)就可以了。

图1数码管示意图
接下来,大家可能就要关心着这7个发光二极管是如何控制的,我们又是如何通过FPGA的I/O口去点亮或熄灭任意一个发光二极管?很简单,原理上来讲,一个带小数点的数码管的所有8个发光二极管的正极或负极有一个公共端,通常必须接GND(共阴极数码管)或者接VCC(共阳极数码管),而另一个非公共端的8个引脚就留给用户的I/O直接控制了。例如,如果我们使用的是共阴极的数码管,那么我们在使用该数码管时就要将其公共端接地(或者接低电平0),我们的应用中,把这个公共端连接到了FPGA的I/O脚上,这便是数码管的片选信号。如果FPGA的这个I/O脚输出低电平0,那么这个数码管就能够显示数字;如果这个I/O输出高电平1,那么无论数码管的8个段选端输出0还是1,都无法将8个发光二极管的任意一个点亮,这也达到了关闭数码管显示的效果。这样一来,这个数码管的公共端被我们当做了数码管片选引脚使用了,虽然不是名副其实的“片选”,但还真达到了异曲同工之妙。
         我们的例程要实现的功能比较简单基础:让4个数码管每隔1s不断的递增计数显示,计数范围为0-F。为了便于代码编写控制7个用于段选(不包括小数点)的发光二极管显示不同的字符,这里只做了一个简单的对应表,把不同字符显示时的7个I/O值进行编码,如表3所示。
表3数码管显示字符与驱动编码映射表
数字/字符        0        1        2        3        4        5        6        7
编码(16进制)        3f        06        5b        4f        66        6d        7d        07
数字/字符        8        9        A        B        C        D        E        F
编码(16进制)        7f        6f        77        7c        39        5e        79        71

         本实例的功能框图如图3所示。PLL产生的25MHz时钟,分别供给两个子模块,秒计数器(counter.v)模块产生一个每秒递增的16位数据,这16位数据以16进制形式通过数码管显示驱动模块(seg7.v)显示到数码管上。数码管显示驱动模块以分时复用的片选方式,将数据送到数码管的各个段选位上。

图3数码管驱动功能框图
数码管驱动实例代码
module seven_tube_drive (clk, rst_n, data_show, seven_tube_seg_n, seven_tube_sel);

        input wire clk;
        input wire rst_n;       
        input wire [23:0] data_show;       
        output reg [7:0] seven_tube_seg_n;
        output reg [2:0] seven_tube_sel;

        localparam S0 =        6'b00_0001;
        localparam S1 =        6'b00_0010;
        localparam S2 =        6'b00_0100;
        localparam S3 =        6'b00_1000;
        localparam S4 =        6'b01_0000;
        localparam S5 =        6'b10_0000;
       
        parameter                T_2ms        =        50_000;

        reg [5:0]        c_state;
        reg [5:0]        n_state;
        reg [15:0]        cnt_1ms;
        wire flag_1ms;
        reg         [3:0] temp;
       
        always @ (posedge clk)
        begin
                if (rst_n == 0)
                        cnt_1ms <= 0;
                else
                        if (cnt_1ms < T_1ms - 1)
                                cnt_1ms <= cnt_1ms + 1'b1;
                        else
                                cnt_1ms <= 0;
        end
       
        assign        flag_1ms = (cnt_1ms == T_1ms - 1) ? 1'b1 : 1'b0;
       
        always @ (posedge clk)
        begin
                if (rst_n == 0)
                        c_state <= S0;
                else
                        c_state <= n_state;
        end
       
        always @ (*)
        begin
                case (c_state)
                        S0                :        if (flag_1ms)
                                                        n_state = S1;
                                                else
                                                        n_state = S0;
               
                        S1                :        if (flag_1ms)
                                                        n_state = S2;
                                                else
                                                        n_state = S1;
               
                        S2                :        if (flag_1ms)
                                                        n_state = S3;
                                                else
                                                        n_state = S2;
               
                        S3                :        if (flag_1ms)
                                                        n_state = S4;
                                                else
                                                        n_state = S3;
               
                        S4                :        if (flag_1ms)
                                                        n_state = S5;
                                                else
                                                        n_state = S4;
               
                        S5                :        if (flag_1ms)
                                                        n_state = S0;
                                                else
                                                        n_state = S5;
               
                        default        :                n_state = S0;
                endcase
        end
       
        always @ (posedge clk)
        begin
                if (rst_n == 0)
                        seven_tube_sel <= 0;
                else
                        case (c_state)
                                S0                :        seven_tube_sel <= 0;
                                S1                :        seven_tube_sel <= 1;
                                S2                :        seven_tube_sel <= 2;
                                S3                :        seven_tube_sel <= 3;
                                S4                :        seven_tube_sel <= 4;
                                S5                :        seven_tube_sel <= 5;
                                default        :        seven_tube_sel <= 0;                               
                        endcase
        end
       
        always @ (*)
        begin
                case (c_state)
                        S0                :        temp = data_show[23:20];
                        S1                :        temp = data_show[19:16];
                        S2                :        temp = data_show[15:12];
                        S3                :        temp = data_show[11:8];
                        S4                :        temp = data_show[7:4];
                        S5                :        temp = data_show[3:0];
                        default        :        temp = 0;
                endcase
        end
       
        always @ (posedge clk)
        begin
                if (rst_n == 0)
                        seven_tube_seg_n <= 8'hff;
                else
                        case (temp)
                                0                :        seven_tube_seg_n <= 8'b1100_0000;
                                1                :        seven_tube_seg_n <= 8'b1111_1001;
                                2                :        seven_tube_seg_n <= 8'b1010_0100;
                                3                :        seven_tube_seg_n <= 8'b1011_0000;
                                4                :        seven_tube_seg_n <= 8'b1001_1001;
                                5                :        seven_tube_seg_n <= 8'b1001_0010;
                                6                :        seven_tube_seg_n <= 8'b1000_0010;
                                7                :        seven_tube_seg_n <= 8'b1111_1000;
                                8                :        seven_tube_seg_n <= 8'b1000_0000;
                                9                :        seven_tube_seg_n <= 8'b1001_0000;
                                10                :        seven_tube_seg_n <= 8'b1000_1000;
                                11                :        seven_tube_seg_n <= 8'b1000_0011;
                                12                :        seven_tube_seg_n <= 8'b1100_0110;
                                13                :        seven_tube_seg_n <= 8'b1010_0001;
                                14                :        seven_tube_seg_n <= 8'b1000_0110;
                                15                :        seven_tube_seg_n <= 8'b1000_1110;
                                default        :        seven_tube_seg_n <= 8'hff;
                        endcase
        end
       
endmodule

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?我要注册

x
雷磊 发表于 2019-8-22 14:48:08 | 显示全部楼层
FPGA快速入门-数码管显示
您需要登录后才可以回帖 登录 | 我要注册

本版积分规则

关闭

站长推荐上一条 /1 下一条

QQ|小黑屋|手机版|Archiver|集成电路技术分享 ( 京ICP备20003123号-1 )

GMT+8, 2024-3-29 17:39 , Processed in 0.065951 second(s), 20 queries .

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表