【 FPGA 】四位16进制的数码管动态显示设计

数码管的动态显示是对每个数码管采用分时复用的方式轮流点亮每个数码管,在同一时间只会点亮一个数码管。

分时复用的扫描显示利用了人眼的视觉暂留特性,如果公共端的控制信号刷新速度足够快,人眼就不会区分出LED的闪烁,认为4个数码管是同时点亮。

如下图:

D1、D2、D3、D4就是公共控制端口,也就是片选端,控制哪一个数码管被选中。

而abcdefg是段选,用来控制数码管的显示内容。

下面代码中的an就是片选端,以及控制信号一致的输出段码信号sseg。片选控制信号的刷新速度必须足够快才能避免闪烁感,但也不能太快,以免影响数码管的开关切换,最佳的工作频率为1000Hz左右。如果FPGA的时钟为50MHz,那么至少跑5*10^4个周期,也即50000个周期刷新一次才行,我们知道2^16=65536,2^15=32768。

所以,用16位2进制数来控制技术吧,技术满了刷新一次。

代码中采用的是18位2进制数,高2位控制片选,低16位计数满一次,进位一次,高两位的变化时00——01——10——11——00——...,分别选中数码管的其中之一,使用case语句即可完成这个功能。

下面代码中的hex0、hex1、hex2、hex3是输入信号,用来控制数码管显示的数字,dp_in用来控制小数点的亮灭。

Verilog HDL描述如下:

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date:    21:03:02 01/05/2019 
// Design Name: 
// Module Name:    scan_led_hex_disp 
// Project Name: 
// Target Devices: 
// Tool versions: 
// Description: 
//
// Dependencies: 
//
// Revision: 
// Revision 0.01 - File Created
// Additional Comments: 
//
//
module scan_led_hex_disp(
    input clk,
    input reset,
    input [3:0] hex0, //第一个数码管显示的数字
    input [3:0] hex1,
    input [3:0] hex2,
    input [3:0] hex3,
    input [3:0] dp_in, //小数点控制
    output reg [3:0] an,   //片选
    output reg [7:0] sseg  //段选
    );
	
	localparam N = 18; //使用低16位对50Mhz的时钟进行分频(50MHZ/2^16)
	reg [N-1:0] regN; //高两位作为控制信号,低16位为计数器,对时钟进行分频
	reg [3:0] hex_in; //段选控制信号
	reg dp; 
	
	always@(posedge clk, posedge reset)
	begin
		if(reset)
			regN <= 0;
		else
			regN <= regN + 1;
	end
	
	always@ *
	begin
		case(regN[N-1:N-2])
		2'b00:begin
			an = 4'b1110; //选中第1个数码管
			hex_in = hex0; //数码管显示的数字由hex_in控制,显示hex0输入的数字;
			dp = dp_in[0]; //控制该数码管的小数点的亮灭
		end
		2'b01:begin
			an = 4'b1101; //选中第二个数码管
			hex_in = hex1;
			dp = dp_in[1];
		end
		2'b10:begin
			an = 4'b1011;
			hex_in = hex2;
			dp = dp_in[2];
		end
		default:begin
			an = 4'b0111;
			hex_in = hex3;
			dp = dp_in[3];
		end
		
		endcase
	
	end

	always@ *
	begin
		case(hex_in)
			4'h0: sseg[6:0] = 7'b0000001; //共阳极数码管
			4'h1: sseg[6:0] = 7'b1001111;
			4'h2: sseg[6:0] = 7'b0010010;
			4'h3: sseg[6:0] = 7'b0000110;
			4'h4: sseg[6:0] = 7'b1001100;
			4'h5: sseg[6:0] = 7'b0100100;
			4'h6: sseg[6:0] = 7'b0100000;
			4'h7: sseg[6:0] = 7'b0001111;
			4'h8: sseg[6:0] = 7'b0000010;
			4'h9: sseg[6:0] = 7'b0000100;
			4'ha: sseg[6:0] = 7'b0001000;
			4'hb: sseg[6:0] = 7'b1100000;
			4'hc: sseg[6:0] = 7'b0110001;	
			4'hd: sseg[6:0] = 7'b1000010;
			4'he: sseg[6:0] = 7'b0110000;
			default: sseg[6:0] = 7'b0111000;
		endcase
		sseg[7] = dp;
	end
	
	

endmodule

 

 

共阳极数码管码表:

            4'h0: sseg[6:0] = 7'b0000001; //共阳极数码管
            4'h1: sseg[6:0] = 7'b1001111;
            4'h2: sseg[6:0] = 7'b0010010;
            4'h3: sseg[6:0] = 7'b0000110;
            4'h4: sseg[6:0] = 7'b1001100;
            4'h5: sseg[6:0] = 7'b0100100;
            4'h6: sseg[6:0] = 7'b0100000;
            4'h7: sseg[6:0] = 7'b0001111;
            4'h8: sseg[6:0] = 7'b0000010;
            4'h9: sseg[6:0] = 7'b0000100;
            4'ha: sseg[6:0] = 7'b0001000;
            4'hb: sseg[6:0] = 7'b1100000;
            4'hc: sseg[6:0] = 7'b0110001;    
            4'hd: sseg[6:0] = 7'b1000010;
            4'he: sseg[6:0] = 7'b0110000;

为了验证上述代码的实际效果,用下列代码调用上述代码来测试:

`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date:    14:05:56 01/06/2019 
// Design Name: 
// Module Name:    scan_led_hex_disp_test 
// Project Name: 
// Target Devices: 
// Tool versions: 
// Description: 
//
// Dependencies: 
//
// Revision: 
// Revision 0.01 - File Created
// Additional Comments: 
//
//
module scan_led_hex_disp_test(
    input clk,
	input [3:0] sw,
    output [3:0] an,
    output [7:0] sseg
    );
	wire [3:0] a,b;
	wire [7:0] sum;
	assign a = {2'b00,sw[1:0]};
	assign b = {2'b00,sw[3:2]};
	assign sum = {4'b0,a}+{4'b0,b};
	
	scan_led_hex_disp uu1(
	.clk(clk),.reset(1'b0),
	.hex3(sum[7:4]),.hex2(sum[3:0]),
	.hex1(b),.hex0(a),
	.dp_in(4'b1011),.an(an),.sseg(sseg)
	);
	


endmodule

功能是两个数码管用来显示数字a和b,而其他两个数码管显示a和b之和。

 

 

 

  • 14
    点赞
  • 100
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
1、设计要求基于小脚丫FPGA开发板和四位数码管实现数字时钟的设计,要求: 1)采用FPGA+按键+四位数码管实现数字时钟功能; 2)时间显示格式:XX:XX:XX (时:分:秒),采用24小时制; 3)四位数码管显示时分秒,可以通过按键控制选择显示时分界面还是分秒界面。 4)通过按键设定初始时间。 5)设置在整点12点时,通过蜂鸣器响示意整点报时。蜂鸣器响维持大概5S; 2、硬件连接FPGA的系统时钟来自于小脚丫FPGA开发板配置的24MHz时钟晶振,连接FPGA的C1引脚。 本设计用到五个个按键K1~K5,硬件设计如图1所示,五个按键分别连接到FPGA的B8、C8、A10、A11和A12引脚。 图1. 按键硬件设计设计用到一个蜂鸣器来示意整点报时,硬件设计如图1所示,蜂鸣器连接到FPGA的B2引脚。 图2. 蜂鸣器硬件设计设计用到四位数码管来显示时间,四位数码管用两个74HC595驱动,硬件设计如图1所示,74HC595的串行时钟SCK、并行时钟RCK和串行数据DIN分别连接到FPGA的N2、M1和K1引脚上。 图3. 数码管驱动74HC595硬件设计 3、工作原理1)使用计数器做分频处理,得到周期为1秒的脉冲信号; 2)使用三个8bit的BCD码表示时钟、分钟、秒钟的值,其中高4bit表示值的十位,低4bit表示值的个位; 3)正常运行时,每来一个1S脉冲信号个位加1,个位满10清零同时十位加1,当秒钟满60清零同时分钟个位加1,依次进行...直到23:59:59的下一刻全部清零; 4)按键K5,模式调节,设计共分4中模式(分秒显示、分秒调节、时分显示、时分调节),按动K5依次切换模式; 5)按键K2,时间调节,当数字时钟在时针调节、分针调节或秒针调节模式时,按动K2调节对应时间位; 6)在调时分和调分秒两个状态,可以通过K4和K2键分别左移右移要调整的位,要调整的位会通过对应位的闪烁来示意。通过K4和 K2左右移动选择好要调整的位以后,就可以通过K1和K3来增大或调小对应的位; 4、代码设计为了实现所需要的功能,我们将整个设计划分不同的模块,如图4所示。 图4. 数字时钟程序设计框架 4.1五位按键消抖模块 图5. 五位按键消抖模块 Ø输入:五位的按键电平信息输入 Ø输出:五位消抖后的脉冲输出 Ø功能:将按键按下一次的电平信号,经过消抖后变成一个维持一个时钟周期的脉冲信号; Ø原理: 图6. 按键抖动特性 FPGA过20ms检测按键是否按下,存储检测到的值,并且按位取反与前一个20ms检测的值相与,得到一个值,如果为1,则判断按键按下,否则则无按下。 图7. FPGA按键的理解示意图 4.2电子表显示控制模块。 图8. 电子表显示控制模块 Ø输入:五位的按键脉冲 Ø输出:十六位的BCD码输出,每四个代表一个十进制数; Ø原理:四位的位闪烁控制信号。某一位为一代表这位对应数码管的一位进行闪烁显示。(在调整状态下,会让当前调整的哪一位进行闪烁。正常显示状态下seg_flash_data全为零); Ø功能:主要就是一个状态机,通过检查输入的按键信息,进行显示状态切换,时间调整。四个状态分别为:显示分秒,调分秒,时分显示,调时分;当K5按键按下(key_pulse[4])时依次跳转,如图9所示。 图 9. 数字时钟状态控制设计 4.3数码管译码模块 图10. 数码管译码模块 Ø输入:四位的BCD码数据 Ø输出:八位的七段数码数据 Ø功能:一个case语句,将输入的四位BCD码转化为七段数码数据; Ø原理:数码管分为共阳极数码管和共阴极数码管。共阳数码管是指将所有发光二极管的阳极接到一起形成公共阳极(COM)的数码管,共阳极(COM)需接+5V才能使其工作。共阴数码管是指将所有发光二极管的阴极接到一起形成公共阴极(COM)的数码,共阴极(COM)需接GND才能使其工作。小脚丫拓展板上的数码管如下图所示: 图11. 数码管内部电路 共阴极数码管: 位选为低电平(即0)选中数码管;各段选为高电平(即接+5V时)选中各数码段;由0到f的编码为: 4.4四位数码管显示控制模块。 图12. 数码管显示控制模块 Ø输入:四个八位的七段数码管数据和位闪烁控制信号seg_flash_data. Ø输出:需要串行输出给74HC595的十六位数据; Ø功能:模块就是循环的将四位七段数码数据,组合一个十六位的输出数据; 4.5 74HC595驱动功能模块 图13. 74HC595驱动功能模块 Ø输入:十六位的位选段选数据。 1)duan_wei_data[13:0]分别对应: 2)[ X,X,H+,H-,DIG4,DIG3,DIG2,DIG1,DP,G,F,E,D,C,B,A] ; Ø输出:SPI接口输出,串行输出十六位位选段选信号; Ø

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

李锐博恩

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

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

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

打赏作者

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

抵扣说明:

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

余额充值