一、数码管驱动原理
共阴极与共阳极:公共端是接高电平还是低电平 左:共阴 右:共阳
段码:决定显示的内容
位选:选择哪一个数码管
动态扫描显示即轮流向各位数码管送出字形码和相应的
位选,利用发光管的余辉和人眼视觉暂留作用,使人的感觉好像各位数码管同
时都在显示。
如果使用 1ms 刷新时间的话由于数码管的余辉效应以及人的视觉暂留
这样就会出现数码管 0 的 LED0、数码管 1 的 LED1 以及数码管 2 的 LED2 “同
时”亮,并不会有闪烁感。
二、FPGA设计
1.1khz扫描时钟
2. 动态扫描(8位寄存器or移位寄存器)位选
3.sel→【31:0】disp_data→[3:0]data_temp→seg段选
设计关键:
计数器
LUT→case语句
module hex8(
Clk,
Reset_n,
en,
disp_data,
sel,
seg
);
input Clk; //50M
input Reset_n;
input en; //数码管显示使能,1使能,0关闭
input [31:0]disp_data;
output [7:0] sel;//数码管位选(选择当前要显示的数码管)
output reg [6:0] seg;//数码管段选(当前要显示的内容)
reg [14:0]divider_cnt;//25000-1
reg clk_1K;
reg [7:0]sel_r;
reg [3:0]data_tmp;//数据缓存
// 分频计数器计数模块
always@(posedge Clk or negedge Reset_n)
if(!Reset_n)
divider_cnt <= 15'd0;
else if(!en)
divider_cnt <= 15'd0;
else if(divider_cnt == 24999)
divider_cnt <= 15'd0;
else
divider_cnt <= divider_cnt + 1'b1;
//1K扫描时钟生成模块
always@(posedge Clk or negedge Reset_n)
if(!Reset_n)
clk_1K <= 1'b0;
else if(divider_cnt == 24999)
clk_1K <= ~clk_1K;
else
clk_1K <= clk_1K;
//8位循环移位寄存器
always@(posedge clk_1K or negedge Reset_n)
if(!Reset_n)
sel_r <= 8'b0000_0001;
else if(sel_r == 8'b1000_0000)
sel_r <= 8'b0000_0001;
else
sel_r <= sel_r << 1;
always@(*)
case(sel_r)
8'b0000_0001:data_tmp = disp_data[3:0];
8'b0000_0010:data_tmp = disp_data[7:4];
8'b0000_0100:data_tmp = disp_data[11:8];
8'b0000_1000:data_tmp = disp_data[15:12];
8'b0001_0000:data_tmp = disp_data[19:16];
8'b0010_0000:data_tmp = disp_data[23:20];
8'b0100_0000:data_tmp = disp_data[27:24];
8'b1000_0000:data_tmp = disp_data[31:28];
default:data_tmp = 4'b0000;
endcase
always@(*)
case(data_tmp)
4'h0:seg = 7'b1000000;
4'h1:seg = 7'b1111001;
4'h2:seg = 7'b0100100;
4'h3:seg = 7'b0110000;
4'h4:seg = 7'b0011001;
4'h5:seg = 7'b0010010;
4'h6:seg = 7'b0000010;
4'h7:seg = 7'b1111000;
4'h8:seg = 7'b0000000;
4'h9:seg = 7'b0010000;
4'ha:seg = 7'b0001000;
4'hb:seg = 7'b0000011;
4'hc:seg = 7'b1000110;
4'hd:seg = 7'b0100001;
4'he:seg = 7'b0000110;
4'hf:seg = 7'b0001110;
endcase
assign sel = (en)?sel_r:8'b0000_0000;
endmodule
三、数码管驱动(74HC595串转并)
Q0~Q7 8个数字输出(二进制)
Vcc 接电源正极
GND 接电源负极
DS 高电频输入1,低电平输入0
/OE 低电平74HC595有效使用(接地GND就好了)
/MR 低电平复位(如果不需要复位直接接电源就行)
SH_CP 高电平触发时,DS的数被存入,一次存一个
ST_CP 高电平触发时,DS存入的所有二进制数被输出
Q7' 级联使用
module hc595_driver(
Clk,
Reset_n,
data,
s_en,
sh_cp,
st_cp,
ds
);
input Clk;
input Reset_n;
input [15:0]data;
input s_en;
output reg sh_cp;
output reg st_cp;
output reg ds;
parameter CNT_MAX = 2;
reg [15:0]r_data;
always@(posedge Clk)
if(s_en)
r_data <= data;
reg [7:0]divider_cnt;//分频计数器;
always@(posedge Clk or negedge Reset_n)
if(!Reset_n)
divider_cnt <= 0;
else if(divider_cnt == CNT_MAX - 1'b1)
divider_cnt <= 0;
else
divider_cnt <= divider_cnt + 1'b1;
wire sck_plus;
assign sck_plus = (divider_cnt == CNT_MAX - 1'b1);
reg [5:0]SHCP_EDGE_CNT;
always@(posedge Clk or negedge Reset_n)
if(!Reset_n)
SHCP_EDGE_CNT <= 0;
else if(sck_plus)begin
if(SHCP_EDGE_CNT == 6'd32)
SHCP_EDGE_CNT <= 0;
else
SHCP_EDGE_CNT <= SHCP_EDGE_CNT + 1'b1;
end
else
SHCP_EDGE_CNT <= SHCP_EDGE_CNT;
always@(posedge Clk or negedge Reset_n)
if(!Reset_n)begin
st_cp <= 1'b0;
ds <= 1'b0;
sh_cp <= 1'd0;
end
else begin
case(SHCP_EDGE_CNT)
0: begin sh_cp <= 0; st_cp <= 1'd0;ds <= r_data[15];end
1: begin sh_cp <= 1; st_cp <= 1'd0;end
2: begin sh_cp <= 0; ds <= r_data[14];end
3: begin sh_cp <= 1; end
4: begin sh_cp <= 0; ds <= r_data[13];end
5: begin sh_cp <= 1; end
6: begin sh_cp <= 0; ds <= r_data[12];end
7: begin sh_cp <= 1; end
8: begin sh_cp <= 0; ds <= r_data[11];end
9: begin sh_cp <= 1; end
10: begin sh_cp <= 0; ds <= r_data[10];end
11: begin sh_cp <= 1; end
12: begin sh_cp <= 0; ds <= r_data[9];end
13: begin sh_cp <= 1; end
14: begin sh_cp <= 0; ds <= r_data[8];end
15: begin sh_cp <= 1; end
16: begin sh_cp <= 0; ds <= r_data[7];end
17: begin sh_cp <= 1; end
18: begin sh_cp <= 0; ds <= r_data[6];end
19: begin sh_cp <= 1; end
20: begin sh_cp <= 0; ds <= r_data[5];end
21: begin sh_cp <= 1; end
22: begin sh_cp <= 0; ds <= r_data[4];end
23: begin sh_cp <= 1; end
24: begin sh_cp <= 0; ds <= r_data[3];end
25: begin sh_cp <= 1; end
26: begin sh_cp <= 0; ds <= r_data[2];end
27: begin sh_cp <= 1; end
28: begin sh_cp <= 0; ds <= r_data[1];end
29: begin sh_cp <= 1; end
30: begin sh_cp <= 0; ds <= r_data[0];end
31: begin sh_cp <= 1; end
32: st_cp <= 1'd1;
default:
begin
st_cp <= 1'b0;
ds <= 1'b0;
sh_cp <= 1'd0;
end
endcase
end
endmodule
四。最后顶层设计(top)
此处略去