基于FPGA的数码管动态扫描显示(含代码)

数码管的显示有静态显示和动态扫描显示。一个数码管通常有8个段码,当要控制数码管的数量在两个及以上时,动态扫描无疑是一个最好的选择,可以大量节约IO资源。

静态显示很好理解,8个段码拼成了数字8.,当我们想要显示对应的数字时只需要对应的段码显示就可以了;那么,什么是动态扫描?动态扫描就是利用肉眼视觉暂留现象,通过快速切换数码管显示位码达到肉眼无法分辨闪烁的效果。

设计思路:

需要动态显示6位数码管,然后需要一个相对快的时钟去切换数码管的位码,我采用的是1Khz频率,系统时钟50Mhz,低电平复位。有的人喜欢给case语句的条件写一个时钟,让位码在这个时钟下进行切换,但是我并不喜欢这样,这样写如果时钟计数值不是数码管位数的整数倍时,数码管很容易出现有一个比较淡的重影,严重的话直接影响数码管的显示效果,我更习惯于用C语言的思路,或者说是状态机的想法进行位码的赋值。

FPGA Verilog 动态扫描部分代码如下:

`timescale 1ns / 1ps
module digital(
	input            clk  ,
	input            rstn ,
	input      [3:0] data1,
	input      [3:0] data2,
	input      [3:0] data3,
	input      [3:0] data4,
	input      [3:0] data5,
	input      [3:0] data6, 
	output reg [7:0] seg  ,
	output reg [5:0] sel
	);

//digital digital_u(
//	.clk  (clk  ),
//	.rstn (rstn ),
//	.data1(data1),
//	.data2(data2),
//	.data3(data3),
//	.data4(data4),
//	.data5(data5),
//	.data6(data6), 
//	.seg  (seg  ),
//	.sel  (sel  )
//);

	reg [15:0]cn1;
	reg clk1k;
	always@(posedge clk or negedge rstn)
		begin
			if(!rstn)
				begin
					cn1<=0;
					clk1k<=0;
				end
			else if(cn1>=24999)
				begin
					clk1k<=!clk1k;
					cn1<=0;
				end
			else cn1<=cn1+1;
		end
	reg [3:0] tub;
	reg [2:0] con;
	reg [5:0] sel_reg;
	always@(posedge clk1k or negedge rstn)
		begin
			if(!rstn)
				begin
					tub      <= 0;
					con      <= 0;
					sel_reg  <= 0;
					sel      <= 6'b000000;
				end
			else begin
				case(con)//浪费seg一个时钟
					0:begin tub<=data1;sel_reg<=6'b011111;con<=1;end
					1:begin tub<=data2;sel_reg<=6'b101111;con<=2;end
					2:begin tub<=data3;sel_reg<=6'b110111;con<=3;end
					3:begin tub<=data4;sel_reg<=6'b111011;con<=4;end
					4:begin tub<=data5;sel_reg<=6'b111101;con<=5;end
					5:begin tub<=data6;sel_reg<=6'b111110;con<=0;end
					default:con<=0;
				endcase
				sel <= sel_reg;//时钟对齐
			end
		end
	always@(posedge clk1k or negedge rstn)
		if(!rstn)
			seg<=8'b1100_0000;
		else	
			case(tub)
				0:seg<=8'b1100_0000;
				1:seg<=8'b1111_1001;
				2:seg<=8'b1010_0100;
				3:seg<=8'b1011_0000;
				4:seg<=8'b1001_1001;
				5:seg<=8'b1001_0010;
				6:seg<=8'b1000_0010;
				7:seg<=8'b1111_1000;
				8:seg<=8'b1000_0000;
				9:seg<=8'b1001_0000;
	//			10:seg<=8'b1000_1000;
	//			11:seg<=8'b1000_0011;
	//			12:seg<=8'b1100_0110;
	//			13:seg<=8'b1010_0001;
	//			14:seg<=8'b1000_0110;
	//			15:seg<=8'b1000_1110;
				default:seg<=8'b1100_0000;
			endcase

endmodule

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

绯红姜梦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值