【每周一练】盘古1K开发板+动态数码管+小数点显示 - FPGA开发者技术社区 - 电子技术论坛 - 广受欢迎的专业电子论坛
分享 收藏 返回

zealsoft 关注 私信
[问答]

【每周一练】盘古1K开发板+动态数码管+小数点显示

感谢发烧友爱好者和小眼睛科技公司提供的FPGA测试机会。前面已经完成了测试一测试二,今天来完成第3个测试。这次的目的是实现四个数码管可以显示不同的数字,按键 K1 控制第一个数码管,按一下数字加 1,显示从 0 到 9,按键 K2 控制第二个数码管,按一下数字加 1,显示从 0 到 9,类似的,按键 K3 控制第三个数码管,按键 K4 控制第四个数码管。在《MES2KG开发板实验指导》中提供了相应的说明,这次我们还是参考相关介绍来介绍demo的工作原理,并做一些补充。

程序包括按键处理和数码管显示两个主要部分,下面分别介绍。

一、按键处理

键盘处理部分包括键盘防抖和键盘计数两个主要部分。键盘防抖在第2次测试已经介绍了,这里只讲计数部分。

计数的原理很简单,就是按键时如果当前值是9,就重置为0,否则当前值加一。

`define UD #1
module key_cnt
(
	input clk,//40M,25ns
	input rstn_key,
	input key,
	output reg [3:0]key_times
);

reg key_reg;
always @(posedge clk)
begin
	key_reg <= `UD key;
end 

always @(posedge clk )
begin
	if(key_reg&&~key&&key_times==4'd9)
		key_times <=`UD 4'd0;
	else if(key_reg&&~key)
		key_times <=`UD key_times + 1'b1;
end 

endmodule

二、数码管显示

MES2KG 底板的数码管使用共阳数码管。数码管基本单元是发光二极管。MES2KG 底板采用的是8段数码管,它比七段数码管多一个发光二极管单元(多一个小数点显示)。共阳数码管是指将所有发光二极管的阳极接到一起形成公共阳极(COM)的数码管。共阳数码管在应用时应将公共极 COM接到+5V或+3.3V,当某一字段发光二极管的阴极为低电平时,相应字段就点亮。当某一字段的阴极为高电平时,相应字段就不亮。

数码管显示出 0~9,代码如下,通过传递要显示的数值给到 key 上,可显示对应数值,sel 选择对应的数码管,如需 4 个如果要显示同样的字符,仅需将dig 的 4 位全部置 1,需要做好对应编码。

`define UD #1
module seq_control
(
	input [1:0]sel,
	input [3:0]key,
	output reg [3:0]dig,
	output reg [7:0]smg
);
/*===================================================
					位选择映射
===================================================*/
always @(*)
begin
	case(sel)
		2'd0:dig = 4'b0001;
		2'd1:dig = 4'b0010;
		2'd2:dig = 4'b0100;
		2'd3:dig = 4'b1000;
		default:dig = 4'b0000;
	endcase
end
//共阳极数码管,为0有效,即点亮
always @(*)
begin
	case(key)
		4'd0:smg = 8'b1000_0001;//"0" 
		4'd1:smg = 8'b1100_1111;//"1"  
		4'd2:smg = 8'b1001_0010;//"2"  
		4'd3:smg = 8'b1000_0110;//"3"  
		4'd4:smg = 8'b1100_1100;//"4"  
		4'd5:smg = 8'b1010_0100;//"5"  
		4'd6:smg = 8'b1010_0000;//"6"  
		4'd7:smg = 8'b1000_1111;//"7"  
		4'd8:smg = 8'b1000_0000;//"8"  
		4'd9:smg = 8'b1000_0100;//"9"  
		default:smg = 8'b1111_1111;		
	endcase
end 



endmodule

硬件连接上无法同一个时间点显示出不同的数值,所以可以通过刷新显示的方式造成视觉上同时显示了不同的数值,原理和电影显示的原理相同,采用大于 25Hz的刷新频率,闪烁基本消失。实验中取刷新率为 100KHz。

`define UD #1
module div_clk
(
	input clk,//40M
	output  clk_100khz//0.1M
);
reg [8:0]cnt;
always @(posedge clk)
begin
	if(cnt == 9'd399)
		cnt<= `UD 9'd0;
	else 
		cnt <= `UD cnt + 1'b1;
end  

reg flag=1'b0;
always @(posedge clk)
begin
	if(cnt == 9'd199)
		flag <= `UD 1'b1;
	else if(cnt == 9'd399)
		flag <= `UD 1'b0;
end 
assign clk_100khz = flag;

endmodule

三、增加小数点的显示

前面只用了7段数码管显示,小数点没有用上。我简单地修改了一下程序,可以让其中一个数码管显示小数点。代码如下:

//共阳极数码管,为0有效,即点亮
always @(*)
begin
	case(key)
		4'd0:smg = 8'b1000_0001;//"0" 
		4'd1:smg = 8'b1100_1111;//"1"  
		4'd2:smg = 8'b1001_0010;//"2"  
		4'd3:smg = 8'b1000_0110;//"3"  
		4'd4:smg = 8'b1100_1100;//"4"  
		4'd5:smg = 8'b1010_0100;//"5"  
		4'd6:smg = 8'b1010_0000;//"6"  
		4'd7:smg = 8'b1000_1111;//"7"  
		4'd8:smg = 8'b1000_0000;//"8"  
		4'd9:smg = 8'b1000_0100;//"9"  
		default:smg = 8'b1111_1111;		
	endcase

    // 如果sel变量为2'd2,则清除掉smg的最高位
    if (sel == 2'd2) begin
        smg[7] = 1'b0;
    end
end

然后重新编译、下载程序即可。

下面的视频就是最终实现的效果。

数码管显示

更多回帖

×
发帖