开发板的使用是AX301,学习资料可以在我的另一篇文章中找到。链接在如下:https://blog.csdn.net/qq_24213087/article/details/108238682
一、静态数码管介绍
数码管是很常见的一种显示设备,一般分为七段数码管和八段数码管,两者区别就在于八段数码管比七段数码管多了一个“点” 。我们采用的数码管为 6 位一体的八段数码管,数码管的段结构图如图所示
我们使用的是共阳极数码管,当某一字段对应的引脚为低电平时,相应字段就点亮,当某一字段对应的引脚为高电平时,相应字段就不亮。
说完上面的原理图,我们来看我们开发板上的设计。
六位一体数码管的相同的段都接在了一起,一共是 8 个引脚,然后加上 6个控制信号引脚,一共是 14 个引脚,如图 10.2 所示,其中 DIG[0…7]是对应数码管的 A,B,C,D,E,F,G,H(即点 DP);SEL[0…5]是六个数码管的六个控制引脚,也是低电平有效,当控制引脚为低电平时,对应的数码管有了供电电压,这样数码管才能点亮,否则无论数码管的段如何变化,也不能点亮对应的数码管。
其原理图如图所示
数码管引脚分配
这里大家注意一下,大家的数码管的引脚有可能顺序不一致,但是一般情况对应的引脚号应该没问题。
二、加法器实验
我们该实验的设计的主要功能就是通过对脉冲的控制,实现对数码管的加减。首先是一个脉冲模块的程序编写,使用分频器输出一个时钟周期为0.1s的脉冲信号。
/* time :2020.9.12
主要功能 :时间控制模块
端口定义 :clk :时钟信号
rst_n :复位信号
flag :数码管加法器信号,一个脉冲信号
===============================================================*/
module time_count(
input clk , // 时钟信号
input rst_n , // 复位信号maichong
output reg flag // 一个时钟周期的脉冲信号
);
//parameter define
parameter MAX_NUM = 50000_000; // 计数器最大计数值
//reg define
reg [25:0] cnt; // 时钟分频计数器,修改计数时,注意修改这个数的位宽
//计数器对时钟计数,每计时到0.1s,输出一个时钟周期的脉冲信号
always @ (posedge clk or negedge rst_n) begin
if (!rst_n) begin
flag <= 1'b0;
cnt <= 24'b0;
end
else if(cnt < MAX_NUM - 1'b1) begin
cnt <= cnt +1'b1;
flag <= 1'b0;
end
else begin
cnt <= 24'b0;
flag <= 1'b1;
end
end
endmodule
其RTL电路如图所示:
接下来是一个静态数码管显示模块,主要通过段选信号和位选信号,实现对六段数码管的控制以及对每段数码管显示字符的控制。
/* time :2020.9.12
主要功能 :数码管静态显示模块
端口定义 :clk :时钟信号
rst_n :复位信号
add_flag :数码管加法器信号
sel :数码管位选
seg_led :数码管段选
===============================================================*/
module seg_led_static (
input clk , // 时钟信号
input rst_n , // 复位信号(低有效)
input add_flag, // 数码管变化的通知信号
output reg [5:0] sel , // 数码管位选
output reg [7:0] seg_led // 数码管段选
);
//reg define
reg [3:0] num; // 数码管显示的十六进制数
//控制数码管位选信号(低电平有效),选中所有的数码管
always @ (posedge clk or negedge rst_n) begin
if (!rst_n)
sel <= 6'b111111;
else
sel <= 6'b011111;
end
//每次通知信号到达时,数码管显示的十六进制数值加1
always @ (posedge clk or negedge rst_n) begin
if (!rst_n)
num <= 4'h0;
else if(add_flag) begin
if (num < 4'hf)
num <= num + 1'b1;
else
num <= 4'h0;
end
else
num <= num;
end
//根据数码管显示的数值,控制段选信号
always @ (posedge clk or negedge rst_n) begin
if (!rst_n)
seg_led <= 8'b0;
else begin
case (num)
4'h0 : seg_led <= 8'b1100_0000;
4'h1 : seg_led <= 8'b1111_1001;
4'h2 : seg_led <= 8'b1010_0100;
4'h3 : seg_led <= 8'b1011_0000;
4'h4 : seg_led <= 8'b1001_1001;
4'h5 : seg_led <= 8'b1001_0010;
4'h6 : seg_led <= 8'b1000_0010;
4'h7 : seg_led <= 8'b1111_1000;
4'h8 : seg_led <= 8'b1000_0000;
4'h9 : seg_led <= 8'b1001_0000;
4'ha : seg_led <= 8'b1000_1000;
4'hb : seg_led <= 8'b1000_0011;
4'hc : seg_led <= 8'b1100_0110;
4'hd : seg_led <= 8'b1010_0001;
4'he : seg_led <= 8'b1000_0110;
4'hf : seg_led <= 8'b1000_1110;
default : seg_led <= 8'b1100_0000;
endcase
end
end
endmodule
最后就是我们的顶层模块,实现两个模块的连接,实现最终的功能:每隔0.1s对数码管的数字进行加1,实现数码管从0到f的显示。
/* time:2020.9.7
主要功能:显示一位数码管
端口定义:clock:时钟
reset:复位
sel:数码管位控制
seg_led:数码管段控
key :按键控制加减
==============================================================*/
module shumaguan (
input sys_clk , // 系统时钟
input sys_rst_n, // 系统复位信号(低有效)
output [5:0] sel , // 数码管位选
output [7:0] seg_led // 数码管段选
);
//parameter define
parameter TIME_SHOW = 50_000_000; // 数码管变化的时间间隔0.5s
//wire define
wire add_flag; // 数码管变化的通知信号
//每隔0.5s产生一个时钟周期的脉冲信号
time_count u_time_count(
.clk (sys_clk ),
.rst_n (sys_rst_n),
.flag (add_flag )
);
//每当脉冲信号到达时,使数码管显示的数值加1
seg_led_static u_seg_led_static (
.clk (sys_clk ),
.rst_n (sys_rst_n),
.add_flag (add_flag ),
.sel (sel ),
.seg_led (seg_led )
);
endmodule
最后上实物实验结果图。
发现只能连接B站的视频,我下次的结果尽量用用视频的方式进行展示。
声明:该文只适用于学习,其内容包含来自书本的摘抄和总结,欢迎大家补充,共同学习进步。