首先,翻译一下使用手册上的说明:
Nexys2开发板包含四位公共阳极七段LED显示屏。 每一个数字由按数字“8”图案排列的七个片段组成,其中嵌入有LED灯。 每段LED可以单独点亮,所以一共可以表示128种图案。
形成每个数字的七个LED灯的阳极被连接在一起成为一个“公共阳极”电路节点,但LED阴极保持分离。 公共阳极信号可用作四位数字的启用输入信号。 四个数字上相同位置的LED灯的阴极是连接到标记为CA到CG的七个电路节点(例如,四个“D”阴极组合到一起成为“CD”电路节点)。 这七个阴极信号可用作4位显示的输入。 该信号连接方案创建一个多重显示,其中阴极信号对所有数字是通用的,但它们只能照亮阳极信号被接通的数字段。可以使用扫描显示控制器电路在该显示器上显示四位数字。 这个电路驱动每个数字的阳极信号和相应的阴极信号,以比人眼可以检测到的更快的速度连续更新。每个数字照亮了四分之一的时间,但因为在眼睛不能察觉到数字变暗之前,数字又再次亮起,所以看到的数字显示持续亮起。 如果更新或“刷新”率放慢到45赫兹左右,大多数人会开始看到显示屏闪烁。为了使四位数字中的每一位出现明亮且持续亮起,所有四位都应该是每1到16ms驱动一次,刷新频率为1KHz至60Hz。 例如,对于60Hz刷新方案,整个显示屏将每16ms刷新一次,每个数字将被刷新的周期为总周期的1/4,或4ms。 控制器必须以正确的方式驱动阴极和相应的阳极信号。为了说明这个过程,如果在确认CB和CC时AN0被接通,则在数字显示为1。如果AN1在CA,CB和CC被接通时被接通,则将显示数字“7” 。如果AN0和CB,CC被驱动为4ms,然后A1和CA,CB,CC连续驱动4ms,显示屏将在前两位显示“17”。
那让我们看看具体要怎样做:
首先写一个模块实现数字到这种图形的转化,也就是七段译码器:
//七段译码器
module qiduanyimaqi(q_num, q_out);
input[3:0] q_num;
output[7:0] q_out;
reg[7:0] q_out;
always @(q_num)
begin
case(q_num)
4'b0000:q_out = 8'b00000011;
4'b0001:q_out = 8'b10011111;
4'b0010:q_out = 8'b00100101;
4'b0011:q_out = 8'b00001101;
4'b0100:q_out = 8'b10011001;
4'b0101:q_out = 8'b01001001;
4'b0110:q_out = 8'b01000001;
4'b0111:q_out = 8'b00011011;
4'b1000:q_out = 8'b00000001;
4'b1001:q_out = 8'b00001001;
default q_out = 8'b00000011;
endcase
end
endmodule
然后需要写一个能将要表示的数字转化为发向七段译码器的数字信号,实现代码如下 :
d_num1到d_num4分别为要显示的4个数字。d1_wx和d1_out分别表示阳极接通情况和8段LED接通情况。
//七段译码器显示处理模块 用于将num1,num2,num3和num4的数字显示在屏幕上
module dtsm(MCLK9, d_num1, d_num2, d_num3, d_num4, d1_wx, d1_out);
input MCLK9;
input[3:0] d_num1;
input[3:0] d_num2;
input[3:0] d_num3;
input[3:0] d_num4;
output[3:0] d1_wx;
output[7:0] d1_out;
reg[3:0] d1_wx = 4'b1110;
wire[7:0] d1_out;
reg[3:0] d_tmp_num;
always @(posedge MCLK9) begin
case(d1_wx)
4'b1110:begin
d_tmp_num = d_num2;
d1_wx = 4'b1101;
end
4'b1101:begin
d_tmp_num = d_num3;
d1_wx = 4'b1011;
end
4'b1011:begin
d_tmp_num = d_num4;
d1_wx = 4'b0111;
end
4'b0111:begin
d_tmp_num = d_num1;
d1_wx = 4'b1110;
end
default: d1_wx = 4'b1110;
endcase
end
qiduanyimaqi qiduanyimaqi(d_tmp_num, d1_out);
endmodule
然后如果直接将板上50MHZ的时钟信号输入,那么因为扫描速度太快,数字会看不清楚
所以我们需要写一个降频器(200Hz):
module div(
input clk,
output reg clk_slow
);
reg [24:0] cnt_div = 25'b0;
always@(posedge clk)
begin
if(cnt_div == 25'd1_000_00)
begin
cnt_div <= 25'b0;
clk_slow <= 1'b1;
end
else
begin
cnt_div <= cnt_div + 25'b1;
clk_slow <= 1'b0;
end
end
endmodule
最后就是修改引脚绑定代码如下
#4个七段译码器
# 7 segment display NET "d1_out[7]" LOC = "L18"; # Bank = 1, Pin name = IO_L10P_1, Type = I/O, Sch name = CA NET "d1_out[6]" LOC = "F18"; # Bank = 1, Pin name = IO_L19P_1, Type = I/O, Sch name = CB NET "d1_out[5]" LOC = "D17"; # Bank = 1, Pin name = IO_L23P_1/HDC, Type = DUAL, Sch name = CC NET "d1_out[4]" LOC = "D16"; # Bank = 1, Pin name = IO_L23N_1/LDC0, Type = DUAL, Sch name = CD NET "d1_out[3]" LOC = "G14"; # Bank = 1, Pin name = IO_L20P_1, Type = I/O, Sch name = CE NET "d1_out[2]" LOC = "J17"; # Bank = 1, Pin name = IO_L13P_1/A6/RHCLK4/IRDY1, Type = RHCLK/DUAL, Sch name = CF NET "d1_out[1]" LOC = "H14"; # Bank = 1, Pin name = IO_L17P_1, Type = I/O, Sch name = CG #NET "d1_out[0]" LOC = "C17"; # Bank = 1, Pin name = IO_L24N_1/LDC2, Type = DUAL, Sch name = DP NET "d1_wx[0]" LOC = "F17"; # Bank = 1, Pin name = IO_L19N_1, Type = I/O, Sch name = AN0 NET "d1_wx[1]" LOC = "H17"; # Bank = 1, Pin name = IO_L16N_1/A0, Type = DUAL, Sch name = AN1 NET "d1_wx[2]" LOC = "C18"; # Bank = 1, Pin name = IO_L24P_1/LDC1, Type = DUAL, Sch name = AN2 NET "d1_wx[3]" LOC = "F15"; # Bank = 1, Pin name = IO_L21P_1, Type = I/O, Sch name = AN3