小梅哥Xilinx FPGA学习笔记15—数码管动态扫描显示

数码管段码显示

一个数码管有八个引脚,控制八段二极管的亮灭,用以显示需要的数字。

当有N个数码管时,一个一个控制的话需要N x 8 个引脚,消耗资源较多。用动态显示的方法可降低成本

数码管动态显示

将每个数码管相应的LED阴极连在一起,并加入选通信号sel。sel为高电平(位选),阴极为低电平(段选)

eg:当sel0为高电平,sel1、sel2为低电平,a为低电平,b-h为高电平时,数码管0的LED0点亮

动态显示的方案通过人眼的视觉暂留特性达到静态显示的效果(动态显示周期<20ms),只需8+n个引脚。节省了大量资源。

逻辑电路:

任务要求clk1频率为50MHz,即周期20ns,分频后clk2频率为1kHz,即周期1ms(500us翻转一次)

查找表:

 不同段码输入后相应的显示内容:

verilog设计文件:

`timescale 1ns / 1ps

module hex8(
    Clk,
    Reset_n,
    Disp_Data,
    sel,
    seg
    );
    
    input Clk;
    input Reset_n;
    input[31:0]Disp_Data;
    output reg [7:0]sel;
    output reg[7:0]seg;//seg[0]对应a...seg[7]对应h

    reg clk_1k; //周期1ms(500us翻转一次)
    reg [14:0]div_cnt;     //5000000/20=25000 15位二进制
    always@(posedge Clk or negedge Reset_n)
    if(!Reset_n)
        div_cnt <= 0;
    else if(div_cnt == 24999)
        div_cnt <= 0;
    else
        div_cnt <= div_cnt + 1'b1;
        
    always@(posedge Clk or negedge Reset_n)
    if(!Reset_n)  
        clk_1k <= 0;
    else if(div_cnt >= 24999)
        clk_1k <= ~clk_1k;  
    
    //这种时钟在绝大多数场合不允许使用
     reg [2:0]num_cnt;
     always@(posedge clk_1k or negedge Reset_n)
     if(!Reset_n)  
        num_cnt <= 0;
     else 
        num_cnt <= num_cnt + 1'b1;
     
     //三八译码器
     always@(*)
        case(num_cnt)
            0:sel = 8'b00000001;
            1:sel = 8'b00000010;
            2:sel = 8'b00000100;
            3:sel = 8'b00001000;
            4:sel = 8'b00010000;
            5:sel = 8'b00100000;
            6:sel = 8'b01000000;
            7:sel = 8'b10000000;
       endcase 
    
   //数码管输出-查表   
   reg[3:0]disp_tmp;
   always@(*)
        case(num_cnt)
            0:disp_tmp = Disp_Data[31:28];
            1:disp_tmp = Disp_Data[27:24];
            2:disp_tmp = Disp_Data[23:20];
            3:disp_tmp = Disp_Data[19:16];
            4:disp_tmp = Disp_Data[15:12];
            5:disp_tmp = Disp_Data[11:8];
            6:disp_tmp = Disp_Data[7:4];
            7:disp_tmp = Disp_Data[3:0];
       endcase 
 
    always@(*)
        case(disp_tmp)
            4'h0:seg = 8'hc0; //注意,是用十六进制表示,这里的0也是十六进制的0
            4'h1:seg = 8'hf9;
            4'h2:seg = 8'ha4;
            4'h3:seg = 8'hb0;
            4'h4:seg = 8'h99;
            4'h5:seg = 8'h92;
            4'h6:seg = 8'h82;
            4'h7:seg = 8'hf8;
            4'h8:seg = 8'h80;
            4'h9:seg = 8'h90;
            4'ha:seg = 8'h88;
            4'hb:seg = 8'h83;
            4'hc:seg = 8'hc6;
            4'hd:seg = 8'ha1;
            4'he:seg = 8'h86;
            4'hf:seg = 8'h8e;
       endcase 
    
endmodule

②改进:

`timescale 1ns / 1ps

module hex8(
    Clk,
    Reset_n,
    Disp_Data,
    sel,
    seg
    );
    
    input Clk;
    input Reset_n;
    input[31:0]Disp_Data;
    output reg [7:0]sel;
    output reg[7:0]seg;//seg[0]对应a...seg[7]对应h

    reg clk_1k; 
    reg [15:0]div_cnt;     
    
    //改进:使能时钟,每1ms给一个持续20ns的高电平,其他时候均为低电平
    always@(posedge Clk or negedge Reset_n)
    if(!Reset_n)
        div_cnt <= 0;
    else if(div_cnt == 49999)
        div_cnt <= 0;
    else
        div_cnt <= div_cnt + 1'b1;
        
    always@(posedge Clk or negedge Reset_n)
    if(!Reset_n)  
        clk_1k <= 0;
    else if(div_cnt == 49999)
        clk_1k <= 1'b1;  
    else 
        clk_1k <= 0;
    

     reg [2:0]num_cnt;
     always@(posedge Clk or negedge Reset_n)
     if(!Reset_n)  
        num_cnt <= 0;
     else if(clk_1k)
        num_cnt <= num_cnt + 1'b1;
     
     //尽量都改为时序逻辑
     //三八译码器 
     always@(posedge Clk)
        case(num_cnt)
            0:sel = 8'b00000001;
            1:sel = 8'b00000010;
            2:sel = 8'b00000100;
            3:sel = 8'b00001000;
            4:sel = 8'b00010000;
            5:sel = 8'b00100000;
            6:sel = 8'b01000000;
            7:sel = 8'b10000000;
       endcase 
    
   //数码管输出-查表   
   reg[3:0]disp_tmp;
   always@(posedge Clk)
        case(num_cnt)
            7:disp_tmp = Disp_Data[31:28];
            6:disp_tmp = Disp_Data[27:24];
            5:disp_tmp = Disp_Data[23:20];
            4:disp_tmp = Disp_Data[19:16];
            3:disp_tmp = Disp_Data[15:12];
            2:disp_tmp = Disp_Data[11:8];
            1:disp_tmp = Disp_Data[7:4];
            0:disp_tmp = Disp_Data[3:0];
       endcase 
 
    always@(posedge Clk)
        case(disp_tmp)
            4'h0:seg = 8'hc0; //注意,是用十六进制表示,这里的0也是十六进制的0
            4'h1:seg = 8'hf9;
            4'h2:seg = 8'ha4;
            4'h3:seg = 8'hb0;
            4'h4:seg = 8'h99;
            4'h5:seg = 8'h92;
            4'h6:seg = 8'h82;
            4'h7:seg = 8'hf8;
            4'h8:seg = 8'h80;
            4'h9:seg = 8'h90;
            4'ha:seg = 8'h88;
            4'hb:seg = 8'h83;
            4'hc:seg = 8'hc6;
            4'hd:seg = 8'ha1;
            4'he:seg = 8'h86;
            4'hf:seg = 8'h8e;
       endcase 
    
endmodule
仿真文件:
`timescale 1ns / 1ps

module hex8_tb();
    reg Clk;
    reg Reset_n;
    reg [31:0]Disp_Data;
    wire[7:0]sel;
    wire[7:0]seg;

hex8 hex8(
    Clk,
    Reset_n,
    Disp_Data,
    sel,
    seg
    );
    initial Clk = 1;
    always #10 Clk = ~Clk;
    
    initial begin
        Reset_n = 0;
        Disp_Data = 32'h00000000;
        #201;
        Reset_n = 1;
        #2000;
        Disp_Data = 32'h12345678;
        #10000000;
        Disp_Data = 32'h9abcdef0;
        #10000000;
        $stop;
        end
endmodule

  • 14
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
小梅哥学习Xilinx FPGA期间进行了积极的探索,特别是对Cyclone V SOC的开发流程进行了学习。从裸机到基于Linux嵌入式系统,小梅哥实现了FPGA和ARM Cortex-A9 CPU之间的双向控制和数据传输。 在代码编写方面,小梅哥设计了一个名为mux2的模块,用于实现二选一多路器。模块包含了输入和输出端口,并通过assign语句实现了信号的赋值。 在激励文件中,小梅哥使用reg和wire定义了输入和输出信号,并通过mux2模块进行了实例化。然后,通过initial块生成了一系列的激励信号,对模块进行仿真。 总结来说,小梅哥Xilinx FPGA学习笔记中记录了自己对Cyclone V SOC的学习、代码编写和激励文件的使用。这些学习内容对于理解FPGA开发流程以及实现特定功能非常有帮助。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [FPGA自学笔记——设计与验证VIP版.pdf](https://download.csdn.net/download/qq_30307853/11656682)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* *3* [小梅哥Xilinx FPGA学习笔记1——二选一多路器](https://blog.csdn.net/weixin_42454243/article/details/122026484)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值