FPGA学习—数码管显示

FPGA学习——数码管显示



结构框架

数码管动态显示采用了人眼暂存的原理,即时分复用,在数码管实现动态显示。
整个实验设计流程框架如下图所示:
在这里插入图片描述


一、硬件设计

开发板采用共阳极数码管,即低电平点亮。
在这里插入图片描述

二、verilog编写

1.计数器

本实验准备设计一个定时器,6为数码管显示24小时制的时间,所以编写一个计数模块。

module counter_10
#(
  parameter	COUNT = 4'd9
	)
(
  input             clk,
  input             rst_n,
  input             en,
  input             clr,
  
  output  reg[3:0]  count,
  output  reg       t
  );
  
always@(posedge clk or negedge rst_n)
begin 
 if(rst_n == 1'b0)
  begin
	count <= 4'd0;
	t <= 1'b0;
  end
 else if(clr == 1'b1)
  begin
	count <= 4'd0;
	t <= 1'b0;
  end 
 else if(en== 1'b1)
  if(count == COUNT)
    begin
	  count <= 4'd0;
	  t <= 1'b1;
    end 
  else
	begin
	  count <= count + 4'd1;
	  t <= 1'b0;
    end
 else
	begin
	 count <= count;
	 t <= 1'b0;
  end 
		
end
	
endmodule
	

改变变量COUNT的数值,可实现不同模的计数器。

2.译码模块

module seg_decoder
(
	input		[3:0]	bin_data,
	output	reg	[7:0]	seg_data
);

always@(*)
begin
	case(bin_data)
		4'd0:seg_data <= 8'b1100_0000;
		4'd1:seg_data <= 8'b1111_1001;
		4'd2:seg_data <= 8'b1010_0100;
		4'd3:seg_data <= 8'b1011_0000;
		4'd4:seg_data <= 8'b1001_1001;
		4'd5:seg_data <= 8'b1001_0010;
		4'd6:seg_data <= 8'b1000_0010;
		4'd7:seg_data <= 8'b1111_1000;
		4'd8:seg_data <= 8'b1000_0000;
		4'd9:seg_data <= 8'b1001_0000;
		4'ha:seg_data <= 8'b1000_1000;
		4'hb:seg_data <= 8'b1000_0011;
		4'hc:seg_data <= 8'b1100_0110;
		4'hd:seg_data <= 8'b1010_0001;
		4'he:seg_data <= 8'b1000_0110;
		4'hf:seg_data <= 8'b1000_1110;
		default:seg_data <= 8'b1111_1111;
	endcase
end

endmodule

将计数器的十进制数按照译码准则转换为8位二进制,控制数码管的段选位。

3.数码管扫描模块

module seg_scan
#(
	parameter SCAN = 13'd4999,
	parameter SEG  = 3'd5)
(
	input				clk,
	input				rst_n,
	input		[7:0]	seg_data0,
	input		[7:0]	seg_data1,
	input		[7:0]	seg_data2,
	input		[7:0]	seg_data3,
	input		[7:0]	seg_data4,
	input		[7:0]	seg_data5,
	
	output	reg[5:0]	seg_sel,
	output	reg[7:0]	seg_data
	);
reg [12:0]	timer;
reg [2:0]	seg;
	
always@(posedge clk or negedge rst_n)
if(rst_n == 1'b0)
	timer <= 13'd0;
else if(timer == SCAN)
	timer <= 13'd0;
else
	timer <= timer + 13'd1;
	
always@(posedge clk or negedge rst_n)
if(rst_n == 1'b0)
	seg <= 3'd0;
else if(seg == SEG && timer == SCAN)
	seg <= 3'd0;
else if(timer == SCAN)
	seg <= seg + 3'd1;
	
always@(posedge clk or negedge rst_n)
if(rst_n == 1'b0)
	begin
		seg_sel <= 6'b0000_00;
		seg_data <= 8'b0000_0000;
	end
else 
	case(seg)
		3'd0:
			begin 
				seg_sel <= 6'b0111_11;
				seg_data <= seg_data0;
			end
		3'd1:
			begin 
				seg_sel <= 6'b1011_11;
				seg_data <= seg_data1;
			end
		3'd2:
			begin 
				seg_sel <= 6'b1101_11;
				seg_data <= seg_data2;
			end
		3'd3:
			begin 
				seg_sel <= 6'b1110_11;
				seg_data <= seg_data3;
			end
		3'd4:
			begin 
				seg_sel <= 6'b1111_01;
				seg_data <= seg_data4;
			end
		3'd5:
			begin 
				seg_sel <= 6'b1111_10;
				seg_data <= seg_data5;
			end
		default:
			begin
				seg_sel <= 6'b1111_11;
				seg_data <= 8'b1111_1111;
			end
	endcase
	
endmodule
		

扫描时间间隔设为0.01ms,人眼无法捕捉0.01ms的变化,进而实现6位数码管”同时“显示。

4.顶层模块

module seg_test
#(
	parameter	SCAN = 13'd4999,
	parameter   SEG = 3'd5,
	parameter	BAUD = 32'd49999999
)
(
	input				clk,
	input				rst_n,
	
	output	[5:0]	seg_sel,
	output	[7:0]	seg_data
);

wire 		t0,t1,t2,t3,t4,t5;
wire[3:0]	count0,count1,count2,count3,count4,count5;
wire[7:0]	seg_data0,seg_data1,seg_data2,seg_data3,seg_data4,seg_data5;

reg t;
reg[25:0]	timer;

always@(posedge clk or negedge rst_n)
	if(rst_n == 1'b0)
	begin
		timer <= 26'd0;
		t <= 1'b0;
	end
	else if(timer == BAUD)
	begin
		timer <= 26'd0;
		t <= 1'b1;
	end
	else
	begin
		timer <= timer + 1'd1;
		t <= 1'b0;
	end			

counter_10
#(
  .COUNT(9)
	)counter_10_0
(
  .clk		(clk),
  .rst_n	(rst_n),
  .en		(t),
  .clr		(1'b0),
            
  .count	(count0),
  .t		(t0)
  );
  
counter_10
#(
  .COUNT(5)
	)counter_10_1
(
  .clk		(clk),
  .rst_n	(rst_n),
  .en		(t0),
  .clr		(1'b0),
            
  .count	(count1),
  .t		(t1)
  );
  
counter_10
#(
  .COUNT(9)
	)counter_10_2
(
  .clk		(clk),
  .rst_n	(rst_n),
  .en		(t1),
  .clr		(1'b0),
            
  .count	(count2),
  .t		(t2)
  );
  
 counter_10
#(
  .COUNT(5)
	)counter_10_3
(
  .clk		(clk),
  .rst_n	(rst_n),
  .en		(t2),
  .clr		(1'b0),
            
  .count	(count3),
  .t		(t3)
  );
  
 counter_10
#(
  .COUNT(3)
	)counter_10_4
(
  .clk		(clk),
  .rst_n	(rst_n),
  .en		(t3),
  .clr		(1'b0),
            
  .count	(count4),
  .t		(t4)
  );
  
   counter_10
#(
  .COUNT(2)
	)counter_10_5
(
  .clk		(clk),
  .rst_n	(rst_n),
  .en		(t4),
  .clr		(1'b0),
            
  .count	(count5),
  .t		(t5)
  );
  
seg_decoder	seg_decoder_0
(
	.bin_data(count0),
	.seg_data(seg_data0)
);
seg_decoder	seg_decoder_1
(
	.bin_data(count1),
	.seg_data(seg_data1)
);
seg_decoder	seg_decoder_2
(
	.bin_data(count2),
	.seg_data(seg_data2)
);
seg_decoder	seg_decoder_3
(
	.bin_data(count3),
	.seg_data(seg_data3)
);
seg_decoder	seg_decoder_4
(
	.bin_data(count4),
	.seg_data(seg_data4)
);
seg_decoder	seg_decoder_5
(
	.bin_data(count5),
	.seg_data(seg_data5)
);

seg_scan
#(
	.SCAN(SCAN),
	.SEG (SEG)
)seg_scan
(
	.clk		(clk),
	.rst_n		(rst_n),
	.seg_data0	(seg_data0),
	.seg_data1	(seg_data1),
	.seg_data2	(seg_data2),
	.seg_data3	(seg_data3),
	.seg_data4	(seg_data4),
	.seg_data5	(seg_data5),
	
	.seg_sel	(seg_sel),
	.seg_data	(seg_data)
	);
	
endmodule

实验结果

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值