Verilog HDL 之 七段数码管扫描显示

本文介绍了一种利用Verilog HDL语言实现数码管扫描显示的方法。通过分频控制和译码逻辑,实现了对多个数码管的快速轮询显示,确保了良好的视觉效果并降低了功耗。

摘自:http://www.cnblogs.com/kongtiao/archive/2011/07/23/2114618.html

 

原理:

  一般来说,多个数码管的连接并不是把每个数码管都独立的与可编程逻辑器件连接,而是把所有的LED管的输入连在一起。如图1.1所示。

    

                      图1.1 扫描数码管的原理图

  这样做的好处有两点:一是节约了器件的IO口;其二是降低了功耗。每次向LED写数据时,通过片选选通其中一个LED,然后把数据写入该LED管,因此每个时刻只有一个LED管是亮的。为了能持续看见LED上面的显示内容,必须对LED管进行扫描,即依次并循环地点亮各个LED管。利用人眼的视觉暂停效应,在一定的扫描频率下,人眼就会看见好几个LED一起点亮。每个LED的功耗较大,如果所有的LED一起点亮,其功耗较大。利用扫描的方式,每个时刻只有LED管是亮的,可以大大的减少功耗。
  扫描频率大小不许合适才能有很好的效果。如果太小,而每个LED开启的时间大于人眼的视觉暂停时间,那么会产生闪烁现象。而扫描频率太大,则会造成LED的频繁开启和关断,大大增加LED功耗(开启和关断的时刻功耗很大)。一般来说,稍描频率选在50Hz比较合适。

实验实现:

  实现步骤请参照 【连载】 FPGA Verilog HDL 系列实例--------8-3编码器。这里就不再赘述。

设计文件输入Verilog HDL代码。

View Code
复制代码
 1 //-------------------------------------------------------------------------------------------------
 2 //
 3 // File        : scan_seg.v
 4 // Generated   : 2011-07-23
 5 // Author      : wangliang
 6 //
 7 //-------------------------------------------------------------------------------------------------
 8 
 9 `timescale 1 ns / 1 ps
10 
11 module scan_seg ( rst ,clk ,DIG ,Y );
12 
13 input rst ;
14 wire rst ;
15 input clk ;
16 wire clk ;
17 
18 output [7:0] DIG ;
19 wire [7:0] DIG ;
20 output [7:0] Y ;
21 wire [7:0] Y ;
22 
23 reg clkout ;
24 reg [31:0]cnt;  
25 reg [2:0]scan_cnt ;     
26 
27 parameter  period= 100000;
28 
29 assign Y = {1'b1,(~Y_r[6:0])};
30 assign DIG =~DIG_r;
31 reg [6:0] Y_r;
32 reg [7:0] DIG_r ;
33 
34 always @( posedge clk or negedge rst)      //分频50Hz
35     begin 
36     if (!rst)
37         cnt <= 0 ;
38     else  begin  
39             cnt<= cnt+1;
40         if (cnt    == (period >> 1) - 1)               
41                 clkout <= #1 1'b1;
42         else if (cnt == period - 1)                    
43             begin 
44                 clkout <= #1 1'b0;
45                  cnt <= #1 'b0;      
46             end
47          
48         end
49     end
50 
51 always @(posedge clkout or negedge rst)          
52     begin 
53       if (!rst)
54         scan_cnt <= 0 ;
55     else  begin
56         scan_cnt <= scan_cnt + 1;    
57         if(scan_cnt==3'd7)  scan_cnt <= 0;
58         end 
59     end
60     
61 always @( scan_cnt)         //数码管选择
62     begin 
63     case ( scan_cnt )    
64         3'b000 : DIG_r <= 8'b0000_0001;    
65         3'b001 : DIG_r <= 8'b0000_0010;    
66         3'b010 : DIG_r <= 8'b0000_0100;    
67         3'b011 : DIG_r <= 8'b0000_1000;    
68         3'b100 : DIG_r <= 8'b0001_0000;    
69         3'b101 : DIG_r <= 8'b0010_0000;    
70         3'b110 : DIG_r <= 8'b0100_0000;     
71         3'b111 : DIG_r <= 8'b1000_0000;    
72         default :DIG_r <= 8'b0000_0000;    
73     endcase
74     end
75 
76 always @ (scan_cnt ) //译码
77     begin 
78     case (scan_cnt)
79         0: Y_r = 7'b0111111; // 0
80         1: Y_r = 7'b0000110; // 1
81         2: Y_r = 7'b1011011; // 2
82         3: Y_r = 7'b1001111; // 3
83         4: Y_r = 7'b1100110; // 4
84         5: Y_r = 7'b1101101; // 5
85         6: Y_r = 7'b1111101; // 6
86         7: Y_r = 7'b0100111; // 7
87         8: Y_r = 7'b1111111; // 8
88         9: Y_r = 7'b1100111; // 9
89         10: Y_r = 7'b1110111; // A
90         11: Y_r = 7'b1111100; // b
91         12: Y_r = 7'b0111001; // c
92         13: Y_r = 7'b1011110; // d
93         14: Y_r = 7'b1111001; // E
94         15: Y_r = 7'b1110001; // F
95         default: Y_r = 7'b0000000;
96     endcase
97     end    
98     
99 endmodule
复制代码

代码分析:

  可以看出这部分代码由4部分组成,第一部分是分频,因为我们扫描数码管不需要很快的频率,第二部分是选择控制数码管的位置,第三部分是对第二部分的译码,第四部分是显示数据。

引脚分配:

  由Verilog HDL设计文件生成的.bsf文件如图1.2所示

 

        图1.2 七段数码管的外部接口图

  clk接系统时钟,rst接复位信号,DIG[7..0]接选择的的数码管(控制显示在哪一个数码管上),Y[7..0]接数码管的显示位(控制显示什么数字)。

实验结果:

  在上面的数码管上从前到后一次显示76543210.

### 七段数码管的工作原理与电路设计 #### 工作原理 七段数码管是一种常见的电子显示设备,通常由七个发光二极管(LED)组成,分别标记为 a 到 g。这些段的点亮组合可以显示数字 0 到 9 及部分字母[^1]。每个段的 LED 在正向电压下导通时会发光,通过控制不同段的导通状态,可以实现不同的字符显示。 在共阴极数码管中,所有 LED 的阴极连接在一起并接地,阳极则分别控制各个段;而在共阳极数码管中,所有 LED 的阳极连接在一起并接至电源,阴极则分别控制各个段。因此,在共阴极配置中,高电平使段点亮,而共阳极则相反,低电平使段点亮[^1]。 #### 原理图 一个典型的七段数码管原理图包括七个段 a~g,以及可能存在的 dp 段(小数点)。每个段都包含一个 LED,其两端分别连接到对应的驱动引脚和公共端(阴极或阳极)。例如,在共阴极数码管中,所有 LED 的阴极连接到地,而阳极则连接到各自的驱动电路输出端[^3]。 ``` a ------- | | f | | b | g | ------- | | e | | c | | ------- d (dp) ``` #### 电路设计 在实际应用中,为了减少所需的 I/O 引脚数量,通常使用多路复用技术来控制多个数码管。例如,在一个四位数码管系统中,每个数码管的段码输入共享同一组信号线,但每个数码管的公共端(通常是阴极或阳极)连接到独立的选通信号线上。这样可以通过快速切换选通信号,依次点亮每个数码管,利用人眼的视觉暂留效应实现连续显示效果[^3]。 以下是一个简化的 C 语言示例代码,展示了如何在 51 单片机上实现动态扫描显示: ```c #include <reg51.h> #define uchar unsigned char #define uint unsigned int sbit Data_L = P2^0; sbit Led_L = P2^1; uchar code table[] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71}; void delay(uint ms) { while(ms--) { // Delay implementation } } void main() { uchar i; P0 = 0xFF; // Initialize segment lines to high impedance state Data_L = 1; Led_L = 1; Data_L = 0; Led_L = 0; while(1) { for(i=0; i<8; i++) { P0 = table[i]; // Send the segment code Data_L = 1; Data_L = 0; P0 = 0x01 << i; // Select the current digit Led_L = 1; Led_L = 0; delay(500); // Delay to prevent ghosting } } } ``` 此代码片段演示了如何使用查表法获取相应的段码,并通过延时函数控制数码管的刷新频率,从而实现稳定的显示效果。 #### 数字逻辑设计中的应用 在数字逻辑课程实验中,七段数码管常被用来作为加法器结果的输出设备。例如,使用两个无符号数相加的结果可以通过分离器将 1bit 输出转换成 4bit 输入,然后传递给七段译码器的输入端口,最终在数码管上显示出加法运算的结果[^2]。 #### 相关问题
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值