一、数码管介绍
四位数码管3641AS为一款共阴极的四位八段数码管,其具体的每一段为单个二极管,可通过压降实现点亮,通过控制单位多段二极管的点亮实现数字或字母等字符。
共阴极:八段发光二极管的阴极端连接在一起,阳极端分开控制,使用时候公共端接地,要使哪个发光二极管亮,则对应的阳极端接高电平;
共阳极:八段发光二极管的阳极端连接在一起,阴极端分开控制,使用时候公共端接电源,要使哪个发光二极管亮,则对应的阴极端接低地。
此处为共阴极,其具体原理图如下:
如图所示:A—DP为输入端,全部在二极管的正极,二极管的负极共同接地。只有当A—DP输入为高电平的时候,二极管才导通,然后对应的段发亮。
二、实验功能
点亮后两位数码管,通过按键实现数据的自加,即按下一次按键,数码管显示的数据加一。
三、代码讲解
1、顶层top文件
`timescale 1ns / 1ps
module top_seg_key(
input sys_clk, //时钟信号
input sys_rst_n, //复位信号
input key, //按键信号
output wire [3:0] sel, //输出四位位选
output wire [7:0] seg_data //输出八位段选
);
key key_inst( //按键模块
.sys_clk (sys_clk),
.sys_rst_n (sys_rst_n),
.key (key),
.key_flag (key_flag)
);
seg seg_inst( //数码管显示模块
.sys_clk (sys_clk),
.sys_rst_n (sys_rst_n),
.key_flag (key_flag),
.sel (sel),
.seg_data (seg_data)
);
endmodule
此模块为顶层模块,例化了按键模块,数码管显示模块,输入了时钟信号,复位信号及按键信号,输出了四位位选信号及八位段选信号。
2、数码管显示模块
`timescale 1ns / 1ps
module seg(
input sys_clk,
input sys_rst_n,
input key_flag,
output reg [3:0] sel,
output reg [7:0] seg_data
);
parameter cnt_1ms = 50_000; //1ms;
reg [31:0] cnt;
reg cnt_flag; //1ms标志
reg [2:0] cnt_sel; //位选计数
reg state = 0;
//--------------计数1ms------------------//
always @(posedge sys_clk or negedge sys_rst_n)
if(!sys_rst_n)
cnt <= 0;
else
begin
if(cnt >= cnt_1ms - 1)
cnt <= 0;
else
cnt <= cnt + 1;
end
always @(posedge sys_clk or negedge sys_rst_n)
if(!sys_rst_n)
cnt_flag <= 1'b0;
else
begin
if(cnt == cnt_1ms - 1)
cnt_flag <= 1'b1;
else
cnt_flag <= 1'b0;
end
always @(posedge sys_clk or negedge sys_rst_n) //如想实现四位数码管显示,可改变state的值
if(!sys_rst_n)
state <= 1'b0;
else
begin
if(cnt_flag == 1)
state <= ~state;
else
state <= state;
end
reg [15:0] num;
reg [15:0] cnt_s = 0;
always @(posedge sys_clk or negedge sys_rst_n)
if(!sys_rst_n)
cnt_s <= 0;
else
begin
if(key_flag == 1 && cnt_s == 19)
cnt_s <= 0;
else if(key_flag == 1)
cnt_s <= cnt_s + 1;
else
cnt_s <= cnt_s;
end
always @(posedge sys_clk or negedge sys_rst_n)
if(!sys_rst_n)
sel <= 4'b1111;
else
begin
case(state) //两个值实现两位数码管显示,四位可依此改变
0:
begin
sel <= 4'b1110;
num <= cnt_s % 10;
end
1:
begin
sel <= 4'b1101;
num <= cnt_s /10 % 10;
end
default: sel <= 4'b1111;
endcase
end
always @(posedge sys_clk or negedge sys_rst_n)
if(!sys_rst_n)
seg_data <= 8'b0000_0000;
else
begin
case(num)
0:seg_data <= 8'b0011_1111; //dp g f e d c b a
1:seg_data <= 8'b0000_0110;
2:seg_data <= 8'b0101_1011;
3:seg_data <= 8'b0100_1111;
4:seg_data <= 8'b0110_0110;
5:seg_data <= 8'b0110_1101;
6:seg_data <= 8'b0111_1101;
7:seg_data <= 8'b0000_0111;
8:seg_data <= 8'b0111_1111;
9:seg_data <= 8'b0110_1111;
default:seg_data <= 8'b0000_0000;
endcase
end
endmodule
数码管显示模块,动态显示,通过一个1ms计数器进行位选,即每一位之间的位选间隔为1ms。此处数码管显示原理为视觉暂留效应及余晖效应。此外有数码管的静态显示为基础,不做更多原理赘述。文章来源:https://www.toymoban.com/news/detail-743743.html
3、按键模块
`timescale 1ns / 1ps
module key(
input sys_clk,
input sys_rst_n,
input key,
output reg key_flag //按键标志信号
);
parameter cnt_10ms = 500_000; //10ms
reg [31:0] cnt = 0;
always @(posedge sys_clk or negedge sys_rst_n)
if(!sys_rst_n)
cnt <= 0;
else
begin
if(key)
cnt <= 0;
else if(cnt >= cnt_10ms - 1)
cnt <= cnt;
else
cnt <= cnt + 1;
end
always @(posedge sys_clk or negedge sys_rst_n)
if(!sys_rst_n)
key_flag <= 1'b0;
else
begin
if(cnt == cnt_10ms - 2)
key_flag <= 1'b1;
else
key_flag <= 1'b0;
end
endmodule
按键模块的主要部分为按键消抖。由于机械按键的物理特性,按键被按下的过程中,存在一段时间的抖动,同时在释放按键的过程中也存在抖动,这就导致在识别的时候可能检测为多次的按键按下,而通常检测到一次按键输入信号的状态为低电平,就可以确认按键被按下了,所以我们在使用按键时往往需要消抖,以确保按键被按下一次只检测到一次低电平。此处通过计数10ms,输出正确的按键标志信号。文章来源地址https://www.toymoban.com/news/detail-743743.html
到了这里,关于四位数码管3641AS的FPGA实现的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!