## 2个7段数码管显示 - 了解数码管显示的工作原理 - 加强对组合逻辑中的译码器的理解 - 掌握Verilog语言设计数码管显示驱动 ### 1. 知识点 {{ :7segled.gif |}} 数码管是工程设计中使用很广的一种显示输出器件。一个7段数码管(如果包括右下的小点可以认为是8段)分别由a、b、c、d、e、f、g位段和表示小数点的dp位段组成。实际是由8个LED灯组成的,控制每个LED的点亮或熄灭实现数字显示。通常数码管分为共阳极数码管和共阴极数码管,结构如下图所示: {{ :数码管.jpg |共阳极、共阴极数码管}} **图1 共阳极、共阴极数码管** 共阴8段数码管的信号端低电平有效,而共阳端接高电平有效。当共阳端接高电平时只要在各个位段上加上相应的低电平信号就可以使相应的位段发光。比如:要使a段发光,则在a段信号端加上低电平即可。共阴极的数码管则相反。 可以看到数码管的控制和LED的控制有相似之处,在[[STEP-MXO2第二代|小脚丫STEP-MXO2 V2]]开发板上有两位共阴极数码管, \\ {{ :undefined:7segment.png |}} \\ 数码管所有的信号都连接到FPGA的管脚,作为输出信号控制。FPGA只要输出这些信号就能够控制数码管的那一段LED亮或者灭。这样我们可以通过开关来控制FPGA的输出,和[[3. 3-8译码器]]实验一样,通过组合逻辑的输出来控制数码管显示数字,下面是数码管显示的表格 \\ {{ ::timg.jpg |}} \\ 这其实是一个4-16译码器 ### 2. CircuitJS中的电路仿真 {{ :7seg-js.mp4 |}} 在CircuitJS中仿真的效果 ### 3. 原理图 在本实验中我们使用了核心板上的4个开关SW和4个按键KEY来分别控制2个数码管的显示,通过开关和按键的组合得到不同的显示数值。 要注意的是开关和按键的状态正好相反: * 缺省状态时开关为低电平,按下开关时该端口变为高电平 * 缺省状态时按键为高电平,按下按键时该端口变为低电平 {{drawio>7_seg_x2_block.png}} ### 4. Verilog代码 如果我们想数码管能显示16进制可以全译码,如果只想显示数字,可以只利用其中10个译码,下面看看如果用Verilog来实现。 // ******************************************************************** // >>>>>>>>>>>>>>>>>>>>>>>>> COPYRIGHT NOTICE <<<<<<<<<<<<<<<<<<<<<<<<< // ******************************************************************** // File name : segment.v // Module name : segment // Author : STEP // Description : segment initial // Web : www.stepfpga.com // // -------------------------------------------------------------------- // Code Revision History : // -------------------------------------------------------------------- // Version: |Mod. Date: |Changes Made: // V1.0 |2021/10/08 |Initial ver // -------------------------------------------------------------------- // Module Function:数码管的译码模块初始化 module LED (seg_data_1,seg_data_2,seg_led_1,seg_led_2); input [3:0] seg_data_1; //数码管需要显示0~9十个数字,所以最少需要4位输入做译码 input [3:0] seg_data_2; //小脚丫上第二个数码管 output [8:0] seg_led_1; //在小脚丫上控制一个数码管需要9个信号 MSB~LSB=DIG、DP、G、F、E、D、C、B、A output [8:0] seg_led_2; //在小脚丫上第二个数码管的控制信号 MSB~LSB=DIG、DP、G、F、E、D、C、B、A reg [8:0] seg [9:0]; //定义了一个reg型的数组变量,相当于一个10*9的存储器,存储器一共有10个数,每个数有9位宽 initial //在过程块中只能给reg型变量赋值,Verilog中有两种过程块always和initial //initial和always不同,其中语句只执行一次 begin seg[0] = 9'h3f; //对存储器中第一个数赋值9'b00_0011_1111,相当于共阴极接地,DP点变低不亮,7段显示数字 0 seg[1] = 9'h06; //7段显示数字 1 seg[2] = 9'h5b; //7段显示数字 2 seg[3] = 9'h4f; //7段显示数字 3 seg[4] = 9'h66; //7段显示数字 4 seg[5] = 9'h6d; //7段显示数字 5 seg[6] = 9'h7d; //7段显示数字 6 seg[7] = 9'h07; //7段显示数字 7 seg[8] = 9'h7f; //7段显示数字 8 seg[9] = 9'h6f; //7段显示数字 9 end assign seg_led_1 = seg[~seg_data_1]; //连续赋值,这样输入不同四位数,就能输出对于译码的9位输出 assign seg_led_2 = seg[seg_data_2]; endmodule 注意最后的两句连续赋值语句的不同,原因在于4个按键和4个开关的缺省状态正好相反,所以对于第一个数码管的4个输入(对应于4个按键),需要先反相,相当于加了4个1位的反相器。 在Web IDE里面的效果如下: {{ :7_seg_verilog.png |}} 在Web IDE中的Verilog代码窗口 ### 5. 管脚分配 利用小脚丫上的4路按键(key)和4路开关(sw),作为输入信号分别控制2个数码管的显示输出。在Web IDE中的管脚分配见如下图: {{ :7_seg_pinout.png |}} 在Web IDE中2个数码管的控制管脚分配 ### 6. 功能验证 将生成的JED文件发送到小脚丫FPGA的STEPFPGA盘中,即可完成对其编程,编程后的效果如下: ### 7. 扩展使用 小脚丫FPGA核心板对外的扩展连接只需要36根IO,但采用了132BGA封装的芯片,在核心板上有足够的管脚用于核心板上几个器件(LED、数码管、开关、按键)的使用,因此核心板上的2个7段数码管采用了FPGA的管脚直接连接的独立显示模式。 但大多数应用场景需要用较少的IO管脚也能够驱动多个数码管,比如4个、6个乃至10个,如何才能实现?那就需要扫描显示的模式,即所有数码管共用8根数据信号线,各自再有1根选通信号线,采用分时的方式循环选通各位数码管,比如驱动4个数码管仅需要8+4 = 12根信号线进行显示。利用人眼的“视觉暂留效应”,可以使数码管显示看起来是同时显示。这种扫描显示模式实现起来相对比较复杂,但是节约信号线的使用。这种显示方式会在后面掌握了时序逻辑的基本概念以后再进行实现。 在实际的产品中,我们还可以使用专用的数码管驱动器件来实现,比如74HC595串行变并行的芯片、南京沁恒公司推出的[[http://www.wch.cn/products/CH450.html|数码管显示驱动芯片CH450]]等。