本帖最后由 正点原子运营 于 2023-11-9 16:22 编辑
第十三章 静态数码管显示实验
1)实验平台:正点原子 ATK-DFPGL22G开发板
2) 章节摘自【正点原子】ATK-DFPGL22G之FPGA开发指南_V1.0
6)FPGA技术交流QQ群:435699340
数码管是一种现代常用的数码显示器件,具有发光显示清晰、响应速度快、功耗低、体积小、寿命长、易于控制等诸多优点,在数显仪器仪表、数字控制设备等方面得到广泛应用。本章我们将介绍八段数码管的控制原理以及如何在数码管上显示出变化的数字。 本章包括以下几个部分: 1.1 数码管简介 1.2 实验任务 1.3 硬件设计 1.4 程序设计 1.5 下载验证
1.1 数码管简介数码管也称半导体数码管,它是将若干发光二极管按一定图形排列并封装在一起的一种数码显示器件。常见的数码管如图 13.1.1所示,这种数码管主要被称为八段数码管或8字形数码管,可用来显示小数点、数字0~9,和英文字母A~F。 除了常用的八段数码管之外,较常见的还有“±1”数字管、“N”形管、“米”字管以及工业科研领域使用的14段管、16段管、24段管等。 不管是什么形式的数码管,其显示原理都是点亮内部的发光二极管来发光。那么如何用数码管显示指定的数字呢?
数码管内部电路如图 13.1.3所示,从该图可以看出,一位数码管的引脚是10个,其中7个引脚对应连接到组成数码管中间“8”字型的led,Dp引脚连接到数码管的小数点显示led(dp)。最后还有两个公共端,生产商为了封装统一,单个数码管都封装成10个引脚,其中8和3两个公共端引脚(图中为com)是连接在一起的。公共端又可分为共阳极和共阴极,图 13.1.3(b)为共阴极内部原理图,图 13.1.3(c)为共阳极内部原理图。 对共阴极数码管来说,其8个发光二极管的阴极在数码管内部全部连接在一起,所以称“共阴”,而阳极独立。对共阳极数码管来说,其8个发光二极管的阳极在数码管内部全部连接在一起,所以称“共阳”,而阴极独立。以共阳极数码管为例,当我们想让数码管显示数字“8”,可以给a、b、c…g七个引脚送低电平,数码管就显示“8”,显示数字“1”,就给b、c引脚低电平,其余引脚(除公共端)给高电平,数码管就显示“1”。
当多位数码管应用于某一系统时,为了减少数码管占用的I/O口,将其段选(数码管的a、b、c等引脚)连接在一起,而位选(数码管的公共端)独立控制。这样我们可以通过位选信号控制哪几个数码管亮,而且在同一时刻,位选选通的所有数码管上显示的数字始终都是一样的,因为它们的段选是连接在一起的,所以送入所有数码管的段选信号都是相同的,数码管的这种显示方法叫做静态显示。
对于静态显示还有一种是数码管的每一个码段都由一个单独的I/O端口进行驱动,其优点是编程较为简单,显示亮度较高;缺点是占用I/O较多,当数码管较多时,必须增加译码驱动器进行驱动,或使用串口转并口芯片来拓展端口。因而对于多位数码管的使用,一般都采用前一种方式进行电路设计,这种电路设计更为方便的是以动态方式驱动数码管。动态显示与静态显示的区别关键在于位选的控制。由于静态显示容易实现,本章我们以6位共阳数码管的静态方式为例,带大家初步了解一下数码管的工作原理。
1.2 实验任务本节实验任务是使用FPGA开发板上的6位数码管以静态方式依次显示000000、111111、222222至FFFFFF,结束后继续从000000开始计数,每0.5s变化一次。
1.3 硬件设计我们的开发板上有6位共阳数码管,其原理图如图 13.3.1所示。需要说明的是,这里的数码管使用的是共阳型数码管,在使用FPGA做驱动的时候,并不能直接采用通用的驱动方式,原因在于在硬件设计中,由于BANK电压的不同导致不能直接去点亮,所以对数码管的段选以及位选的驱动电路做了一些调整,观察原理图可以看到,位选部分我们采用S8050三极管做控制,故可以得到当三极管控制端为高电平时,三极管导通,对应的数码管位选端接地,呈现低电平,同时对段选部分分析,当三极管的控制端高电平的时候,对应开启旁边的NMOS管,该MOS管接入3.3v以达到持续为数码管提供稳定的供电的目的,但是MOS管会有开启的关断的延迟,如果不修改驱动方式会对数码管的显示造成影响,所以我们在代码中对段选的控制做了一定的处理,来解决显示异常的问题。 本实验中,各端口信号的管脚分配如下表所示:
对应的fdc约束语句如下所示: 1.4 程序设计根据实验任务,我们可以大致规划出系统的控制流程:首先我们需要一个静态数码管显示模块在数码管上显示数据,其次需要一个计时模块每当计时到0.5s时改变数码管显示的数值。由此画出系统的功能框图如下所示: 由系统框图可知,FPGA部分包括三个模块,顶层模块(seg_led_static_top)、计数器模块(time_count)以及数码管静态显示模块(seg_led_static)。其中在顶层模块中完成对其余模块的例化。 各模块端口及信号连接如下图所示: FPGA顶层例化了以下两个模块:计时模块和数码管静态显示模块,实现各模块之间数据的交互。计时模块将计时到0.5s时的标志信号flag传递给数码管静态显示模块,数码管静态显示模块接收到此信号时显示的数值增加1。 计时模块:计时模块对系统时钟进行计数,当计时到给定值(此处指0.5s)时输出标志信号。
数码管静态显示模块:数码管静态显示模块在数码管上以静态方式显示数值。
顶层模块代码如下: - 1 module seg_led_static_top (
- 2 input sys_clk , // 系统时钟
- 3 input sys_rst_n, // 系统复位信号(低有效)
- 4
- 5 output [5:0 sel , // 数码管位选
- 6 output [7:0 seg_led // 数码管段选
- 7
- 8 );
- 9
- 10 //parameter define
- 11 parameter TIME_SHOW = 25'd25000_000; // 数码管变化的时间间隔0.5s
- 12
- 13 //wire define
- 14 wire add_flag; // 数码管变化的通知信号
- 15
- 16 //*****************************************************
- 17 //** main code
- 18 //*****************************************************
- 19
- 20 //每隔0.5s产生一个时钟周期的脉冲信号
- 21 time_count #(
- 22 .MAX_NUM (TIME_SHOW)
- 23 ) u_time_count(
- 24 .clk (sys_clk ),
- 25 .rst_n (sys_rst_n),
- 26
- 27 .flag (add_flag )
- 28 );
- 29
- 30 //每当脉冲信号到达时,使数码管显示的数值加1
- 31 seg_led_static u_seg_led_static (
- 32 .clk (sys_clk ),
- 33 .rst_n (sys_rst_n),
- 34
- 35 .add_flag (add_flag ),
- 36 .sel (sel ),
- 37 .seg_led (seg_led )
- 38 );
- 39
- 40 endmodule
复制代码顶层模块主要完成对其余模块的例化。代码第11行的参数TIME_SHOW控制数码管每隔多长时间改变显示的数值,该参数值与代码第32行的clk时钟信号频率有关。由于例化时clk为系统时钟sys_clk(50MHz),所以每隔0.5秒改变数码管显示的数值时此参数值为
,此功能由计时模块(time_count)实现。
计时模块代码如下: - 1 module time_count(
- 2 input clk , // 时钟信号
- 3 input rst_n , // 复位信号
- 4
- 5 output reg flag // 一个时钟周期的脉冲信号
- 6 );
- 7
- 8 //parameter define
- 9 parameter MAX_NUM = 25000_000; // 计数器最大计数值
- 10
- 11 //reg define
- 12 reg [24:0 cnt; // 时钟分频计数器
- 13
- 14 //*****************************************************
- 15 //** main code
- 16 //*****************************************************
- 17
- 18 //计数器对时钟计数,每计时到0.5s,输出一个时钟周期的脉冲信号
- 19 always @ (posedge clk or negedge rst_n) begin
- 20 if (!rst_n) begin
- 21 flag <= 1'b0;
- 22 cnt <= 24'b0;
- 23 end
- 24 else if(cnt < MAX_NUM - 1'b1) begin
- 25 cnt <= cnt +1'b1;
- 26 flag <= 1'b0;
- 27 end
- 28 else begin
- 29 cnt <= 24'b0;
- 30 flag <= 1'b1;
- 31 end
- 32 end
- 33
- 34 endmodule
复制代码 代码中第9行的参数MAX_NUM为计数的最大计数值,由于是对时钟计数,相当于计时,第19行的always语句块表示的是当计数器cnt计数值小于MAX_NUM - 1'b1时,标志(flag)为“0”,否则标志为“1”,并且计数器cnt清零。
数码管静态显示模块的代码如下: - 1 module seg_led_static (
- 2 input clk , // 时钟信号
- 3 input rst_n , // 复位信号(低有效)
- 4
- 5 input add_flag, //数码管变化的通知信号
- 6 output reg [5:0 sel , // 数码管位选
- 7 output reg [7:0 seg_led //数码管段选
- 8 );
- 9
- 10 //reg define
- 11 reg [3:0 num; // 数码管显示的十六进制数
- 12
- 13 //*****************************************************
- 14 //** main code
- 15 //*****************************************************
- 16
- 17 //控制数码管位选信号(高电平有效),选中所有的数码管
- 18 always @ (posedge clk or negedge rst_n) begin
- 19 if (!rst_n)
- 20 sel <= 6'b000000;
- 21 else
- 22 sel <= 6'b111111;
- 23 end
- 24
- 25 //每次通知信号到达时,数码管显示的十六进制数值加1
- 26 always @ (posedge clk or negedge rst_n) begin
- 27 if (!rst_n)
- 28 num <= 4'h0;
- 29 else if(add_flag) begin
- 30 if (num < 4'hf)
- 31 num <= num + 1'b1;
- 32 else
- 33 num <= 4'h0;
- 34 end
- 35 else
- 36 num <= num;
- 37 end
- 38
- 39 //根据数码管显示的数值,控制段选信号
- 40 always @ (posedge clk or negedge rst_n) begin
- 41 if (!rst_n)
- 42 seg_led <= 8'b0;
- 43 else begin
- 44 case (num)
- 45 4'h0 : seg_led <= ~8'b1100_0000;
- 46 4'h1 : seg_led <= ~8'b1111_1001;
- 47 4'h2 : seg_led <= ~8'b1010_0100;
- 48 4'h3 : seg_led <= ~8'b1011_0000;
- 49 4'h4 : seg_led <= ~8'b1001_1001;
- 50 4'h5 : seg_led <= ~8'b1001_0010;
- 51 4'h6 : seg_led <= ~8'b1000_0010;
- 52 4'h7 : seg_led <= ~8'b1111_1000;
- 53 4'h8 : seg_led <= ~8'b1000_0000;
- 54 4'h9 : seg_led <= ~8'b1001_0000;
- 55 4'ha : seg_led <= ~8'b1000_1000;
- 56 4'hb : seg_led <= ~8'b1000_0011;
- 57 4'hc : seg_led <= ~8'b1100_0110;
- 58 4'hd : seg_led <= ~8'b1010_0001;
- 59 4'he : seg_led <= ~8'b1000_0110;
- 60 4'hf : seg_led <= ~8'b1000_1110;
- 61 default : seg_led <= ~8'b1100_0000;
- 62 endcase
- 63 end
- 64 end
- 65
- 66 endmodule
复制代码 代码第11行的num信号为数码管显示的数值,由代码第30行的if语句块可知,其能显示的数值为0~f。由于开发板上的数码管为共阳数码管,所以不显示小数点时该位值为“1”,因而seg_led信号的最高位为“1”。
1.5 下载验证 首先将下载器一端连接电脑,另一端与开发板上的JTAG下载口相连,最后连接电源线并打开电源开关。接下来我们下载程序,验证静态数码管显示的功能。
下载完成后观察到开发板上数码管显示的值从“000000”到“111111”依次增加到“FFFFFF”,如下图所示,说明数码管静态显示实验程序下载验证成功。
|