1. 理论
1.1 显示原理
由上图数码管接线可知数码管LED灯的所有阳级(正极)接公共端,故该数码管为共阳数码管。这六位数码管段阴级(负极)都并联,在阳极都给高电平的同时阴极拉低,数码管就会被点亮。
数码管显示有分为静态显示和动态显示,静态显示特点是在同一时间上所有位显示是相同的数值,显示单一无法满足更多的需求。往往使用更加更多的是动态显示,程序设计会更加复杂。动态显示可以实现六位数码管上内容都不一样比如显示742347这个数。
在余晖效应的作用下,若一个数码管在 1s 内点亮两次,人眼很明显的看到其亮了两次,若 1s 内点亮 10 次呢?只能看到其在快速的闪烁,若点亮 100 次 1000次呢?总有一个速度是人眼分辨不出来在闪烁的(1ms)。所以一个数码管一直亮不需要一直给高电平,只要在很短的时间点亮一次后熄灭,再点亮熄灭。在六位数码管中,在很短的时间点亮第一位数码管的同时,驱动段选(发此位数码管需显示的数据),然后在点亮下一位同时驱动段选,六位以此循环看起来六位数码管就是同一时刻显示且显示的内容不一样,这样的方法称为动态扫描。
最后总结动态显示的驱动方式:使用 1ms 的刷新时间让六个数码管轮流显示,:第 1ms 点第一个数码管,第 2ms 点亮第二个数码管,以此类推依次点亮六个数码管, 6ms 一个轮回。点亮相应数码管的时候给驱动段选使其显示相应的值,这样就可以使六个数码管显示不同的值,并且人眼察觉不到数码管在闪烁。
2. 实践
2.1 静态数码管
重点学习动态,这里只提供波形、代码给大家参考。
实验效果:控制六位数码管让其以 000000、 111111、 222222 一直到 FFFFFF 循环显示。每个字符显示 0.5s 后变化。
`timescale 1ns/1ns
module seg_static
(
input wire sys_clk ,
input wire sys_rst_n ,
output reg [5:0] sel , //数码管位选信号
output reg [7:0] seg //数码管段选信号
);
parameter 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 define
reg add_flag ;
reg [24:0] cnt_wait ;
reg [3:0] num ;
//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;
else
cnt_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)
add_flag <= 1'b1;
else
add_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;
else
num <= num;
//sel:选中六个数码管
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
sel <= 6'b000000;
else
sel <= 6'b111111;
/