OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 10647|回复: 0
打印 上一主题 下一主题

[ALTERA] 【正点原子FPGA连载】第十一章 静态数码管显示实验--摘自《正点原子开拓者FPGA开发指南》

[复制链接]

527

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165778
金钱
165778
注册时间
2010-12-1
在线时间
2124 小时
跳转到指定楼层
楼主
发表于 2019-5-8 18:43:06 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
1)实验平台:正点原子开拓者FPGA开发板
2)全套实验源码+手册+视频下载地址:http://www.openedv.com/thread-281143-1-1.html
3)本实例源码下载: 5_seg_led_static_top.rar (3 MB, 下载次数: 32)
4)对正点原子Linux感兴趣的同学可以加群讨论:712557122  点击加入:
5)关注正点原子公众号,获取最新资料更新:

                                         第十一章 静态数码管显示实验

数码管是一种现代常用的数码显示器件,具有发光显示清晰、响应速度快、功耗低、体积小、寿命长、易于控制等诸多优点,在数显仪器仪表、数字控制设备等方面得到广泛应用。本章我们将介绍八段数码管的控制原理以及如何在数码管上显示出变化的数字。
本章包括以下几个部分:
1         
1.1         数码管简介
1.2         实验任务
1.3         硬件设计
1.4         程序设计
1.5         下载验证


1.1      数码管简介
数码管也称半导体数码管,它是将若干发光二极管按一定图形排列并封装在一起的一种数码显示器件。常见的数码管如图 11.1.1所示,这种数码管主要被称为八段数码管或8字形数码管,可用来显示小数点、数字0~9,和英文字母A~F。

图 11.1.1 八段数码管
除了常用的八段数码管之外,较常见的还有“±1”数字管、“N”形管、“米”字管以及工业科研领域使用的14段管、16段管、24段管等。

图 11.1.2 其他常用数码管
不管是什么形式的数码管,其显示原理都是点亮内部的发光二极管来发光。那么如何用数码管显示指定的数字呢?
数码管内部电路如图 11.1.3所示,从该图可以看出,一位数码管的引脚是10个,其中7个引脚对应连接到组成数码管中间“8”字型的led,Dp引脚连接到数码管的小数点显示led(dp)。最后还有两个公共端,生产商为了封装统一,单个数码管都封装成10个引脚,其中8和3两个公共端引脚(图中为com)是连接在一起的。公共端又可分为共阳极和共阴极,图 11.1.3(b)为共阴极内部原理图,图 11.1.3(c)为共阳极内部原理图。

图 11.1.3 数码管内部原理图
对共阴极数码管来说,其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      硬件设计
我们的开拓者FPGA开发板上有6位共阳数码管,其原理图如图 11.3.1所示。在这里我们需要注意的是,为了增加FPGA输出信号的驱动能力,我们使用PNP型三极管驱动数码管的位选段,所以给三极管基极提供低电平时,位选信号为高电平。

图 11.3.1 硬件原理图
本实验中,各端口信号的管脚分配如下表所示:
表 11.3.1 静态数码管显示实验管脚分配图
  
信号名
  
方向
管脚
端口说明
sys_clk
input
E1
系统时钟,50M
sys_rst_n
input
M1
系统复位,低有效
sel[0]
output
N16
数码管位选0
sel[1]
output
N15
数码管位选1
sel[2]
output
P16
数码管位选2
sel[3]
output
P15
数码管位选3
sel[4]
output
R16
数码管位选4
sel[5]
output
T15
数码管位选5
seg_led[0]
output
M11
数码管段选a
seg_led[1]
output
N12
数码管段选b
seg_led[2]
output
C9
数码管段选c
seg_led[3]
output
N13
数码管段选d
seg_led[4]
output
M10
数码管段选e
seg_led[5]
output
N11
数码管段选f
seg_led[6]
output
P11
数码管段选g
seg_led[7]
output
D9
数码管段选h
1.4      程序设计
根据实验任务,我们可以大致规划出系统的控制流程:首先我们需要一个静态数码管显示模块在数码管上显示数据,其次需要一个计时模块每当计时到0.5s时改变数码管显示的数值。由此画出系统的功能框图如下所示:

图 11.4.1 数码管静态显示实验系统框图
程序中各模块端口及信号连接如图 11.4.2所示:

图 11.4.2 顶层模块原理图
FPGA顶层(seg_led_static_top)例化了以下两个模块:计时模块(time_count)和数码管静态显示模块(seg_led_static),实现各模块之间数据的交互。计时模块将计时到0.5s时的标志信号flag传递给数码管静态显示模块,数码管静态显示模块接收到此信号时显示的数值增加1。
计时模块(time_count):计时模块对系统时钟进行计数,当计时到给定值(此处指0.5s)时输出标志信号。
数码管静态显示模块(seg_led_static):数码管静态显示模块在数码管上以静态方式显示数值。
顶层模块的代码如下:
1  moduleseg_led_static_top (
2      //global clock
3      input               sys_clk  ,       // 系统时钟
4      input               sys_rst_n,       // 系统复位信号(低有效)
5  
6      //seg_ledinterface
7      output    [5:0]     sel     ,       // 数码管显示控制
8      output    [7:0]     seg_led          // 数码管显示的数据
9  
10 );
11
12 //parameter define
13 parameter TIME_SHOW = 25'd25000_000;     // 每个数字显示的时间
14
15 //wire define
16 wire      add_flag;                      //增1标志信号
17
18 //*****************************************************
19 //**                    main code
20 //*****************************************************
21
22seg_led_static u_seg_led_static (
23     //modele clock
24     .clk        (sys_clk  ),             // 模块时钟信号
25     .rst_n      (sys_rst_n),            // 复位信号(低有效)
26     //seg_ledinterface
27     .sel        (sel      ),             //数码管显示控制
28     .seg_led    (seg_led  ),             //数码管显示的数据
29     .add_flag   (add_flag)              // 数值增1标志信号
30 );
31
32time_count #(.MAX_NUM(TIME_SHOW)
33 ) u_time_count(
34     //system clock
35     .clk        (sys_clk  ),             // 时钟信号
36     .rst_n      (sys_rst_n),            // 复位信号
37     //user interface
38     .flag       (add_flag)              // 数值增1标志信号
39 );
40
41 endmodule
顶层模块主要完成对其余模块的例化。代码第13行的参数TIME_SHOW控制数码管每隔多长时间改变显示的数值,该参数值与代码第35行的clk时钟信号频率有关。由于例化时clk为系统时钟sys_clk(50MHz),所以每隔0.5秒改变数码管显示的数值时此参数值为 ,此功能由计时模块(time_count)实现。
计时模块的代码如下所示:
1  moduletime_count(
2      //system clock
3      input           clk     ,                // 时钟信号
4      input           rst_n   ,                // 复位信号
5  
6      //userinterface
7      output   reg    flag                     //计满标志
8  );
9  
10 //parameter define
11 parameter MAX_NUM = 25000_000;              // 计数器最大计数(0.5s)
12
13 //reg define
14 reg    [24:0]     cnt     ;                 // 时钟分频计数器
15
16 //*****************************************************
17 //**                   main code
18 //*****************************************************
19
20 //计数
21 always @ (posedge clk or negedgerst_n) begin
22     if (!rst_n) begin
23         flag <=  1'b0;
24         cnt <= 24'b0;
25     end
26     elseif(cnt < MAX_NUM -1'b1)begin
27         flag <=1'b0;
28         cnt <= cnt +1'b1;
29     end
30     elsebegin
31         flag <=  1'b1;
32         cnt <= 24'b0;
33     end
34 end
35
36 endmodule
代码中第11行的参数MAX_NUM为计数的最大计数值,由于是对时钟计数,相当于计时,第21行的always语句块表示的是当计数器cnt计数值小于MAX_NUM - 1'b1时,标志(flag)为“0”,否则标志为“1”,并且计数器cnt清零。通过SignalTapII抓到的波形图如下图所示:

图 11.4.3 SignalTap波形图
数码管静态显示模块的代码如下:
1  moduleseg_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 negedgerst_n) begin
19     if (!rst_n)
20         sel <=6'b111111;
21     else
22         sel <=6'b000000;
23 end
24
25 //每次通知信号到达时,数码管显示的十六进制数值加1
26 always @ (posedge clk or negedgerst_n) begin
27     if (!rst_n)
28         num <=4'h0;
29     elseif(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 negedgerst_n) begin
41     if (!rst_n)
42         seg_led <=8'b0;
43     elsebegin
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”。下图为该模块运行时SignalTapII抓取到的波形图:

图 11.4.4 SignalTapb波形图
由该波形图可知,当add_flag信号拉高时,数值信号num加1,输出对应的段选数据由F8h变为80h,与代码设计的意图相符。
1.5      下载验证
首先我们打开数码管静态显示实验工程,在工程所在的路径下打开seg_led_static_top/par文件夹,在里面找到“seg_led_static_top.qpf”并双击打开。注意工程所在的路径名只能由字母、数字以及下划线组成,不能出现中文、空格以及特殊字符等。工程打开后如图 11.5.1所示。

图 11.5.1 数码管静态显示实验工程
然后将下载器一端连接电脑,另一端与开发板上的JTAG下载口相连,最后连接电源线并打开电源开关。
接下来我们下载程序,验证静态数码管显示的功能。
工程打开后通过点击工具栏中的“Programmer”图标打开下载界面,通过“Add File”按钮选择seg_led_static_top/par/output_files目录下的“seg_led_static_top.sof”文件。开发板电源打开后,在程序下载界面点击“HardwareSetup”,在弹出的对话框中选择当前的硬件连接为“USB-Blaster[USB-0]”。然后点击“Start”将工程编译完成后得到的sof文件下载到开发板中,如图 11.5.2所示。

图 11.5.2 程序下载界面
下载完成后观察到开发板上数码管显示的值从“000000”到“111111”依次增加到“FFFFFF”,如下图所示,说明数码管静态显示实验程序下载验证成功。

图 11.5.3 数码管静态显示实验结果显示

image252.png (870 Bytes, 下载次数: 236)

image252.png

image258.png (589 Bytes, 下载次数: 260)

image258.png
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子产品购买店铺https://zhengdianyuanzi.tmall.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /1 下一条

正点原子公众号

如发现本坛存在违规或侵权内容, 请点击这里发送邮件举报 (或致电020-38271790)。请提供侵权说明和联系方式。我们将及时审核依法处理,感谢配合。

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2026-9-9 02:12

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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