本文使用FPGA配合按键和数码管外设实现动态数码管显示。
实验的要求为:
四个数码管显示不同的数字,按键K1 控制第一个数码管,按一下数字加1,从0 到9,按键K2 控制第二个数码管,按一下数字加1,从0 到9,按键K3控制第三个数码管,按键K4 控制第四个数码管。
数码管是一种半导体发光器件,其基本单元是发光二极管。能显示4个数码管叫四位数码管。数码管按段数分为七段数码管和八段数码管,八段数码管比七段数码管多一个发光二极管单元(多一个小数点显示);按发光二极管单元连接方式分为共阳极数码管和共阴极数码管。共阳数码管是指将所有发光二极管的阳极接到一起形成公共阳极(COM)的数码管。共阳数码管在应用时应将公共极COM接到+5V,当某一字段发光二极管的阴极为低电平时,相应字段就点亮。当某一字段的阴极为高电平时,相应字段就不亮。共阴数码管是指将所有发光二极管的阴极接到一起形成公共阴极(COM)的数码管。共阴数码管在应用时应将公共极COM 接到地线GND 上,当某一字段发光二极管的阳极为高电平时,相应字段就点亮。当某一字段的阳极为低电平时,相应字段就不亮。
每周一练】小眼睛FPGA1K开发板硬件平台中对数码管威廉希尔官方网站 的描述中,可以知道开发板上的数码管为共阳极接法。要点亮数码管中中表示数字的一部分,控制引脚设置为低电平即可。
数码管的控制引脚分为用于选择某个位可以被控制未选引脚和用于控制被选择的数字位显示的段选引脚。想控制数码中某个位显示的数字时,首先使能其位选引脚,然后控制段选引脚控制其显示的数字。基于上述数码管控制原理,可以设计数码管的控制模块如下。
`timescale 1ns / 1ps
`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
由于硬件连接上控制引脚与四位数码管都是连接的,同时控制四个位显示不同的数字是无法实现,我们可以通过刷新的方式造成视觉上同时显示了不同的数值。
人眼对于75Hz以上的灯光是没有闪烁感的,频率越高,对人眼的影响越小,同时LED灯达到要求的亮度也是有要求,所以实验中我们取刷新率位100KHz。开发板上的时钟为50MHz,所以我们需要设计一个时钟分频模块用于提供100KHz的时钟。模块设计如下:
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:Meyesemi
// Engineer: Will
//
// Create Date: 2022-08-12 20:31
// Design Name:
// Module Name:
// Project Name:
// Target Devices: Pango
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 1.0 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
`define UD #1
module div_clk
(
input clk,//50M
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
结合每周一练】盘古1K开发板 练习二:按键控制LED灯实验设计的按键消抖和计数模块。可以实现实验要求的功能。顶层模块的设计如下
`timescale 1ns / 1ps
`define UD #1
module top_seq
(
input clk,//40MHZ 25ns
input [3:0]button,
output reg [3:0]dig,
output reg [7:0]smg
);
/*===================================================
按键消抖
===================================================*/
wire [3:0]key;
btn_deb
#(
.BT_WIDTH(4'd4)
)
u_btn_deb
(
.clk(clk),
.btn_in(button),
.btn_out(key)
);
/*===================================================
4个按键的计数
===================================================*/
wire [3:0] key0_cnt;
key_cnt key1
(
.clk(clk),
.key(key[0]),
.key_times(key0_cnt)
);
wire [3:0] key1_cnt;
key_cnt key2
(
.clk(clk),
.key(key[1]),
.key_times(key1_cnt)
);
wire [3:0] key2_cnt;
key_cnt key3
(
.clk(clk),
.key(key[2]),
.key_times(key2_cnt)
);
wire [3:0] key3_cnt;
key_cnt key4
(
.clk(clk),
.key(key[3]),
.key_times(key3_cnt)
);
/*===================================================
时钟分频
===================================================*/
wire clk_100khz;
div_clk div_clk
(
.clk (clk),
.clk_100khz (clk_100khz)
);
/*===================================================
数码管显示
===================================================*/
reg [1:0]sel=0;
wire [3:0]dig0;
wire [7:0]smg0;
always @(posedge clk_100khz)
begin
sel <= `UD sel+1'b1;
end
seq_control seq_control_0
(
.sel(2'd3),
.key(key0_cnt),
.dig(dig0),
.smg(smg0)
);
wire [3:0]dig1;
wire [7:0]smg1;
seq_control seq_control_1
(
.sel(2'd2),
.key(key1_cnt),
.dig(dig1),
.smg(smg1)
);
wire [3:0]dig2;
wire [7:0]smg2;
seq_control seq_control_2
(
.sel(2'd1),
.key(key2_cnt),
.dig(dig2),
.smg(smg2)
);
wire [3:0]dig3;
wire [7:0]smg3;
seq_control seq_control_3
(
.sel(2'd0),
.key(key3_cnt),
.dig(dig3),
.smg(smg3)
);
always @(posedge clk_100khz)
begin
if(sel==2'b00)
dig <= `UD dig0;
else if(sel==2'b01)
dig <= `UD dig1;
else if(sel==2'b10)
dig <= `UD dig2;
else if(sel==2'b11)
dig <= `UD dig3;
end
always @(posedge clk_100khz)
begin
if(sel==2'b00)
smg <= `UD smg0;
else if(sel==2'b01)
smg <= `UD smg1;
else if(sel==2'b10)
smg <= `UD smg2;
else if(sel==2'b11)
smg <= `UD smg3;
end
endmodule
添加引脚约束如下
编译综合烧录后,实验的显示效果如下
更多回帖