19. 数码管的静态显示

在许多项目设计中,我们通常需要一些显示设备来显示我们需要的信息,可以选择的显示设备有很多,而数码管是使用最多,最简单的显示设备之一。数码管是一种半导体发光器件,具有响应时间短、体积小、重量轻、寿命长等优点。本章节将为大家介绍数码管的显示原理和驱动方式。

19.1. 理论学习

19.1.1. 数码管简介

数码管是一种半导体发光器件,其基本单元是发光二极管。数码管按段数一般分为七段数码管和八段数码管,八段数码管比七段数码管多一个发光二极管(多一个小数点显示)。当然也还有一些其他类型的数码管如“N”形管、“米”字管以及工业科研领域用的16段管、24段管等,在此就不详细介绍。下面将为大家详细介绍本次实验使 用的八段数码管。

segsta002

图 25‑1 常见数码管

19.1.2. 八段数码管

八段数码管的结构图如图 25‑2所示。

segsta003

图 25‑2 八段数码管结构图

由图 25‑2可以看出,八段数码管是一个八字型数码管,分为八段:a、b、c、d、e、f、g、dp,其中dp为小数点,每一段即为一个发光二极管,这样的八段我们称之为段选信号。数码管常用的有10根管脚,每一段有一根管脚,另外两根管脚为一个数码管的公共端,两根互相连接。

数码管分为共阳极数码管和共阴极数码管。共阳极数码管就是把发光二极管的正极连接在一起作为一个引脚,负极分开。相反的,共阴极数码管就是把发光二极管的阴极连接在一起作为一个引脚,正极分开。这两者的区别在于,公共端是连接到地还是高电平,对于共阳极数码管需要给对应段低电平才会使其点亮,而对于共阴极数码管则需要 给其高电平才会点亮。本次实验使用的是共阳极数码管,也就是说给对应段低电平才会被点亮。给不同的段点亮可显示0~f的值,如表格 25‑1所示。

表格 25‑1 数码管编码译码表

二进制段码右边为高位左边为低位。我们只要点亮相应的段码,就能显示我们需要显示的内容。

段式数码管工作方式有两种:静态显示和动态显示。静态显示的特点是每个数码管的段选必须接一个8位数据线来显示字形,显示字形可一直保持,直到送入新字形码为止。那么如果点亮6个码管是不是需要48位数据线去分别控制每一个码管的段选?当然这种方法也可以,但是其占用的I/O口较多,因此硬件电路比较复杂,成本较高, 很少使用。

那么如何节约资源呢?以我们本实验使用的数码管为例,如图 25‑3所示:

segsta004

图 25‑3 六位数码管等效电路图

由上图可以看到,我们将六个数码管的段选信号连接在一起,而位选(sel)独立控制,这样六个数码管接在一起就少了8×5个I/O口。这里对位选信号特别说明一下:由上图可以看到每一个数码管都有一个位选信号,而这个位选信号就控制着数码管的亮灭。这样我们就可以通过位选信号去控制 数码管亮,而在同一时刻,位选选通的数码管上显示的字形是一样的,因为我们将6个数码管相对应的段选连在了一起,数码管的显示自然就相同了,数码管的这种显示方式即为静态显示。而如果要让每个数码管显示的值不同,我们要用到另外一种显示方式,即动态显示,将在下一章节给大家介绍。本章节先讲述6位共阳极数码管的静态显 示,为下个章节的动态显示做准备。

由图 25‑3可以看到,即使这样我们控制数码管仍然需要占用14个I/O口资源(8个段选,6个位选)。如果我想节约FPGA芯片的更多I/O口去做其它设计,那能不能使用更少的I/O口去驱动数码管显示呢?这当然是可以的,我们可通过74HC595芯片(位移缓存器)进行实现。

19.1.3. 74HC595简介

74HC595是一个8位串行输入、并行输出的位移缓存器。其内部具有8位移位寄存器和一个存储器,具有三态输出功能。我们先跟据该芯片的引脚图来为大家讲解其功能,如图 25‑4所示。

segsta005

图 25‑4 74HC595芯片引脚图

其各引脚功能简介如表格 25‑2所示。

表格 25‑2 74HC595引脚功能简介

引脚名

引脚编号

引脚功能

Q0—Q7

15,1—7

并行数据输出

GND

8

电源地

Q7S

9

串行数据输出

10

主复位(低电平有效)

SHCP

11

移位寄存器时钟输入

STCP

12

存储寄存器时钟输入

13

输出使能输入(低电平有效)

DS

14

串行数据输入

VCC

16

电源电压

如表格 25‑2所示,该芯片有个并行的数据输出,同时芯片的输入是串行数据,也就是说我们使用一个串行输入口就可以并行输出八个输入的串行数据。从上一小节数码管的讲解我们知道六位八端数码管需要14个I/O(也就是14bit)去驱动数码管,而使用该芯片后,我们就可以将输出的数码管信号以串行(1bit)的方式 输入该芯片,然后该芯片会将我们输入的数码管信号以并行的方式输出。但是可以看到一片芯片只能并行输出8位数据,而我们的六位八段数码管是需要14位数据驱动的,这该怎么办呢?这里我们可以使用两片74HC595芯片进行输出,事实上这正是74HC595的一大特点,可以进行级联。74HC595芯片有个Q7S引脚, 该引脚的功能为串行数据输出,我们将这个输出接入下一片74HC595芯片的串行数据输入端,这样后面的数据就会在下一片74HC595芯片输出了。应用好这个联级功能,我们最少只需占用三个I/O口就可以控制很多片74HC595。

我们知道了数据的输入输出,那我们该如何控制这些数据输入和输出呢?我们通过74HC595芯片内部结构图来为大家讲解其控制过程,如图 25‑5所示。

segsta006

图 25‑5 74HC595内部结构图

如图 25‑5所示,是主复位,低电平时将移位寄存器的数据清零,通常接到VCC防止数据清零。SHCP为移位寄存器时钟输入,上升沿时将输入的串行数据(DS端输入)移入移位寄存器中。需要注要的是它是一个移位寄存器,也就是说当下一个脉冲(时钟上升沿)到来时,上一个脉冲移入的数据就会往下移动一位。如果我们串行 输入8bit数据,8bit数据输入完之后,那么第一位输入的数据将会移动到最后面。若我们一次输入的数据超过8bit,那么后面的数据就会通过Q7S端口输出,此时我们可以将该接口接到另一片74HC595芯片的串行输入端(级联),这样数据就会随着脉冲依次移位到另一片74HC595芯片上。

当串行数据移入到74HC595芯片的移位寄存器之后,我们如何控制其输出呢?74HC595内部有一个8位存储寄存器,该寄存器由STCP(存储寄存器时钟)控制,STCP上升沿时移位寄存器的数据会进入数据存储寄存器中,通过让(输出使能输入)为低即可让存储寄存器中的数据进行输出。

最后我们总结一下74HC595的使用步骤:

  1. 首先把要传输的数据通过引脚DS输入到74HC595中。

  2. 产生SHCP时钟,将DS上的数据串行移入移位寄存器。

  3. 产生STCP时钟,将移位寄存器里的数据送入存储寄存器。

  4. 将引脚置为低电平,存储寄存器的数据会在Q0—Q7并行输出,同时并行输出的数据会被锁存起来。

输入与输出的关系如图 25‑6所示:

segsta007

图 25‑6 串并输出关系

如上图所示最先输入的数据会被移位到最后位进行输出。通过以上理论知识的讲解相信大家对数码管以及74HC595的使用都有了大致的了解,下面我们通过实战演练去看看具体该如何操作。

19.2. 实战演练

19.2.1. 实验目标

根据上一小节的理论学习,我们可以设计一个这样的6位数码管静态显示:控制六位数码管让其以000000、111111、222222一直到FFFFFF循环显示。每个字符显示0.5s后变化。

19.2.2. 硬件资源

本章节我们要使用开发板上的六位八段数码管进行实验,如图 25‑7所示。

segsta008

图 25‑7 硬件资源

征途Pro开发板上使用的数码管型号为FJ3661BH,以及使用了两片74HC595芯片。原理图如图 25‑8、图 25‑9所示。

segsta009

图 25‑8 数码管原理图

segsta010

图 25‑9 74HC595原理图

图 25‑8的数码管为共阳极数码管,即段选为低电平点亮。对应的数码管点亮原理图为图 25‑3所示。从图中可以看到,其位选为高电平时才能点亮对应数码管,DIG1(sel[5])对应的是开发板上最左侧数码管,依次类推,DIG6(sel[0])对应的就是开发板上最右侧数码管。

如图 25‑9所示开发板上搭载了两片74HC595芯片用于输出数码管驱动信号,其中我们接到了VCC防止数据清零,所以这两片74HC595芯片我们只用四个IO口控制即可。我们将两片74HC595进行级联,一片的Q7S输出端接到另一片的数据输入端DS,这样我们输入的14位串行输入数码管信号的前六位就会在 第二片就行输出。(注意:因为是移位寄存器,如果一次共输入14位数据,那么第一位输入的串行数据会在第二片74HC595芯片的Q5输出)。

19.2.3. 程序设计

硬件资源介绍完毕,我们开始实验工程的程序设计。

19.2.3.1. 整体说明

我们根据实验任务可以先画出我们的系统框图,根据框图我们可以更加明确的看到我们该如何完成这个实验。

segsta011

图 25‑10 数码管静态显示系统框图

根据框图可以看到实验一共分为3个模块,下面分模块为大家介绍。

表格 25‑3 数码管静态显示工程模块简介

模块名称

功能描述

seg_static

静态数码管驱动模块

hc595_ctrl

74HC595控制模块

seg_595_static

数码管静态显示顶层模块

19.2.3.2. 静态数码管驱动模块

模块框图

segsta012

图 25‑11 静态数码管驱动模块框图

表格 25‑4 静态数码管驱动模块输入输出信号描述

信号

位宽

类型

功能描述

sys_clk

1bit

Input

50MHz晶振时钟输入

sys_rst_n

1bit

Input

复位信号,低电平有效

sel

6bit

Output

数码管位选信号

seg

8bit

Output

数码管段选信号

数码管的静态显示驱动模块我们只需要给其输入时钟、复位信号即可,此模块是产生驱动数码管的段选信号和位选信号。下面根据波形图去了解位选信号和段选信号该如何输出才能使数码管达到我们的显示要求。

波形图绘制

六位数码管静态显示参考波形图,具体见图 25‑12。

segsta013

图 25‑12 数码管静态显示波形图

如图 25‑12所示:

cnt_wait:根据实验要求需要等待0.5s后显示的字符才发生变化。所以我们需要一个0.5s的循环计数器。我们输入的时钟频率是50MHz,一个时钟周期的时间就是(1/50MHz)s,也就是20ns。所以我们计数器从0计到24_999_999即为0.5s(25000000*20ns)的时间。计到0. 5s后让其归0开始下一个0.5s的计数。

add_flag:当计数器计到0.5s时,我们拉高一个标志信号,让这个标志信号去控制数码管字符的跳转。

num:每个数码管显示的字符,初始显示为0,六个就是000000。当检测到跳转的标志信号为高时,让各个数码管显示的字符加1。当加到4’hF时让其归0重新相加以此循环。

sel:数码管的位选信号。我们是显示六个数码管,直接给其全点亮即可。根据原理图可知我们需要给其位选信号高电平数码管才会被点亮,所以给对应的位数高电平对应的数码管就会点亮,一位表示一个数码管。这里我们全部点亮即可。

seg:数码管的段选信号,给其相应段码点亮显示num里的值即可。

本设计思路只做参考,并非唯一方法,读者也可利用所学知识,按照自己思路进行设计。

代码编写

根据波形图以及波形的的讲解,详细大家已经对模块所有信号的逻辑关系都已经基本了解,那么代码编写起来就比较简单了。模块参考代码,具体见代码清单 25‑1。

代码清单 25‑1 数码管静态显示参考代码(seg_static.v)

module seg_static
(
input wire sys_clk , //系统时钟,频率50MHz
input wire sys_rst_n , //复位信号,低电平有效output reg [5:0] sel , //数码管位选信号
output reg [7:0] seg //数码管段选信号);//////\* Parameter and Internal Signal \////////parameter defineparameter 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 definereg add_flag ; //数码管数值+1标志信号reg [24:0] cnt_wait ; //时钟分频计数器reg [3:0] num ; //数码管显示的十六进制数//////\* Main Code \////////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;elsecnt_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 - 1)add_flag <= 1'b1;elseadd_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;elsenum <= num;//sel:选中六个数码管always@(posedge sys_clk or negedge sys_rst_n)if(sys_rst_n == 1'b0)sel <= 6'b000000;elsesel <= 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 ; //闲置状态,不显示endcaseendmodule

以上代码都是根据波形图进行编写的,这里就不再过多讲解了。

19.2.3.3. 74HC595控制模块

模块框图

segsta014

图 25‑13 74HC595控制模块框图

表格 25‑5 74HC595控制模块框图

信号

位宽

类型

功能简介

sys_clk

1bit

Input

系统时钟,频率50MHz

sys_rst_n

1bit

Input

复位信号,低有效

sel

6bit

Input

数码管位选信号

seg

8bit

Input

数码管段选信号

stcp

1bit

Output

存储寄存器时钟

shcp

1bit

Output

移位寄存器时钟

ds

1bit

Output

串行数据

oe

1bit

Output

输出使能,低有效

由图 25‑13、表格 25‑5所示,该模块我们需要产生stcp、shcp、ds、oe四个信号对74HC595进行控制。其中ds(串行数据)就是输入的数码管位选信号和段选信号;shcp(移位寄存器时钟),这个是ds数据进入移位寄存器的时钟,它的频率是有限制的,我们可以从数据手册中看到,如图 25‑14所示:

segsta015

图 25‑14 shcp、stcp时钟频率

由上图可以看到shcp和stcp的最大频率是有限制的,由原理图可以看到我们使用的电压是3.3v,同时温度不同其支持的最大频率也不同,大家可根据自己的实验环境进行频率的选取,本实验我们使用系统时钟(50MHz)四分频得到的shcp时钟(12.5MHz)去进行驱动,而stcp时钟是在我们串行输入14位数 码管之后拉高的,其频率远远小于shcp,所以这里我们只要确定shcp的频率即可,至于oe信号我们一直让其拉低即可。下面根据波形图图为大家进一步讲解。

波形图绘制

segsta016

图 25‑15 74HC595控制模块波形图

如图 25‑15所示时钟和复位由顶层传来,seg(数码管段选)和sel(数码管位选)由数码管驱动模块传来。seg数据和sel数据就是我们需要串并转换的数据,这两个信号的位宽加起来为14位,即我们每传输14位数据后需并行输出。

cnt:分频计数器。这里我们让计数器在0和3之间循环计数,这样一个循环生成一个时钟即为四分频时钟。

cnt_bit:传输位数计数器。我们知道我们需要传输14bit的数据,故我们需要一个数据器对传输的位数进行计数,这样我们对传输完成14位数据就可以用这个计数器进行判别了。如图所示,当cnt等于3时让cnt_bit计数器加1,让其从0到13循环计数,每个数值代表传输一位数据。

data:我们将需要传输的数码管信号寄存在data中,方便赋值。存储顺序是根据我们传输的位数顺序由低到高位进行存储的,至于数码管各信号的传输顺序我们在硬件部分已有所讲解。

ds:串行数据输出(对我们FPGA芯片来说其是输出,对74HC595来说其是输入,stcp和shcp信号也是如此)。这里我们回到原理图 25‑9,可以看到第二片的Q5引脚连到了数码管的DIG6,也就是最右侧的数码管,而我们最右侧数码管对应的是我们位选信号的最低位,即sel[0]。所以我们第一位应传输 的数据为sel[0],依次类推根据原理图传输相应的数据,具体的传输数据如波形图所示。当一次数据传完之后再次回到状态0开始新一轮的数码管信号传输。

shcp:移位寄存器时钟,上升沿时将数据写入移位寄存器中。我们在ds数据的中间状态拉高产生上升沿,这样可以使shcp采得的ds数据更加稳定。如波形图所示我们在cnt=2时拉高,cnt=0时拉低,即可产生该时钟,其频率即为系统时钟四分频(12.5MHz)。

stcp:存储寄存器时钟。当我们14位数码管控制信号传输完之后我们需要拉高一个stcp时钟来将信号存入存储寄存器之中。最后一个数据是在cnt_bit=13且cnt=2时传输的,所以我们就在下一个时钟(cnt_bit=13且cnt=3时)将stcp拉高一个时钟产生上升沿即可。

oe:存储寄存器数据输出使能信号,低电平有效,这里我们将复位信号取反的值赋给该信号即可。

本设计思路只做参考,并非唯一方法,读者也可利用所学知识,按照自己思路进行设计。

代码编写

根据波形图以及波形图的讲解,相信大家已经对模块所有信号的逻辑关系都已经基本了解,那么代码编写起来就比较简单了。模块参考代码,具体见代码清单 25‑2。

代码清单 25‑2 74HC595控制模块参考代码(hc595.v)

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 //使能信号,低有效);//////\* Parameter and Internal Signal \////////reg definereg [1:0] cnt_4 ; //分频计数器reg [3:0] cnt_bit ; //传输位数计数器//wire definewire [13:0] data ; //数码管信号寄存//////\* Main Code \////////将数码管信号寄存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;elsecnt_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;elsecnt_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;elsestcp <= 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;elseshcp <= 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];elseds <= ds;endmodule

代码是根据所绘制的波形图进行讲解的,前面已经波形图有了详细的讲解,再次就不再过多的叙述了。

19.2.3.4. 顶层模块

模块框图

segsta017

图 25‑16 顶层模块

顶层模块主要是对各个子功能模块的实例化,以及对应信号的连接,各输入输出如表格 25‑6所示。

表格 25‑6 顶层模块输入输出信号描述

信号

位宽

类型

功能描述

sys_clk

1bit

Input

系统时钟,50MHz

sys_rst_n

1bit

Input

复位信号,低有效

stcp

1bit

Output

存储寄存器时钟

shcp

1bit

Output

移位寄存器时钟

ds

1bit

Output

串行数据

oe

1bit

Output

输出使能,低有效

代码编写

顶层模块代码编写较为容易,无需波形图的绘制。顶层参考代码,具体见代码清单 25‑3。

代码清单 25‑3 数码管动态显示顶层模块参考代码(seg_595_static.v)

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 //输出使能信号);//////\* Parameter And Internal Signal \////////wire definewire [5:0] sel;wire [7:0] seg;//////\* Instantiation \////////---------- 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
19.2.3.5. RTL视图

顶层模块介绍完毕,使用Quartus II软件对实验工程进行编译,工程通过编译后查看实验工程RTL视图。工程RTL视图,具体见由图 25‑17可知,实验工程的RTL视图与实验整体框图相同,各信号线均已正确连接。

segsta018

图 25‑17 RTL视图

19.2.3.6. 仿真验证

仿真代码编写

编写仿真代码,对参考代码进行仿真验证。仿真参考代码,具体见代码清单 25‑4。

代码清单 25‑4 数码管静态显示仿真参考代码(tb_seg7_static.v)

\`timescale 1ns/1ns
module tb_seg_595_static();////
//\* Parameter and Internal Signal \//
//////wire define
wire stcp ; //输出数据存储寄时钟wire shcp ; //移位寄存器的时钟输入wire ds ; //串行数据输入wire oe ; //输出使能信号//reg definereg sys_clk ;reg sys_rst_n ;//////\* Main Code \////////对sys_clk,sys_rst_n赋初始值initialbeginsys_clk = 1'b1;sys_rst_n <= 1'b0;#100sys_rst_n <= 1'b1;end//clk:产生时钟always #10 sys_clk <= ~sys_clk;//重新定义参数值,缩短仿真时间defparam seg_595_static_inst.seg_static_inst.CNT_WAIT_MAX = 100;//////\* Instantiation \////////-------------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

仿真波形分析

配置好仿真文件,使用ModelSim对参考代码进行仿真。

segsta019

图 25‑18 数码管静态驱动模块仿真波形图(一)

由图 25‑18可以看到数码显示的值(num)从0开始跳转到了1,再跳转到了2;同时段选信号(seg)的编码与显示的字符也相吻合,仿真图与我们所画波形图的开头是一致的。

segsta020

图 25‑19 数码管静态驱动模块仿真波形图(二)

由图 25‑19可以看到数码管显示的数值从4’hf跳转回0从头开始显示了,这与我们的设计和绘制的波形图是一致的。可以满足我们的实验要求。

segsta021

图 25‑20 74HC595控制模块仿真波形图

如图 25‑20所示,抓取的74HC595控制模块的各信号时序与我们绘制的波形图时序是一致的。

19.3. 上板调试

19.3.1. 引脚约束

仿真验证通过后,准备上板验证,上板验证之前先要进行引脚约束。工程中各输入输出信号与开发板引脚对应关系如表格 25‑7所示。

表格 25‑7 引脚分配表

信号名

信号类型

对应引脚

备注

sys_clk

input

E1

时钟

sys_rst_n

input

M15

复位

stcp

output

K9

存储寄存器时钟

shcp

output

B1

移位寄存器时钟

ds

output

R1

串行数据

oe

output

L11

输出使能

下面进行管脚分配,管脚的分配方法在前面章节已有所讲解,在此就不再过多叙述,管脚的分配如下图 25‑21所示。

segsta022

图 25‑21 管脚分配

19.3.1.1. 结果验证

管脚配置完成之后重新进行编译,编译完之后就可以进行下载验证了,在下载之前首先将电源与下载线与开发板连接好,连接好之后上电,如图 25‑22所示。

segsta023

图 25‑22 下载连线图

打开下载界面后,当检测到下载器(USB-Blaster)已连接之后,即可点击“Add File…”添加sof文件,添加好后点击“start”开始下载,随后界面会显示下载成功,如图 25‑23所示。

segsta024

图 25‑23 下载成功界面

下载成功后可以看到数码管上的数据从000000~FFFFFF之间循环显示,说明验证成功。

19.4. 章末总结

到这里,本章节讲解完毕,通过本章节相信大家对数码管有了初步的了解,那么对下一章节的数码管的动态显示将会有所帮助。


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/922406.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/922406.shtml
英文地址,请注明出处:http://en.pswp.cn/news/922406.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

深入理解大语言模型(5)-关于token

到目前为止对 LLM 的描述中&#xff0c;我们将其描述为一次预测一个单词&#xff0c;但实际上还有一个更重要的技术细 节。即 LLM 实际上并不是重复预测下一个单词&#xff0c;而是重复预测下一个 token 。对于一个句子&#xff0c;语言模型会 先使用分词器将其拆分为一个个 to…

视觉智能的「破壁者」——Transformer如何重塑计算机视觉范式?三大CV算法论文介绍 ViTMAESwin Transformer

当自然语言处理领域因Transformer而焕发新生时&#xff0c;计算机视觉却长期困于卷积神经网络的架构桎梏。直到ViT&#xff08;Vision Transformer&#xff09;的横空出世&#xff0c;才真正打破了视觉与语言之间的壁垒。它不仅是技术的革新&#xff0c;更是范式革命的开始&…

Java 并发容器源码解析:ConcurrentSkipListSet 行级深度剖析

Java 并发容器源码解析&#xff1a;ConcurrentSkipListSet 行级深度剖析 本文将深入解析 Java 并发容器 ConcurrentSkipListSet 的核心源码&#xff0c;结合流程图、代码注释、设计思想、优缺点分析、业务场景、调试与优化、集成方案、高阶应用等&#xff0c;帮助你系统掌握这款…

答题卡自动识别案例

目录 1.答题卡自动批阅整体实现思路 2.关键技术步骤与原理 答题卡区域提取 ①轮廓检测并排序 ②执行透视变换 ③找到每一个圆圈轮廓 ④先对所有圆圈轮廓从上到下排序 ⑤再通过循环每次只提取出五个轮廓再进行从左到右的排序 3.完整代码 1.答题卡自动批阅整体实现思路 …

C#实现通过POST实现读取数据

C# POST请求与MySQL数据存储实现下面是一个完整的C#解决方案&#xff0c;用于发送POST请求、接收响应数据&#xff0c;并将数据保存到MySQL数据库中。完整代码实现 using System; using System.Net.Http; using System.Text; using System.Threading.Tasks; using Newtonsoft.J…

Java 字符编码问题,怎么优雅地解决?

网罗开发&#xff08;小红书、快手、视频号同名&#xff09;大家好&#xff0c;我是 展菲&#xff0c;目前在上市企业从事人工智能项目研发管理工作&#xff0c;平时热衷于分享各种编程领域的软硬技能知识以及前沿技术&#xff0c;包括iOS、前端、Harmony OS、Java、Python等方…

STL之string类(C++)

1.string类核心定位std::string 本质是对 “字符序列” 的封装&#xff0c;内部通过动态数组存储字符&#xff0c;并自动管理内存&#xff08;分配、扩容、释放&#xff09;&#xff0c;对外提供了简洁的接口用于字符串的创建、修改、拼接、查找等操作。1.1 使用前提头文件包含…

[Maven 基础课程]第一个 Maven 项目

idea 新建一个项目&#xff1a; 来到 New Project 页面&#xff1a; 这里我们有两种方式创建 maven 项目&#xff0c;一种是自定义创建&#xff0c;另一种是使用 maven 模版项目创建。 自定义创建 maven 项目 基本配置 Name: first_maven_project 项目名称&#xff0c;设为 …

uni小程序中使用Echarts图表

前言 今天鸡米花给大家带来的是在uni里面使用echarts&#xff0c;能够完美支持和PC端一样的效果&#xff0c;我这边的工程是uni转为微信小程序&#xff0c;用的是vue3vite来写的&#xff0c;然后实现了竖屏和横屏的展示方式&#xff0c;好了献上效果图。 效果图 一、引入插件 这…

从FOTA测试到汽车电子安全体系的启蒙之旅

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 做到欲望极简,了解自己的真实欲望,不受外在潮流的影响,不盲从,不跟风。把自己的精力全部用在自己。一是去掉多余,凡事找规律,基础是诚信;二是…

stm32中 中断和事件的区别

一、核心概念比喻想象一下工厂里的一个报警系统&#xff1a;​中断 (Interrupt)​​&#xff1a;就像火警警报器响了。它的目的是通知管理员&#xff08;CPU&#xff09;​​&#xff1a;“着火了&#xff01;”。管理员听到后&#xff0c;会停下手中的工作&#xff08;保存现场…

深入理解MySQL主从架构中的Seconds_Behind_Master指标

问题&#xff1a;主从延迟与写后读不一致 在典型的 MySQL 主从架构下&#xff0c;所有写操作都会直接进入主库&#xff0c;而读操作大多分流到从库&#xff0c;从而实现读写分离&#xff0c;缓解主库压力。 然而 MySQL 的复制机制是异步的&#xff1a;主库先写入 binlog&#…

MySQL安装(linux版本)

MySQL安装&#xff08;linux版本&#xff09; 课程地址 08. 进阶-MySQL安装(linux版本)_哔哩哔哩_bilibili 安装过程中所有需要的程序都放在网盘里了 通过网盘分享的文件&#xff1a;虚拟机 链接: https://pan.baidu.com/s/1eLMD2iq1uEujNN7mWs2dIg?pwdckmh 提取码: ckmh …

OpenCV 图像双三次BSpline插值

文章目录 一、简介 二、实现代码 三、实现效果 参考资料 一、简介 之前我们介绍过BSpline曲线,一条B样条曲线可以被定义成 n + 1 n+1 n+1个控制点的集合 { Q i } i = 0 n {\{Q_i\}}^{n}_{i=0}

Prometheus+Grafana构建企业级监控方案

1.prometheus工作原理&#xff1a; Prometheus将指标收集并存储为时间序列数据库&#xff08;时序数据库&#xff09;&#xff0c;即指标信息与记录它的时间戳一起存储&#xff0c;以及称为标签的可选键值对。 特性&#xff1a; 具有由指标名称和键/值对识别的时间序列数据的…

第23课:行业解决方案设计

第23课:行业解决方案设计 课程目标 掌握金融、医疗、教育等行业应用 学习领域特定Agent设计 了解行业标准集成 实践设计行业解决方案 课程内容 23.1 金融行业解决方案 金融Agent系统 class FinancialAgentSystem {constructor() {this.agents =

Go语言快速入门教程(JAVA转go)——2 环境搭建与入门

安装go Go官网下载地址&#xff1a;https://golang.org/dl/ 中国区官方镜像站&#xff08;推荐&#xff09;&#xff1a;https://golang.google.cn/dl/ windows安装 下载好后选择安装路径即可&#xff0c;安装完成后&#xff0c;winr 输入cmd调出命令行窗口&#xff0c;输入…

ffplay播放pcm

用 ffplay 播放 PCM 裸流时&#xff0c;必须手动告诉它“没有封装头、采样率、声道数、采样格式”四个关键点。命令模板如下&#xff1a; ffplay -f <采样格式> -ar <采样率> -ac <声道数> -i <pcm文件>常用组合示例 48 kHz、16 bit、小端、双声道 ffp…

【LLM】大模型训练中的稳定性问题

训练稳定性问题 &#x1f4cb; 概述 本文档详细介绍了在项目中解决训练稳定性问题的方法、原理分析以及实际应用。涵盖了梯度裁剪、损失函数优化、数值稳定化处理和学习率调度等关键技术。&#x1f6a8; 问题描述 现象: 训练过程中出现数值不稳定&#xff0c;损失函数波动剧烈 …

【linux系统】6. 基础开发工具(一)

一. 软件包管理器 1&#xff09;Linux下安装软件的常用方法 1. 源代码安装 下载程序的源代码&#xff0c;本地编译成二进制文件&#xff0c;拷贝到系统指定路径下。 2. rpm包安装 已经编译好的安装包&#xff0c;使用rpm对应的指令去安装&#xff0c;也比较麻烦。 3. 包…