• 【小月电子】FPGA开发板(XLOGIC_V1)系统学习教程-LESSON5


    数码管动态显示例程讲解

    若要观看该博客配套的视频教程,可点击此链接

    开发板实物图

    在这里插入图片描述
    在这里插入图片描述
    根据多年工作经验,总结出的FPGA的设计流程,概括起来总共有以上12步,其中根据项目难易度可省去其中一些步骤。比如非常简单的项目,我们可以省去虚线框里面的步骤,但是我们的入门级课程,即使再简单,也按照这12个步骤来进行讲解。

    1. 需求解读

    1.1 需求

    在六位数码管上稳定的显示123456

    1.2 知识背景

    数码管是由多个 LED 发光二极管组成的一个“8”字型的器件,根据极性不同,分为共阳极和共阴极,我们开发板上采用的是共阳数码管。数码管内部结构如下图:
    在这里插入图片描述
    在这里插入图片描述

    通过图上可以看出,共阳极和共阴极的区别。共阳极公共端接电源正极,共阴极公共端接地。选用共阳极数码管时,我们只需将对应的 abcdefgdq 给低电平便可点亮对应的数码管。共阴极与之相反,需要将 abcdefgdq 接入电源正极便可点亮对应的数码管。数码管示意图如下:
    在这里插入图片描述

    我们选用的开发板使用的是共阳极数码管,如果要显示 2,那么我们应该点亮
    A,B,G,E,D 段发光二极管。如果要显示 5,大家可以自行分析,应该点亮哪些段,这样我们便可以得出共阳数码管 0 到 9 的编码。为了节约大家的时间,我将共阳数码管对应的编码整理出来,如下图,可以直接调用。共阴数码管的编码只用按位取反即可。
    开发板共阳数码管段选编码表如下:
    在这里插入图片描述

    1.3 硬件设计

    在这里插入图片描述

    图5.有源晶振
    ![在这里插入图片描述](https://img-blog.csdnimg.cn/cbcdef28787c4f2ab4dd4b88726d2397.png#pic_center) ![在这里插入图片描述](https://img-blog.csdnimg.cn/b4deaa89d37c486a8b15537d4a5c9be8.png#pic_center)

    XLOGIC开发板上选用的是PNP三极管,当给三极管基极输入低电平,三极管的集电极与发射极便导通,3.3V 的电压便加在了数码管的位选管脚上,那么我们要点亮第一位数码管则需要给SMG_W0 输入低电平,并按数码管编码表给数码管的段选赋值。

    1.4 动态扫描原理

    我们上一讲讲了数码管的静态显示,如果只有一位,用静态扫描的方式那么我们需要控 制 8个段选,1个位选,总共 9 个引脚。如果我们要控制 6 位数码管,而同样采用静态显示的方式,那总共要用 9*6=54 个管脚,事必会造成管脚的严重浪费。为了节约管脚,同时又能显示多位信息,我们可以采用动态扫描的方式来驱动多位数码管,同样的驱动6位数码管,用动态扫描的方式只需要控制8个段选,6个位选信号,总共14个管脚,比静态扫描节约了40个,所以,利用动态扫描方式驱动数码管,是我们学习以及工作中必需要学会的。 多位数码管用于显示更多的数值信息,其由多个数码管组成,这些数码管的段(a~h) 一一对应连接在一起,公共极独立。动态扫描即按照一定的方向逐一选中数码管(通过位选接口来选中要点亮的数码管),然后给段选管脚输入事先准备好的编码数据,并保持一定的时间,如此循环。由于人眼的视觉暂留效应,我们看到的现象便是多位同时显示,这就像我们小时候翻看动画书,当翻得很快时,我们就发现书里面的小动物跑起来了,当时还乐此不疲的找过各种动画书。根据经验,当帧率为 15fps 以上时,动画是连贯的,帧率越高动画也越流畅。但是帧率过高,会造成看不清数码管上显示的信息。所以适当的帧率才是最好的。对于我们的6位数码管,扫描 1 次(显示 6 个数字) 为一帧。我们可以观察不同的扫描频率对应的数码管显示效果,找到显示效果较好的扫描方式。经实验发现,当每一个数字显示 10ms,数码管有明显的闪烁现象,当改为5ms时则显示稳定。原理掌握了,我们可以开始编写代码

    1.5 接口说明

    信号名方向FPGA管脚号说明
    CLK50M输入B10时钟信号,50MHZ
    SMG_W0输出E12位选控制信号,低电平可导通三极管,使其给数码管位选供电
    SMG_W1输出B15位选控制信号,低电平可导通三极管,使其给数码管位选供电
    SMG_W2输出E15位选控制信号,低电平可导通三极管,使其给数码管位选供电
    SMG_W3输出H11位选控制信号,低电平可导通三极管,使其给数码管位选供电
    SMG_W4输出K16位选控制信号,低电平可导通三极管,使其给数码管位选供电
    SMG_W5输出K14位选控制信号,低电平可导通三极管,使其给数码管位选供电
    SMG_A输出F13数码管段选控制信号,低电平点亮该段
    SMG_B输出B16数码管段选控制信号,低电平点亮该段
    SMG_C输出J16数码管段选控制信号,低电平点亮该段
    SMG_D输出J13数码管段选控制信号,低电平点亮该段
    SMG_E输出G14数码管段选控制信号,低电平点亮该段
    SMG_F输出E13数码管段选控制信号,低电平点亮该段
    SMG_G输出G12数码管段选控制信号,低电平点亮该段
    SMG_DP输出J14数码管段选控制信号,低电平点亮该段

    总结:通过上述说明,可以将需求解读成:当点亮第一位数码管时,位选为6’h1f,此时数码管段选的编码为8’hf9;当点亮第二位数码管时,位选为6’h2f,数码管段选的编码为8’h25;当点亮第三位数码管时,位选为6’h37,数码管段选的编码为8’h0d;当点亮第四位数码管时,位选为6’h3b,数码管段选的编码为8’h99;当点亮第五位数码管时,位选为6’h3d,数码管段选的编码为8’h49;当点亮第六位数码管时,位选为6’h3e,数码管段选的编码为8’h41;

    2. 绘制理论波形图

    在这里插入图片描述
    在这里插入图片描述

    3.新建ISE工程

    为了让工程看起来整洁,同时方便工程移植。我们新建4个文件夹,分别是Project,Source,Sim,Doc。
    Project — 工程文件夹,里面放的ISE工程
    Source — 源代码文件夹,里面放的工程源码(.v文件或.vhd文件)
    Sim — 仿真文件夹,里面放的仿真相关的文件
    Doc — 存放相关资料,比如数据手册,需求文档等

    4.编写代码

    ///
    //QQ:3181961725
    //TEL/WX:13540738439
    //作者:Mr Wang
    //模块介绍:数据管动态扫描,显示123456
    module smg_drv(
    	input	clk,
    	input	rst_n,
    	output	reg [5:0] smg_bit,
    	output	reg [7:0] smg_seg
    	);
    	parameter	refresh_time=50000;//一个时钟周期20ns,50000*20=1000000ns=1ms
    	reg	[3:0]	cnt;
    	reg	[24:0]	refresh_cnt;
    	always@(posedge clk or negedge rst_n)begin
    		if(!rst_n)
    			refresh_cnt<=0;
    		else if(refresh_cnt==refresh_time-1)
    			refresh_cnt<=0;
    		else 
    			refresh_cnt<=refresh_cnt+1;
    	end
    	always@(posedge clk or negedge rst_n)begin
    		if(!rst_n)
    			cnt<=4'hf;
    		else if(refresh_cnt==0&&cnt==5)
    			cnt<=0;
    		else if(refresh_cnt==0)
    			cnt<=cnt+1;
    		else;
    	end
    	always@(posedge clk or negedge rst_n)begin
    		if(!rst_n)begin
    			smg_bit<=6'h3f;
    			smg_seg<=8'h0;
    		end else case(cnt)
    			0:begin smg_bit<=6'h1f;smg_seg<=8'h9f; end 
    			1:begin smg_bit<=6'h2f;smg_seg<=8'h25; end 
    			2:begin smg_bit<=6'h37;smg_seg<=8'h0d; end 
    			3:begin smg_bit<=6'h3b;smg_seg<=8'h99; end 
    			4:begin smg_bit<=6'h3d;smg_seg<=8'h49; end 
    			5:begin smg_bit<=6'h3e;smg_seg<=8'h41; end 
    			default:;
    		endcase
    	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

    5.编写仿真测试激励文件

    `timescale 1ns/1ns
    module smg_drv_tb;
    	reg					clk		;
    	reg					rst_n	;
    initial
    begin
    	clk = 0;
    	rst_n=0;
    	#1000
    	rst_n=1;
    end
    always #10 clk=~clk;
    smg_drv Usmg_drv(
    	.clk		(clk),
    	.rst_n		(rst_n),
    	.smg_bit	(),
    	.smg_seg    ()
    	);
    endmodule
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    6.Modelsim仿真

    Modelsim仿真一般有两种方法

    1. 图形化界面仿真,即所有的操作都是在Modelsim软件界面上来完成,该方式的优点是,简单易学,适用于简单的项目,缺点是操作步骤繁琐。

    2. 批处理仿真,这种方式在仿真前需要编写相应的脚本文件,该方式的优点是,一键即可完成仿真,省时省力,缺点是前期需要编写脚本文件。前两讲采用的是图形化界面仿真的方式;为了更贴近工程实际,从这一讲开始,我们就采用批处理方式仿真。具体操作步骤可参考我们的视频教程
      仿真出的波形如下图所示:
      在这里插入图片描述

    7.对比波形图

    将第二步绘制的理论波形图与第六步Modelsim仿真出来的波形图进行对比,结果一致,说明我们的逻辑设计是正确的。如果发现比对结果不一致,就需要找到不一致的原因,最终要保证对比结果一致。通过对比,理论波形与仿真波形一致,说明功能符合设计要求。

    8.绑定管脚(编写UCF文件)

    NET "clk" TNM_NET = "clk";
    TIMESPEC TS_sys_clk_i = PERIOD "clk" 20 ns HIGH 50 %;
    NET "clk" 			LOC = B10	| IOSTANDARD = LVCMOS33 ;
    
    NET "rst_n" 		LOC = E4	| IOSTANDARD = LVCMOS33;
    NET "smg_seg[7]" 	LOC = F13	| IOSTANDARD = LVCMOS33;
    NET "smg_seg[6]" 	LOC = B16	| IOSTANDARD = LVCMOS33;
    NET "smg_seg[5]" 	LOC = J16	| IOSTANDARD = LVCMOS33;
    NET "smg_seg[4]" 	LOC = J13	| IOSTANDARD = LVCMOS33;
    NET "smg_seg[3]" 	LOC = G14	| IOSTANDARD = LVCMOS33;
    NET "smg_seg[2]" 	LOC = E13	| IOSTANDARD = LVCMOS33;
    NET "smg_seg[1]" 	LOC = G12	| IOSTANDARD = LVCMOS33;
    NET "smg_seg[0]" 	LOC = J14	| IOSTANDARD = LVCMOS33;
    
    NET "smg_bit[5]" 	LOC = E12	| IOSTANDARD = LVCMOS33;
    NET "smg_bit[4]" 	LOC = B15	| IOSTANDARD = LVCMOS33;
    NET "smg_bit[3]" 	LOC = E15	| IOSTANDARD = LVCMOS33;
    NET "smg_bit[2]" 	LOC = H11	| IOSTANDARD = LVCMOS33;
    NET "smg_bit[1]" 	LOC = K16	| IOSTANDARD = LVCMOS33;
    NET "smg_bit[0]" 	LOC = K14	| IOSTANDARD = LVCMOS33;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    9.添加.v和.ucf文件

    在这里插入图片描述

    10.编译综合,同时将未使用管脚设置为悬空状态

    1.设置未使用管脚为悬空状态
    在这里插入图片描述
    在这里插入图片描述

    2.编译综合
    在这里插入图片描述

    11.下载BIT文件

    编译综合成功后便可以将生成的BIT文件下载到开发板(记得插上下载器,同时开发板上电)
    1.打开IMPACT
    在这里插入图片描述

    2.搜索器件

    在这里插入图片描述

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    3.选择bit文件

    在这里插入图片描述
    在这里插入图片描述

    在这里插入图片描述

    下载成功后,便可以观察到开发板上的实验现象,如果实验现象与设计需求相符,那说明我们的设计是没有问题的,即可进行下一步生成MCS文件

    12.生成MCS文件,同时固化到配置芯片中

    FPGA有一个特性,就是掉电后配置信息会丢失,所以我们需要将配置信息存储在配置芯片(FLASH)中,待开发板上电后,FPGA便会读取配置芯片中的配置信息,这样开发板掉电再上电后同样可正常工作。要将程序固化到配置芯片,需要先生成MCS文件。
    BIT文件转换成MCS文件步骤:

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    在这里插入图片描述

    固化MCS文件
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    固化成功后,开发板断电再重新上电,可以观察到开发板仍然可以执行刚刚的功能。

  • 相关阅读:
    MybatisPlus快速学习
    RabbitMQ及各种模式
    MathType7.4绿色和谐版数学公式编辑器
    如何用 GPT-4 全模式(All Tools)帮你高效学习和工作?
    重磅!元宇宙招聘会来袭,60多所高校学生参加...
    Cilium系列-15-7层网络CiliumNetworkPolicy简介
    数据结构——二叉搜索树
    【UDS 14229-1诊断服务内容详细解读】
    关于知识图谱(第二天)
    微服务-Feign
  • 原文地址:https://blog.csdn.net/Moon_3181961725/article/details/126705055