至简设计系列_7段数码管显示
2026/8/20 15:07:50 网站建设 项目流程

–作者:肖肖肖

本文为明德扬原创及录用文章,转载请注明出处!
明德扬官网:明德扬产品官网

1.1 总体设计

1.1.1 概述

LED数码管以发光二极管作为发光单元,颜色有单红,黄,蓝,绿,白,黄绿等效果,并且可以构造成“8”字形。数码管根据LED的接法不同分为共阴和共阳两类,它们的发光原理是一样的,只是它们的电源极性不同而已。

数码管可以通过驱动电路来驱动内部的各个段码,从而显示出需要的数字。根据数码管驱动方式的不同,可以将其分为静态式和动态式两类。

1.1.2 设计目标

完成数码管的显示,具体功能要求如下:

  1. 间隔1s切换数码管位选,做到数码管从左到右流动显示的效果;

  2. 数码管显示的数值从0开始,每切换一位位选数值加一;

1.1.3信号列表

信号名I/O位宽定义
clkI1系统工作时钟 50M
rst_nI1系统复位信号,低电平有效
segmentO88位数码管段选信号。 由低到高,分别表示数码管的a,b,c,d,e,f,g,dp,低电平时,点亮对应段位。
seg_selO88位数码管位选信号,低电平时,对应位置数码管点亮。

1.1.4设计思路

Ø 数码管显示原理

数码管的8个显示字段”a、b、c、d、e、f、g、h”对应显示面板的位置如下图所示。

数码管显示数字0到9对应的gfedcba值如下表所示。

表5- 1 数码管显示数字与字段值的对应关系

显示 数字共阳gfedcba 2进制共阳gfedcba 16进制共阴gfedcba 2进制共阴gfedcba 16进制
07’b10000007’h407’b 01111117’h3f
17’b 11110017’h797’b 00001107’h06
27’b 01001007’h427’b 10110117’h5b
37’b 01100007’h307’b 10011117’h4f
47’b 00110017’h197’b 11001107’h66
57’b 00100107’h127’b 11011017’h6d
67’b 00000107’h027’b 11111017’h7d
77’b 11110007’h787’b 00001117’h07
87’b 00000007’h007’b 11111117’h7f
97’b 00100007’h107’b 11011117’h6f

数码管静态驱动是指每个数码管的每一个段码都通过一个I/O端口进行驱动,或使用如BCD码二-十进制译码器译码进行驱动,也称直流驱动。静态驱动编程简单,显示亮度高,但占用的I/O端口多,这里不使用这种方法。

数码管动态驱动是将所有数码管的8个显示字段"a、b、c、d、e、f、g、h"的同名端连接在一起,此外每个数码管的公共极COM需增加由各自独立I/O线控制的位选通控制电路。当要输出某一字形码时,所有数码管都会接收到相同的字形码,但究竟是哪个数码管会显示出字形取决于单片机对位选通COM端电路的控制。只需将显示数码管的选通控制打开,该位就会显示出字形,而没有选通的数码管并不会点亮。数码管特定的发光二极管段加上电压后,这些特定的段就会发亮,并且当每位元数码管的点亮时间为1~20ms,由于人的视觉暂留现象及发光二极体的余辉效应,尽管实际上各位数码管并非同时点亮,但只要扫描的速度足够快,给人的印象就是一组稳定的显示资料,不会有闪烁感,使得动态显示的效果和静态显示是一样的,这样能够节省大量的I/O口,而且功耗更低。

以下是mp801开发板对应的数码管原理图,并且是共阳极的数码管:

Ø 工程架构

根据设计目标将现象翻译成信号表示如下:

第1秒,数码管0显示数字“0”,即seg_sel的值为8’b1111_1110,seg_ment的值为8’b1100_0000;

第2秒,数码管1显示数字“1”,即seg_sel的值为8’b1111_1101,seg_ment的值为8’b1111_1001;

第3秒,数码管2显示数字“2”,即seg_sel的值为8’b1111_1011,seg_ment的值为8’b1010_0100;

第4秒,数码管3显示数字“3”,即seg_sel的值为8’b1111_0111,seg_ment的值为8’b1011_0000;

第5秒,数码管4显示数字“4”,即seg_sel的值为8’b1110_1111,seg_ment的值为8’b1001_1001;

第6秒,数码管5显示数字“5”,即seg_sel的值为8’b1101_1111,seg_ment的值为8’b1001_0010;

第7秒,数码管6显示数字“6”,即seg_sel的值为8’b1011_1111,seg_ment的值为8’b1000_0010;

第8秒,数码管7显示数字“7”,即seg_sel的值为8’b0111_1111,seg_ment的值为8’b1111_1000;

第九秒,回到数码管0显示数字“0”,以此进行循环。

总结发现,数码管每隔1秒进行变化,且8个数码管轮流显示。

因此本工程用到了三个计数器的架构,具体架构如下图所示:

1秒计数器cnt_1s:用于计算1s的时间,加一条件为1,表示一直在计数;数到50,000,000下,表示数到1s就结束。

位选计数器sel_cnt:用于区分选通的数码管,加一条件为end_cnt_1s,表示每间隔1秒的时间后,切换选通下一个数码管;数到8下,表示8个数码管都选通过一轮了。

1.1.5参考代码

module seg_disp( rst_n , clk , seg_sel , segment ); parameterTIME_1S = 50_000_000 ; parameterSEG_WID = 8 ; parameterSEG_NUM = 8 ; parameterCNT_WID = 10 ; parameterTIME_20US = 10’d1000 ; parameterNUM_0 = 8’b1100_0000; parameterNUM_1 = 8’b1111_1001; parameterNUM_2 = 8’b1010_0100; parameterNUM_3 = 8’b1011_0000; parameterNUM_4 = 8’b1001_1001; parameterNUM_5 = 8’b1001_0010; parameterNUM_6 = 8’b1000_0010; parameterNUM_7 = 8’b1111_1000; parameterNUM_8 = 8’b1000_0000; parameterNUM_9 = 8’b1001_0000; parameterNUM_ERR = 8’b1111_1111; input clk ; input rst_n ; output [SEG_WID - 1:0] seg_sel ; output [SEG_WID - 1:0] segment ; reg[SEG_WID - 1:0]seg_sel ; reg[SEG_WID - 1:0]segment ; reg[ 31 : 0] cnt_1s ; reg [SEG_NUM1:0] sel_cnt ; reg[ 4 - 1 : 0] seg_tmp ; wire add_cnt_1s ; wire end_cnt_1s ; wire add_sel_cnt ; wire end_sel_cnt ; always @(posedge clk or negedge rst_n) begin if(rst_n==0) begin cnt_1s <= 0; end else if(add_cnt_1s) begin if(end_cnt_1s) cnt_1s <= 0; else cnt_1s <= cnt_1s+1 ; end end assign add_cnt_1s = 1; assign end_cnt_1s = add_cnt_1s && cnt_1s == TIME_1S-1 ; always@(posedge clk or negedge rst_n)begin if(rst_n==1'b0)begin sel_cnt <= 0; end else if(add_sel_cnt)begin if(end_sel_cnt) sel_cnt <= 0; else sel_cnt <= sel_cnt + 1; end end assign add_sel_cnt = end_cnt_1s; assign end_sel_cnt = add_sel_cnt &&sel_cnt == SEG_NUM-1; always@(posedge clk or negedge rst_n)begin if(rst_n==1'b0)begin seg_sel <= {SEG_NUM{1'b1}}; end else begin seg_sel <= ~(1'b1 << sel_cnt); end end always@(posedge clk or negedge rst_n)begin if(rst_n==1'b0) seg_tmp = 0; else seg_tmp = sel_cnt ; end always@(posedge clk or negedge rst_n)begin if(rst_n==1'b0)begin segment<=NUM_0; end else begin case (seg_tmp) 0 : segment <= NUM_0; 1 : segment <= NUM_1; 2 : segment <= NUM_2; 3 : segment <= NUM_3; 4 : segment <= NUM_4; 5 : segment <= NUM_5; 6 : segment <= NUM_6; 7 : segment <= NUM_7; 8 : segment <= NUM_8; 9 : segment <= NUM_9; default : segment <= NUM_ERR; endcase end end endmodule

1.2 效果和总结

Ø 下图是该工程在db603开发板上的现象

Ø 下图是该工程在mp801开发板上的现象

Ø 下图是该工程在ms980试验箱上的现象

由于该项目的上板现象是上电数码管从左到右流动显示对应的数值,想观看完整现象的朋友可以看一下现象演示的视频。

感兴趣的朋友也可以访问论坛进行FPGA相关工程设计学习,也可以看一下我们往期的文章。
明德扬官网:明德扬产品官网

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询