文章目录
- 一、实验环境
- 二、实验原理
- 三、实验任务
- 四、实验过程
- 4.1 time_count模块
- 4.2 seg_led_static模块
- 4.3 top_seg_led_static模块
- 4.4 引脚配置
- 五、仿真
- 5.1 仿真代码
- 5.2 仿真结果
- 六、实验结果
- 七、总结
一、实验环境
quartus 18.1
modelsim
vscode
Cyclone IV开发板
二、实验原理
我们使用的数码管是8段数码管,每段是由led组成。通过控制每段led的亮灭,来控制数码管显示不同的数字和字母。
数码管分为共阴极和共阳极,共阳极数码管如图所示,a—dp为输入端,全部在二极管的负极,二极管的正极极共同接+5v(高电平)。只有当a—dp输入为低电平的时候,二极管才导通,然后对应的段发亮。共阴极与之相反。
要显示不同的数字或者字母,就要选择点亮对应的led段。下图中、对应的是cyclone IV开发板上数码管的真值表,可以通过查找该表来显示我们想要的数字或者字母。
我们的开发板上的数码管分为了6位和8段,6位了控制6个数码管是否显示,8段来控制每个数码管显示的内容。本次实验是数码管的静态显示,因此只考虑段选信号。在不同的时刻,各个位选信号保持不变,并根据真值表,选择要显示的数字或者字母。并且Cyclone IV开发板中的数码管是共阳极,所以数码管中需要给低电平,对应的led段才会亮。
三、实验任务
六个数码管同时间隔0.5s显示0-f。要求:使用一个顶层模块,调用计时器模块和数码管静态显示模块。
四、实验过程
4.1 time_count模块
module time_count(input clk,//50MHz时钟信号input rst_n,//复位信号outputregflag//一个时钟周期的脉冲信号);parameter MAX_NUM = 25'd25_000_000;//计数器最大计数值reg[24:0] cnt ; //时钟分频计数器//计数器对时钟计数,每0.5s,输出一个时钟周期脉冲信号always @(posedge clk or negedge rst_n)beginif(!rst_n)begin//按复位时flag <= 1'b0;//信号为0cnt <= 25'd0;//计数器清零endelse if(cnt < MAX_NUM - 1'b1)begin//如果没到时间flag <= 1'b0;//信号为0cnt <= cnt + 1'b1;//计数器正常累计+1endelsebegin //否则到时间flag <= 1'b1;//信号变为1cnt <= 25'd0;endendendmodule
4.2 seg_led_static模块
moduleseg_led_static(inputclk ,inputrst_n ,inputflag,outputreg [5:0] sel ,//数码管位选信号outputreg [7:0] seg//数码管段选信号);reg [3:0]num;//数码管显示十六进制数//控制数码管位选信号(注:低电平有效),选中所有的数码管always @(posedge clk or negedge rst_n)beginif(!rst_n)//如果按复位键0sel <= 6'b111111;//则默认为高电平else sel <= 6'b000000;//否则为低电平end//每次通知信号flag到达时,数码管计数加1always @(posedge clk or negedge rst_n)beginif(!rst_n)num <=4'h0;else if(flag)beginif(num < 4'hf)num <= num + 1'h1;else num <= 4'h0;endelse beginnum <= num;endend//根据数码管显示的数值,控制段选信号always @(posedge clk or negedge rst_n)beginif(!rst_n)seg <= 8'b0;else begincase(num)//匹配16进制数4'h0:seg <= 8'b1100_0000;//匹配到后参考共阳极真值表4'h1:seg <= 8'b1111_1001;4'h2:seg <= 8'b1010_0100;4'h3:seg <= 8'b1011_0000;4'h4:seg <= 8'b1001_1001;4'h5:seg <= 8'b1001_0010;4'h6:seg <= 8'b1000_0010;4'h7:seg <= 8'b1111_1000;4'h8:seg <= 8'b1000_0000;4'h9:seg <= 8'b1001_0000;4'ha:seg <= 8'b1000_1000;4'hb:seg <= 8'b1000_0011;4'hc:seg <= 8'b1100_0110;4'hd:seg <= 8'b1010_0001;4'he:seg <= 8'b1000_0110;4'hf: seg <= 8'b1000_1110;default : seg <= 8'b1100_0000;endcaseendendendmodule
4.3 top_seg_led_static模块
moduletop_seg_led_static(inputclk,//50MHz系统时钟input rst_n,//系统复位信号(低有效)output[5:0] sel,//数码管位选output[7:0] seg//数码管段选); parameterMAX_NUM = 25'd25_000_000;// 数码管变化的时间间隔0.5swireadd_flag;// 数码管变化的通知信号//每隔0.5s产生一个时钟周期的脉冲信号time_count #(.MAX_NUM(MAX_NUM)) u_time_count(.clk(clk),//50MHz时钟信号.rst_n(rst_n),//复位信号.flag(add_flag)//一个时钟周期的脉冲信号);//每当脉冲信号到达时,使数码管显示的数值加1seg_led_static u_seg_led_static(.clk(clk),.rst_n(rst_n),.flag(add_flag),.sel(sel),.seg(seg));endmodule
4.4 引脚配置
五、仿真
5.1 仿真代码
`timescale 1ns/1nsmodule top_seg_led_static_tb();regclk;reg rst_n;wire[5:0]sel ;wire [7:0]seg;parameter CYCLE = 5'd20;//周期20nsparameter MAX_NUM = 8'd100;//调小间隔时间100*20nsalways #(CYCLE/2) clk = ~clk;//翻转时钟initial beginclk = 0 ;//时钟初始为0rst_n = 0 ;//复位初始为0#(CYCLE) ;//延迟20nsrst_n = 1 ;//复位置1#(16*MAX_NUM*CYCLE);//显示0-f时间$stop ;//停止end top_seg_led_static#(.MAX_NUM (MAX_NUM))u_top_seg_led_static(.clk(clk),//50MHz系统时钟.rst_n(rst_n),//系统复位信号(低有效).sel(sel),//数码管位选.seg(seg)//数码管段选);endmodule
5.2 仿真结果
六、实验结果
七、总结
本次实验主要是数码管的静态显示,只控制了数码管的段选信号,后续还需要控制位选信号实现动态显示。