FPGA实验 -- 数码管显示

静态显示部分

使用八段数码管,具体如下图所示,这里使用共阳极数码管。

假设需要使用六位八段数码管

为了节省IO口资源这里使用74HC595芯片,具体如下所示:

 MR端口有效时对数据进行清零,通常接VCC保持高电平。DS端口将串行数据传入。SHCP将穿行数据移位放入移位寄存器中,按脉冲操作。如果串行数据一次传入的数据超过8为,会将前几位多出来的数据放入Q7S端口中存入下一级595芯片,与下一个595芯片的DS端口相连接。STCP端口在上升沿时会将移位寄存器中的数据存入存储器中,当OE有效时,数据进行输出。

74HC595也可以进行级联来满足更多端口的需要,对应8个位选和6个段选14个IO口这里使用两个595芯片进行级联,如下所示:

 实验目标:

从全0到全F的循环显示,每个数字显示0.5s

 分模块设计

 

系统模块总体示意图:

  

  第一部分

module seg_static
#(parameter CNT_MAX = 25'd24_999_999)
(
	input wire sys_clk,
	input wire sys_res,
	
	output reg [5:0] sel,
	output reg [7:0] seg
);

reg [24:0] cnt;
reg [3:0] data;
reg cnt_flag;

always@(posedge sys_clk or negedge sys_res)
	if(sys_res == 1'b0)
		cnt <= 25'd0;
	else if(cnt == CNT_MAX)
		cnt <= 25'd0;
	else
		cnt <= cnt + 1'b1;

always@(posedge sys_clk or negedge sys_res)  //这里的flag信号作用与cnt_MAX作用重复可以不加
	if(sys_res == 1'b0)
		data <= 4'd0;
	else if((cnt_flag == 1'b1)&&(data == 4'd15))
		data <= 4'd0;
	else if(cnt == CNT_MAX)
		data <= data + 1'b1;
	else
		data <= data;
		
always@(posedge sys_clk or negedge sys_res)
	if(sys_res == 1'b0)
		cnt_flag <= 1'b0;
	else if(cnt == CNT_MAX - 1'b1)
		cnt_flag <= 1'b1;
	else 
		cnt_flag <= 1'b0;
		
always@(posedge sys_clk or negedge sys_res)
	if(sys_res == 1'b0)
		sel <= 6'd0;
	else 
		sel <= 6'b111_111;

always@(posedge sys_clk or negedge sys_res)
	if(sys_res == 1'b0)
		seg <= 8'hc0;
	else case(data)
		4'd0:seg <= 8'hc0;
		4'd1:seg <= 8'hf9;
		4'd2:seg <= 8'ha4;
		4'd3:seg <= 8'hb0;
		4'd4:seg <= 8'h99;
		4'd5:seg <= 8'h92;
		4'd6:seg <= 8'h82;
		4'd7:seg <= 8'hf8;
		4'd8:seg <= 8'h80;
		4'd9:seg <= 8'h90;
		4'd10:seg <= 8'h88;
		4'd11:seg <= 8'h83;
		4'd12:seg <= 8'hc6;
		4'd13:seg <= 8'ha1;
		4'd14:seg <= 8'h86;
		4'd15:seg <= 8'h8e;
		default:seg <= 8'hff; //不满足时不显示
	endcase
		
endmodule

 

module seg_595_static
(
	input wire sys_clk,
	input wire sys_res,
	
	output wire ds,
	output wire shcp,
	output wire stcp,
	output wire oe
	
);

wire [5:0] sel;
wire [7:0] seg;

seg_static
#(.CNT_MAX(25'd24))
seg_static_1
(
	.sys_clk(sys_clk),
	.sys_res(sys_res),
	
	.sel(sel),
	.seg(seg)
);

endmodule
`timescale 1ns/1ns
module tb_seg_static();

reg sys_clk;
reg sys_res;

wire [5:0] sel;
wire [7:0] seg;

initial
	begin
		sys_clk = 1'b1;
		sys_res <= 1'b0;
		#20
		sys_res <= 1'b1;
		
	end
	
always #10 sys_clk = ~sys_clk;

seg_static
#(.CNT_MAX(25'd24))
seg_static_1
(
	.sys_clk(sys_clk),
	.sys_res(sys_res),
	
	.sel(sel),
	.seg(seg)
);

endmodule

第二部分

注意拼接data数据时数码管位选信号的次序反过来,这是由于595芯片串行转并行的特性决定的,设置595需要4个时钟周期来完成一个完整数据的传输过程,利用四分频可以更好的铺垫输出四个信号的高低电平时刻

module hc595_ctr
(
	input wire sys_clk,
	input wire sys_res,
	input wire [5:0] sel,
	input wire [7:0] seg,
	
	output reg ds,
	output reg shcp,
	output reg stcp,
	output wire oe
	
);

wire [13:0] data;
reg [1:0] cnt;
reg [3:0] cnt_bit;

assign data = {sel,seg};

always@(posedge sys_clk or negedge sys_res)
	if(sys_res == 1'b0)
		cnt <= 2'd0;
	else if(cnt == 2'd3)
		cnt <= 2'd0;
	else
		cnt <= cnt + 1'b1;

always@(posedge sys_clk or negedge sys_res)
	if(sys_res == 1'b0)
		cnt_bit <= 4'd0;
	else if((cnt == 2'd3)&&(cnt_bit == 4'd13))
		cnt_bit <= 4'd0;
	else if(cnt == 2'd3)
		cnt_bit <= cnt_bit + 1'b1;
	else
		cnt_bit <= cnt_bit;
		
always@(posedge sys_clk or negedge sys_res)
	if(sys_res == 1'b0)
		ds <= 1'b0;
	else if(cnt == 2'd0)
		ds <= data[cnt_bit];
	else
		ds <= ds;

always@(posedge sys_clk or negedge sys_res)
	if(sys_res == 1'b0)
		shcp <= 1'b0;
	else if(cnt == 2'd2)
		shcp <= 1'b1;
	else if(cnt == 2'd0)
		shcp <= 1'b0;
	else
		shcp <= shcp;

always@(posedge sys_clk or negedge sys_res)
	if(sys_res == 1'b0)
		stcp <= 1'b0;
	else if((cnt == 2'd0)&&(cnt_bit == 4'b0))
		stcp <= 1'b1;
	else if((cnt == 2'd2)&&(cnt_bit == 4'b0))
		stcp <= 1'b0;
	else
		stcp <= stcp;

		
assign oe = 1'b0;

endmodule
module seg_595_static
(
	input wire sys_clk,
	input wire sys_res,
	
	output wire ds,
	output wire shcp,
	output wire stcp,
	output wire oe
	
);

wire [5:0] sel;
wire [7:0] seg;

seg_static
#(.CNT_MAX(25'd24))
seg_static_1
(
	.sys_clk(sys_clk),
	.sys_res(sys_res),
	
	.sel(sel),
	.seg(seg)
);
 
hc595_ctr hc595_ctr_1
(
	.sys_clk(sys_clk),
	.sys_res(sys_res),
	.sel(sel),
	.seg(seg),
	
	.ds(ds),
	.shcp(shcp),
	.stcp(stcp),
	.oe(oe)
	
);

endmodule
module seg_595_static
(
	input wire sys_clk,
	input wire sys_res,
	
	output wire ds,
	output wire shcp,
	output wire stcp,
	output wire oe
	
);

wire [5:0] sel;
wire [7:0] seg;

seg_static
#(.CNT_MAX(25'd24))
seg_static_1
(
	.sys_clk(sys_clk),
	.sys_res(sys_res),
	
	.sel(sel),
	.seg(seg)
);
 
hc595_ctr hc595_ctr_1
(
	.sys_clk(sys_clk),
	.sys_res(sys_res),
	.sel(sel),
	.seg(seg),
	
	.ds(ds),
	.shcp(shcp),
	.stcp(stcp),
	.oe(oe)
	
);

endmodule

  • 1
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值