本设计中使用 6 个共阳数码管,可以显示 6 个数字(包含小数点) 。电路用 PNP管来反向驱动并且控制列扫描信号来选择哪个数码管。而且所有的 6 个数码管的“段选信号”(LEDA … LEDH)都共用驱动引脚(LED_A~LEDH)。数码管的所有驱动信号都是“低电平有效”。具体的原理图设计如下图所示:
单个数码管可以采用静态显示方式,如图所示,数码管被分成 a、 b、 c、 d、e、 f、 g 和小数点,每段可以单独控制亮灭,通过点亮不同的段显示不同的数字和字符。
其编码表如下
依照一定的频率位选各数码管,利用人的视觉暂留来达到视觉上的连续感。
//////////////////////////////////////////////////////////////////////////////////
// Company: NanJing University of Information Science & Technology
// Engineer: Yang Cheng Yu
//
// Create Date: 2019/12/29 15:55:40
// Design Name: seg_decoder
// Module Name: seg_decoder
// Project Name: Clock
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module seg_decoder
(
input clk,
input rst,
input[3:0] bin_data, // bin data input,0-f
output reg[6:0] seg_data // seven segments LED output
);
always@(posedge clk or negedge rst)
begin
if(!rst)
seg_data <= 7'b111_1111;
else
case(bin_data)
4'd0:seg_data <= 7'b100_0000;
4'd1:seg_data <= 7'b111_1001;
4'd2:seg_data <= 7'b010_0100;
4'd3:seg_data <= 7'b011_0000;
4'd4:seg_data <= 7'b001_1001;
4'd5:seg_data <= 7'b001_0010;
4'd6:seg_data <= 7'b000_0010;
4'd7:seg_data <= 7'b111_1000;
4'd8:seg_data <= 7'b000_0000;
4'd9:seg_data <= 7'b001_0000;
4'ha:seg_data <= 7'b000_1000;
4'hb:seg_data <= 7'b000_0011;
4'hc:seg_data <= 7'b100_0110;
4'hd:seg_data <= 7'b010_0001;
4'he:seg_data <= 7'b000_0110;
4'hf:seg_data <= 7'b000_1110;
default:seg_data <= 7'b111_1111;
endcase
end
endmodule
为了节省引脚资源,每个数码管共用一路段选信号,通过一定频率的分别位选来实现六位数码管的显示。则需要引入一个段选、位选控制模块
//////////////////////////////////////////////////////////////////////////////////
// Company: NanJing University of Information Science & Technology
// Engineer: Yang Cheng Yu
//
// Create Date: 2019/12/29 15:55:40
// Design Name: seg_control
// Module Name: seg_control
// Project Name: Clock
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module seg_control(
input clk,
input rst,
input [6:0] seg_data_in0,//第1位数码管信号输入
input [6:0] seg_data_in1,//第2位数码管信号输入
input [6:0] seg_data_in2,//第3位数码管信号输入
input [6:0] seg_data_in3,//第4位数码管信号输入
input [6:0] seg_data_in4,//第5位数码管信号输入
input [6:0] seg_data_in5,//第6位数码管信号输入
output reg[6:0] seg_sel, //段选信号输出
output reg[5:0] bit_sel //位选信号输出
);
reg[2:0] state;
reg[15:0] wait_cnt; //等待时间计数器,等待时间1ms
reg cnt_full; //计数器计满信号
reg cnt_en; //计数器使能信号
localparam START =3'b000;//起始状态
localparam DISP_SEG0=3'b001;//显示第1位数据
localparam DISP_SEG1=3'b011;//显示第2位数据
localparam DISP_SEG2=3'b010;//显示第3位数据
localparam DISP_SEG3=3'b110;//显示第4位数据
localparam DISP_SEG4=3'b100;//显示第5位数据
localparam DISP_SEG5=3'b101;//显示第6位数据
parameter WAIT_VAL=1000;//1000微秒
localparam WAIT_CNT_MAX=WAIT_VAL*1000/20-1;
reg[6:0] seg_data_reg0;//数码管0段选信号寄存器
reg[6:0] seg_data_reg1;//数码管1段选信号寄存器
reg[6:0] seg_data_reg2;//数码管2段选信号寄存器
reg[6:0] seg_data_reg3;//数码管3段选信号寄存器
reg[6:0] seg_data_reg4;//数码管4段选信号寄存器
reg[6:0] seg_data_reg5;//数码管5段选信号寄存器
always@(posedge clk or negedge rst)begin
if(!rst)begin
wait_cnt <= 16'd0;
cnt_full <= 1'b0;
end
else begin
if(cnt_en)
if(wait_cnt==WAIT_CNT_MAX)begin//1ms 计数器值为=1000_000/20=50000
wait_cnt <= 16'd0;
cnt_full <= 1'b1;
end
else begin
wait_cnt <= wait_cnt + 1'b1;
cnt_full <= 1'b0;
end
else begin
wait_cnt <= 16'd0;
cnt_full <= 1'b0;
end
end
end
//状态转移逻辑
always@(posedge clk or negedge rst)begin
if(!rst)
state <= START;
else
case(state)
START:
state <= DISP_SEG0;
DISP_SEG0:
if(cnt_full)
state <= DISP_SEG1;
else
state <= DISP_SEG0;
DISP_SEG1:
if(cnt_full)
state <= DISP_SEG2;
else
state <= DISP_SEG1;
DISP_SEG2:
if(cnt_full)
state <= DISP_SEG3;
else
state <= DISP_SEG2;
DISP_SEG3:
if(cnt_full)
state <= DISP_SEG4;
else
state <= DISP_SEG3;
DISP_SEG4:
if(cnt_full)
state <= DISP_SEG5;
else
state <= DISP_SEG4;
DISP_SEG5:
if(cnt_full)
state <= START;
else
state <= DISP_SEG5;
endcase
end
//状态输出逻辑
always@(posedge clk or negedge rst)begin
if(!rst)begin
cnt_en <= 1'b0;
seg_sel <= 7'b1111_111;
bit_sel <= 6'b111_111;
end
else
case(state)//起始状态先锁存输入数码管数据
START:begin
cnt_en <= 1'b0;
seg_sel <= 7'b1111_111;
bit_sel <= 6'b111_111;
seg_data_reg0 <= seg_data_in0;
seg_data_reg1 <= seg_data_in1;
seg_data_reg2 <= seg_data_in2;
seg_data_reg3 <= seg_data_in3;
seg_data_reg4 <= seg_data_in4;
seg_data_reg5 <= seg_data_in5;
end
DISP_SEG0:begin//显示第1位数码管数据
cnt_en <= 1'b1;
seg_sel <= seg_data_reg0;
bit_sel <= 6'b011_111;
end
DISP_SEG1:begin//显示第2位数码管数据
cnt_en <= 1'b1;
seg_sel <= seg_data_reg1;
bit_sel <= 6'b101_111;
end
DISP_SEG2:begin//显示第3位数码管数据
cnt_en <= 1'b1;
seg_sel <= seg_data_reg2;
bit_sel <= 6'b110_111;
end
DISP_SEG3:begin//显示第4位数码管数据
cnt_en <= 1'b1;
seg_sel <= seg_data_reg3;
bit_sel <= 6'b111_011;
end
DISP_SEG4:begin//显示第5位数码管数据
cnt_en <= 1'b1;
seg_sel <= seg_data_reg4;
bit_sel <= 6'b111_101;
end
DISP_SEG5:begin//显示第6位数码管数据
cnt_en <= 1'b1;
seg_sel <= seg_data_reg5;
bit_sel <= 6'b011_110;
end
default:begin
cnt_en <= 1'b0;
seg_sel <= 7'b111_1111;
bit_sel <= 6'b111_111;
end
endcase
end
endmodule
将数码管解码模块与控制模块级联就可以构成本设计中的时钟显示模块
module time_disp(
input clk,
input rst,
input[3:0] s_ge_seg_in,
input[3:0] s_shi_seg_in,
input[3:0] min_ge_seg_in,
input[3:0] min_shi_seg_in,
input[3:0] h_ge_seg_in,
input[3:0] h_shi_seg_in,
output[6:0] seg_sel,
output[5:0] bit_sel
);
wire[6:0] s_ge;
wire[6:0] s_shi;
wire[6:0] min_ge;
wire[6:0] min_shi;
wire[6:0] h_ge;
wire[6:0] h_shi;
seg_control seg_control(
.clk(clk),
.rst(rst),
.seg_data_in0(s_ge),//第1位数码管信号输入
.seg_data_in1(s_shi),//第2位数码管信号输入
.seg_data_in2(min_ge),//第3位数码管信号输入
.seg_data_in3(min_shi),//第4位数码管信号输入
.seg_data_in4(h_ge),//第5位数码管信号输入
.seg_data_in5(h_shi),//第6位数码管信号输入
.seg_sel(seg_sel), //段选信号输出
.bit_sel(bit_sel) //位选信号输出
);
seg_decoder seg_s_ge_wei
(
.clk(clk),
.rst(rst),
.bin_data(s_ge_seg_in), // bin data input,0-f
.seg_data(s_ge) // seven segments LED output
);
seg_decoder seg_s_shi_wei
(
.clk(clk),
.rst(rst),
.bin_data(s_shi_seg_in), // bin data input,0-f
.seg_data(s_shi) // seven segments LED output
);
seg_decoder seg_min_ge_wei
(
.clk(clk),
.rst(rst),
.bin_data(min_ge_seg_in), // bin data input,0-f
.seg_data(min_ge) // seven segments LED output
);
seg_decoder seg_min_shi_wei
(
.clk(clk),
.rst(rst),
.bin_data(min_shi_seg_in), // bin data input,0-f
.seg_data(min_shi) // seven segments LED output
);
seg_decoder seg_h_ge_wei
(
.clk(clk),
.rst(rst),
.bin_data(h_ge_seg_in), // bin data input,0-f
.seg_data(h_ge) // seven segments LED output
);
seg_decoder seg_h_shi_wei
(
.clk(clk),
.rst(rst),
.bin_data(h_shi_seg_in), // bin data input,0-f
.seg_data(h_shi) // seven segments LED output
);
endmodule