一、背景介绍
- 数码管是一种现代常用的数码显示器件,具有发光显示清晰,响应速度快,功耗低 、体积小、寿命长、易于控制等诸多优点,在数显仪器仪表、数字控制设备等方面得到广泛应用。
- 按发光二极管单元连接方式可分为共阳极数码管和共阴极数码管。共阳数码管是指将所有发光二极管的阳极接到一起形成公共阳极(COM)的数码管,共阳数码管在应用时应将公共极COM接到+5V,当某一字段发光二极管的阴极为低电平时,相应字段就点亮,当某一字段的阴极为高电平时,相应字段就不亮。共阴数码管是指将所有发光二极管的阴极接到一起形成公共阴极(COM)的数码管,共阴数码管在应用时应将公共极COM接到地线GND上,当某一字段发光二极管的阳极为高电平时,相应字段就点亮,当某一字段的阳极为低电平时,相应字段就不亮。通常我们用的数码管都是段选公用的,位选独立的,例如四位一体数码管。
- 数码管的内部原理图如下图所示:
二、实验过程
- 实验任务:
- 本节实验任务是使用FPGA开发板上的6位数码管以静态方式依次显示000000、111111、222222至FFFFFF,结束后继续从000000开始计数,每0.5s变化一次。
- 硬件原理图
- 硬件接口定义
- 程序框图
- seg_led_static_top
- 主要分为两个模块
- 计时模块 (time_count):实现0.5s的计时效果
- 数码管静态显示模块(seg_led_static):通过状态机实现不同状态下的显示配置,数码管静态显示模块在数码管上以静态方式显示数值。
- 代码如下:
module seg_led_static_top(
input sys_clk,
input sys_rst_n,
output [5:0] seg_wei,
output [7:0] seg_duan
);
wire time_flag;
//wire clk;
time_count u_time_count(
.sys_clk (sys_clk),
.sys_rst_n (sys_rst_n),
.time_flag (time_flag)
);
seg_led_static u_seg_led_static(
.sys_clk (sys_clk),
.sys_rst_n (sys_rst_n),
.time_flag (time_flag),
.seg_wei (seg_wei),
.seg_duan (seg_duan)
);
endmodule
module time_count(
input sys_clk,
input sys_rst_n,
output reg time_flag
);
reg [24:0] time_num;
always @(posedge sys_clk or negedge sys_rst_n)begin
if(!sys_rst_n)
begin
time_num<=25'd0;
time_flag<=1'b0;
end
else begin
if(time_num<25'd25_000_000)begin
time_num<=time_num+1'b1;
time_flag<=1'b0;
end
else
begin
time_num<=25'd1;
time_flag<=1'b1;
end
end
end
endmodule
module seg_led_static(
input sys_clk,
input sys_rst_n,
input time_flag,
output reg [5:0] seg_wei,
output reg [7:0] seg_duan
);
reg [3:0] seg_fsm;
always @(posedge sys_clk or negedge sys_rst_n)begin
if(!sys_rst_n)
seg_fsm<=4'd0;
else if(time_flag)
begin
seg_fsm<=seg_fsm+1'b1;
end
else
seg_fsm<=seg_fsm;
end
always @(posedge sys_clk or negedge sys_rst_n)begin
if(!sys_rst_n)
begin
seg_wei <=6'b000000; //低电平点亮数码管
seg_duan <=8'b00000000;
end
else
case(seg_fsm) //共阳数码管
/* 4'b0000: seg_duan <=8'b1100_0000; //0
4'b0001: seg_duan <=8'b1111_1001; //1
4'b0010: seg_duan <=8'b0100_1111;
4'b0011: seg_duan <=8'b0000_0000;
4'b0100: seg_duan <=8'b0000_0000;
4'b0101: seg_duan <=8'b0000_0000;
4'b0110: seg_duan <=8'b0000_0000;
4'b0111: seg_duan <=8'b0000_0000;
4'b1000: seg_duan <=8'b0000_0000;
4'b1001: seg_duan <=8'b0000_0000;
4'b1010: seg_duan <=8'b0000_0000;
4'b1011: seg_duan <=8'b0000_0000;
4'b1100: seg_duan <=8'b0000_0000;
4'b1101: seg_duan <=8'b0000_0000;
4'b1110: seg_duan <=8'b0000_0000;
4'b1111: seg_duan <=8'b0000)0000;
*/
4'h0 : seg_duan <= 8'b1100_0000;
4'h1 : seg_duan <= 8'b1111_1001;
4'h2 : seg_duan <= 8'b1010_0100;
4'h3 : seg_duan <= 8'b1011_0000;
4'h4 : seg_duan <= 8'b1001_1001;
4'h5 : seg_duan <= 8'b1001_0010;
4'h6 : seg_duan <= 8'b1000_0010;
4'h7 : seg_duan <= 8'b1111_1000;
4'h8 : seg_duan <= 8'b1000_0000;
4'h9 : seg_duan <= 8'b1001_0000;
4'ha : seg_duan <= 8'b1000_1000;
4'hb : seg_duan <= 8'b1000_0011;
4'hc : seg_duan <= 8'b1100_0110;
4'hd : seg_duan <= 8'b1010_0001;
4'he : seg_duan <= 8'b1000_0110;
4'hf : seg_duan <= 8'b1000_1110;
default : seg_duan <= 8'b1100_0000;
endcase
end
endmodule
仿真结果如下图:
最终实现实验任务!
(PS:调试中 顶层时钟不要连接同一个模块的两个端口 sys_clk 造成实验问题)