【FPGA实验】数码管静态显示

举报
zstar 发表于 2022/08/06 01:51:37 2022/08/06
【摘要】 开拓者FPGA开发板上有六个共阳极八段数码管,本实验将完成数码管静态显示。 功能描述 控制六位数码管以0.5秒的频率同时显示0-F 16个数字。 分频模块 开发板本身的时钟频率为50kH...

开拓者FPGA开发板上有六个共阳极八段数码管,本实验将完成数码管静态显示。

功能描述

控制六位数码管以0.5秒的频率同时显示0-F 16个数字。

分频模块

开发板本身的时钟频率为50kHz,对应时钟周期为20ns,而本实验需要0.5s让数字变化一次,因此需要对时钟进行分频,使其0.5s输出一个脉冲信号flag。

module time_count(
    input           clk     ,   // 时钟信号
    input           rst_n   ,   // 复位信号

    output   reg    flag        // 一个时钟周期的脉冲信号
);

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

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

//*****************************************************
//**                    main code
//*****************************************************

//计数器对时钟计数,每计时到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 

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

数码管静态显示模块

首先需清楚两个概念:
位选信号(sel)——控制哪个数码管显示
段选信号(seg_led)–控制数码管显示内容

数码管显示具体数值可参考真值表:
在这里插入图片描述
共阳极二极管,常理来说应当0才是点亮,而这里是相反的。
原因可以看下面的原理图,输入信号并不是给到二极管的负级,而是给到了三级管的基极,三极管在这里起到开关的作用,因此相反。
在这里插入图片描述
模块代码:

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;                      // 数码管显示的十六进制数

//*****************************************************
//**                    main code
//*****************************************************

//控制数码管位选信号(低电平有效),选中所有的数码管
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 

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66

顶层模块

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;                     // 数码管变化的通知信号

//*****************************************************
//**                    main code
//*****************************************************

//每隔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 

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40

注:两个分模块之间通过add_flag进行连接。

管脚分配

在这里插入图片描述

文章来源: zstar.blog.csdn.net,作者:zstar-_,版权归原作者所有,如需转载,请联系作者。

原文链接:zstar.blog.csdn.net/article/details/120952175

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。