FPGA使用两个HC595驱动8位数码管
本文章给出使用FPGA3根线来驱动8位数码管的示例代码,输入为disp_data
,共7*8=56位,输出输入如图所示。
硬件方面参数
- 该程序只能控制数码管的7位,如有小数点位则控制不了,如有需要请自行修改。
- 最低7位是最右边的那个数码管(这个需要根据你自己的板子硬件连接来看)。
- 0是亮,1是灭(共阳极数码管是这样,共阴极则相反,如为共阴极则需要修改
HEX8
中对应的内容)。 - a是7位中的最低位。
程序
- 顶层程序
module HEX_top(
Clk,
Rst_n,
disp_data,
SH_CP,
ST_CP,
DS
);
input Clk; //50M
input Rst_n;
output SH_CP; //shift clock
output ST_CP; //latch data clock
output DS; //data
input disp_data;
wire [7:0] sel;//数码管位选(选择当前要显示的数码管)
wire [6:0] seg;//数码管段选(当前要显示的内容)
wire [55:0] disp_data;
HEX8 HEX8(
.Clk(Clk),
.Rst_n(Rst_n),
.En(1'b1),
.disp_data(disp_data),
.sel(sel),
.seg(seg)
);
HC595_Driver HC595_Driver(
.Clk(Clk),
.Rst_n(Rst_n),
.Data({1'b1,seg,sel}),
.S_EN(1'b1),
.SH_CP(SH_CP),
.ST_CP(ST_CP),
.DS(DS)
);
endmodule
- 8位7段数码管显示设计
module HEX8(
Clk,
Rst_n,
En,
disp_data,
sel,
seg
);
input Clk; //50M
input Rst_n;
input En; //数码管显示使能,1使能,0关闭
input [55:0]disp_data;
output [7:0] sel;//数码管位选(选择当前要显示的数码管)
output wire [6:0] seg;//数码管段选(当前要显示的内容)
reg [14:0]divider_cnt;//25000-1
reg clk_1K;
reg [7:0]sel_r;
reg [7:0]data_tmp;//数据缓存
// 分频计数器计数模块
always@(posedge Clk or negedge Rst_n)
if(!Rst_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 Rst_n)
if(!Rst_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 Rst_n)
if(!Rst_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[6:0];
8'b0000_0010:data_tmp = disp_data[13:7];
8'b0000_0100:data_tmp = disp_data[20:14];
8'b0000_1000:data_tmp = disp_data[27:21];
8'b0001_0000:data_tmp = disp_data[34:28];
8'b0010_0000:data_tmp = disp_data[41:35];
8'b0100_0000:data_tmp = disp_data[48:42];
8'b1000_0000:data_tmp = disp_data[55:49];
default:data_tmp = 7'b0000000;
endcase
assign seg = data_tmp;
assign sel = (En)?sel_r:8'b0000_0000;
endmodule
- 74HC595移位寄存器驱动设计
module HC595_Driver(
Clk,
Rst_n,
Data,
S_EN,
SH_CP,
ST_CP,
DS
);
parameter DATA_WIDTH = 16;
input Clk;
input Rst_n;
input [DATA_WIDTH-1 : 0] Data; //data to send
input S_EN; //send en
output reg SH_CP; //shift clock
output reg ST_CP; //latch data clock
output reg DS; //shift serial data
parameter CNT_MAX = 4;
reg [15:0] divider_cnt;//分频计数器
wire sck_pluse;
reg [4:0]SHCP_EDGE_CNT;//SH_CP EDGE counter
reg [15:0]r_data;
always@(posedge Clk or negedge Rst_n)
if(!Rst_n)
r_data <= 16'd0;
else if(S_EN)
r_data <= Data;
else
r_data <= r_data;
//clock divide
always@(posedge Clk or negedge Rst_n)
if(!Rst_n)
divider_cnt <= 16'd0;
else if(divider_cnt == CNT_MAX)
divider_cnt <= 16'd0;
else
divider_cnt <= divider_cnt + 1'b1;
assign sck_pluse = (divider_cnt == CNT_MAX);
always@(posedge Clk or negedge Rst_n)
if(!Rst_n)
SHCP_EDGE_CNT <= 5'd0;
else if(sck_pluse)begin
if(SHCP_EDGE_CNT == 5'd31)
SHCP_EDGE_CNT <= 5'd0;
else
SHCP_EDGE_CNT <= SHCP_EDGE_CNT + 1'd1;
end
else
SHCP_EDGE_CNT <= SHCP_EDGE_CNT;
always@(posedge Clk or negedge Rst_n)
if(!Rst_n)begin
SH_CP <= 1'b0;
ST_CP <= 1'b0;
DS <= 1'b0;
end
else begin
case(SHCP_EDGE_CNT)
5'd0:begin SH_CP <= 1'b0; ST_CP <= 1'b1; DS <= r_data[15]; end
5'd1:begin SH_CP <= 1'b1; ST_CP <= 1'b0;end
5'd2:begin SH_CP <= 1'b0; DS <= r_data[14];end
5'd3:begin SH_CP <= 1'b1; end
5'd4:begin SH_CP <= 1'b0; DS <= r_data[13];end
5'd5:begin SH_CP <= 1'b1; end
5'd6:begin SH_CP <= 1'b0; DS <= r_data[12];end
5'd7:begin SH_CP <= 1'b1; end
5'd8:begin SH_CP <= 1'b0; DS <= r_data[11];end
5'd9:begin SH_CP <= 1'b1; end
5'd10:begin SH_CP <= 1'b0; DS <= r_data[10];end
5'd11:begin SH_CP <= 1'b1; end
5'd12:begin SH_CP <= 1'b0; DS <= r_data[9];end
5'd13:begin SH_CP <= 1'b1; end
5'd14:begin SH_CP <= 1'b0; DS <= r_data[8];end
5'd15:begin SH_CP <= 1'b1; end
5'd16:begin SH_CP <= 1'b0; DS <= r_data[7];end
5'd17:begin SH_CP <= 1'b1; end
5'd18:begin SH_CP <= 1'b0; DS <= r_data[6];end
5'd19:begin SH_CP <= 1'b1; end
5'd20:begin SH_CP <= 1'b0; DS <= r_data[5];end
5'd21:begin SH_CP <= 1'b1; end
5'd22:begin SH_CP <= 1'b0; DS <= r_data[4];end
5'd23:begin SH_CP <= 1'b1; end
5'd24:begin SH_CP <= 1'b0; DS <= r_data[3];end
5'd25:begin SH_CP <= 1'b1; end
5'd26:begin SH_CP <= 1'b0; DS <= r_data[2];end
5'd27:begin SH_CP <= 1'b1; end
5'd28:begin SH_CP <= 1'b0; DS <= r_data[1];end
5'd29:begin SH_CP <= 1'b1; end
5'd30:begin SH_CP <= 1'b0; DS <= r_data[0];end
5'd31:begin SH_CP <= 1'b1; end
endcase
end
endmodule
代码来自于小梅哥的资料,进行了部分修改,使得整个程序可以更方便的被移植
标签:FPGA,Clk,HC595,数码管,Rst,input,CP,data From: https://www.cnblogs.com/hnu-hua/p/18089710