FPGA之静态数码管显示

一曲冷凌霜 提交于 2020-02-06 07:54:26

数码管显示0~F,每隔0.5秒变换一次
数码管连接方式不同分为共阴极数码管和共阳极数码管。
数码管引脚:
在这里插入图片描述
上图两个com引脚实际是连在一起的,其他引脚的公共端,称为位选,位选的高低电平决定改数码管能否点亮,其他管脚为段选信号,决定数码管上哪个二极管发光。
共阴极数码管连接方式
在这里插入图片描述
共阳极数码管连接方式:
在这里插入图片描述
共阳八段极数码管真值表
在这里插入图片描述
数码管原理图
在这里插入图片描述
以第五个数码管为例,LEDSEG CH6通过470R的电阻连接到Q6三极管的基极,第五个数码管的位选SEL5连接到Q6三极管的集电极,Q6三极管的发射极;连接电源。所以在代码中,只需将LEDSEG CH6(代码意义的位选)赋值为0(低电平),则数码管真正的选段就连通电源了,此数码管位共阳极数码管。在数码管电路图中,六个数码管公用八个段选信号,段选信号与FPGA管脚连接。所以,静态显示的时候,六个数码管显示的一样。

本次设计的系统框图
在这里插入图片描述
顶层模块原理图
在这里插入图片描述
顶层模块设计

module seg_led_static_top(
    input   sys_clk, //系统时钟
    input   sys_rst_n, //系统复位信号(低有效)
    
    output  [5:0]   sel, //数码管位选
    output  [7:0]   seg_led //数码管段选
);

//parameter define
parameter TIME_SHOW = 25'd25000_000; //数码管变化的时间间隔0.5s

//wire define 
wire  add_flag; //数码管变化的通知信号

//每隔0.5s产生一个时钟周期的脉冲信号
time_count #(.MAX_NUM(TIME_SHOW)
) 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

时钟模块设计

module time_count(
    input           clk, //时钟信号
    input           rst_n, //复位信号
    
    output  reg     flag //一个时钟周期的脉冲信号
);

//parameter define
parameter MAX_NUM = 25000_000; //计数器最大计数值

//reg define
reg [24:0] cnt; //时钟S分频计数器

//计数器对时钟计数,每计时到0.5s,输出一个时钟周期的脉冲信号
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

静态数码管模块

module seg_led_static(
    input   clk,//时钟信号
    input   rst_n, //复位信号(低有效)
    
    input   add_flag, //数码管变化的通知信号
    output reg  [5:0] sel, //数码管位选(本次实验开发版有六个数码管)
    output reg  [7:0] seg_led //数码管段选
);

reg [3:0] num; //数码管显示的十六位进制数

//控制数码管位选信号(低电平有效),选中所有的数码管(静态显示)
always @ (posedge clk or negedge rst_n) begin
    if (!rst_n)
        sel <= 6'b111111;
    else
        sel <= 6'b000000;
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
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!