基于FPGA数码管动态驱动实验

基于FPGA数码管动态驱动实验

硬件介绍

  1. 国产GW-FPGA 9K开发板
  2. 四位共阳数码管,其图看博主驱动单个数码管实验—驱动单个数码管实验

功能介绍:

实现简单的数字时钟显示,采用动态扫描的方式驱动四个数码管共同显示

顶层文件源码:

`timescale 1ns / 1ps
//引脚说明:    数码管Out_IO:a~g 38 37 36 29 25 26 27   位选:num: 42 35 41 42   冒号显示 :28
module Fore_LED(
        clk,            //时钟信号
        res_n,          //复位信号
        out_iO,   //数码管输出
        colon,
        num       //数码管位数选择
    );

    input clk;         //时钟信号
    input res_n;       //复位信号
    output reg [6:0] out_iO;   //数码管输出
    output reg colon; // h 数码管小数点显示
    output reg [3:0] num;       //数码管位数选择

    // 1khz的毫秒计数器     计数个数为:27027
    parameter _1KHZ = 27027;
    parameter _1STIM = 1000;
    reg [14:0] _count;
    reg [3:0] count_1khz;
    reg [15:0] count_1s;

    reg [4:0] Display_NUM_H;
    reg [5:0] Display_NUM_Min;
    reg [5:0] Display_NUM_S;

    //最底层1khz计数模块
    always @(posedge clk or negedge res_n) begin
        if(!res_n)
            _count <= 0;
        else if(_count == _1KHZ-1)
            _count <= 0;
        else
            _count <= _count + 1'd1;
    end
    //1ms扫描模块
    always @(posedge clk or negedge res_n) begin
        if(!res_n)
            count_1khz <= 0;
        else if(_count == _1KHZ-2 && count_1khz >= 3'd4 )
            count_1khz <= 0;
        else if(_count == _1KHZ-2)
            count_1khz <= count_1khz + 1'd1;
    end
    //1s定时模块        计数个数 : 27,027,027
    always @(posedge clk or negedge res_n) begin
        if(!res_n)
            count_1s <= 0;
        else if(_count == _1KHZ-2 && count_1s == _1STIM-1)
            count_1s <= 0;
        else if(_count == _1KHZ-2)
            count_1s <= count_1s+1'd1;
    end
    //计数增长模块
    reg _1s_Flag;
	reg _1min_Flag;
    reg Flag_Buf;
    always @(posedge clk or negedge res_n) begin
        if(!res_n) begin
            _1s_Flag <= 0;
            Flag_Buf <= 1;
        end
        else if(count_1s == _1STIM-2) begin
            _1s_Flag <= 0;
            Flag_Buf <= 1;
        end
        else if(count_1s == _1STIM-3 && Flag_Buf == 1) begin
            _1s_Flag<=1;
            Flag_Buf <=0;
        end
        else if(Flag_Buf == 0)
            _1s_Flag<=0;

    end
    //秒加器
    always @(posedge clk or negedge res_n) begin
        if(!res_n) begin
            Display_NUM_S <= 20;
            colon <= 1;
        end
        else if(Display_NUM_S > 60 ) begin
            Display_NUM_S <= 0;
        end
        else if(_1s_Flag == 1)begin
            Display_NUM_S <= Display_NUM_S + 1'd1;
            colon <= ~colon;
        end
    end
    //分加器
    always @(posedge clk or negedge res_n) begin
        if(!res_n)begin
            Display_NUM_Min <= 21;
			_1min_Flag<=0;
		end
        else if(Display_NUM_S >= 60 && Display_NUM_Min >= 60) begin
            Display_NUM_Min <= 0;
        end
        else if(Display_NUM_S >= 60 && _1s_Flag == 1 )begin
            Display_NUM_Min <= Display_NUM_Min + 1'd1;
			_1min_Flag<=1;
		end	
		else 
			_1min_Flag<=0;
    end

    //时加器
    always @(posedge clk or negedge res_n) begin
        if(!res_n)
            Display_NUM_H <= 13;
        else if(Display_NUM_Min >= 59 && Display_NUM_H >= 24) begin
            Display_NUM_H <= 0;
        end
        else if(Display_NUM_Min >= 59 && _1min_Flag == 1 )
            Display_NUM_H <= Display_NUM_H + 1'd1;
    end

    //共阳数码管  {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};
    reg [6:0] Digitron_Data [15:0];
    //要显示的数据
    reg [31:0] disp_data;

    always @(posedge clk or negedge res_n) begin
        if(!res_n) begin
            disp_data <= 1;
            Digitron_Data[0] <= 7'hc0;  // 正常顺序
            Digitron_Data[1] <= 7'hf9;
            Digitron_Data[2] <= 7'hA4;
            Digitron_Data[3] <= 7'hb0;
            Digitron_Data[4] <= 7'h99;
            Digitron_Data[5] <= 7'h92;
            Digitron_Data[6] <= 7'h82;
            Digitron_Data[7] <= 7'hF8;
            Digitron_Data[8] <= 7'h80;
            Digitron_Data[9] <= 7'h90;
        end
        else begin

            disp_data[6:0]  <= Digitron_Data[Display_NUM_H/10];
            disp_data[14:8] <= Digitron_Data[Display_NUM_H%10];
            disp_data[22:16]<= Digitron_Data[Display_NUM_Min/10];
            disp_data[30:24]<= Digitron_Data[Display_NUM_Min%10];

        end
    end


    always @(posedge clk or negedge res_n) begin
        if(!res_n)
            num <= 0;
        else begin
            case (count_1khz)
                4'd0: begin
                    num<= 4'b0001;
                    out_iO<= disp_data[6:0];
                end
                4'd1: begin
                    num<= 4'b0010;
                    out_iO<= disp_data[14:8];
                end
                4'd2: begin
                    num<= 4'b0100;
                    out_iO<= disp_data[22:16];
                end
                4'd3: begin
                    num<= 4'b1000;
                    out_iO<= disp_data[30:24];
                end
                default:
                    num <= num;
            endcase
        end
    end

endmodule

testbench文件

`timescale 1ns / 1ns
module Fore_LED_tb();

    reg clk;            //时钟信号
    reg res_n;       //复位信号
    wire [7:0] out_iO;   //数码管输出
    wire [3:0] num;       //数码管位数选择

    Fore_LED #(
        ._1KHZ(102),
        ._1STIM(12)
    ) Fore_LED(
                .clk(clk),          //时钟信号
                .res_n(res_n),      //复位信号
                .out_iO(out_iO),    //数码管输出
                .num(num)           //数码管位数选择
            );

    always #10 clk = ~clk;

    initial begin
        clk = 0;
        // out_iO = 1;
        // num=0;
        res_n = 0;
        #20
        res_n = 1;
    end
endmodule

modusim软件仿真波形

在这里插入图片描述

最后说明:

引脚约束等读者自行按照自己的开发板选择管脚即可,注意引脚的电平即可

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值