目录

一:实验要求

二:程序源代码

2.1  CNT6的VHDL源代码

2.2   CLKGEN(分频器)的VHDL源程序

2.3  DTTIMES(数字秒表顶层文件)的VHDL源程序

三:硬件实验现象

四:对实验步骤详细分析

4.1     CNT6代码分析

 4.2  DISPLAY的源代码分析

 4.3 分频器波形仿真  (重要!)

 4.4   顶层文件波形仿真


一:实验要求

设计并调试好一个计时范围为0.01s~1h的数字秒表,并用GW48系列或其他EDA实验开发系统(事先应选定拟采用的实验芯片的型号)进行硬件验证。

                                      图1: 实验电路

设计思路:为了能够在数码管上显示,所以需要CTRLS(动态扫描)和DISPLAY(动态显示),相对于DTCNT9999不同的是这时候需要的数码管从四根变到了六根,并且由于我们日常秒表的特性(大家可以打开我们手机自带的时钟,里面就有秒表的功能)其中60s是等于一分钟的,60分钟是等于1h的,从0.01s--1h需要四个10进制的计数器,俩个六进制的计数器。

那么大家想一下,那我最小单元0.01s从哪里而来呢,这时候就用到了分频器。

分频器的功能就是将输入的信号频率进行一个分频(可以当成一个除法器)

NEWCLK=CLK/分频常数

其中我选择3万的分频常数,并且把外部频率作为输入频率,通过不断调整外部频率来达到100hz计数时钟输出。(所以我需要找到3M的外部频率)

二:程序源代码

部分代码与第一篇一致可以移植

2.1  CNT6的VHDL源代码

LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY CNT6 IS
	PORT(CLK: IN STD_LOGIC;
		  CLR: IN STD_LOGIC;
		  ENA: IN STD_LOGIC;
		  CQ:OUT STD_LOGIC_VECTOR(3 DOWNTO 0);
		  CO:OUT STD_LOGIC);
END ENTITY CNT6;
ARCHITECTURE ART OF CNT6 IS
	SIGNAL CQI: STD_LOGIC_VECTOR(3 DOWNTO 0);
	BEGIN
	PROCESS(CLK, CLR, ENA) IS
		BEGIN
		IF CLR='1' THEN CQI<="0000";
		 ELSIF CLK'EVENT AND CLK='1' THEN
		  IF ENA='1' THEN
		     IF CQI="0101" THEN CQI<="0000";
		     ELSE CQI<=CQI+'1'; END IF;
		  END IF;
		END IF;
	END PROCESS;
	PROCESS(CQI) IS
	  BEGIN
	  IF CQI="0000" THEN CO<='1';
	  ELSE CO<='0'; END IF;
	END PROCESS;
	CQ<=CQI;
END ARCHITECTURE ART;

2.2   CLKGEN(分频器)的VHDL源程序

LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY CLKGEN IS
	PORT(CLK: IN STD_LOGIC; --3 MHz信号输入
	     NEWCLK: OUT STD_LOGIC); --100 Hz计时时钟信号输出
END ENTITY CLKGEN;
ARCHITECTURE ART OF CLKGEN IS
	SIGNAL CNT: INTEGER RANGE 0 TO 10#29999#;--十进制计数预制数
	--SIGNAL CNT: INTEGER RANGE 0 TO 10#29#;--十进制计数预制数
	BEGIN
	PROCESS(CLK) IS --分频计数器,由3MHz时钟产生100Hz信号
		BEGIN
		IF CLK'EVENT AND CLK='1' THEN
		 IF CNT=10#29999# THEN CNT<=0; --分频常数为 30000
		 --IF CNT=10#29#THEN CNT<=0;--分频常数为30
		  ELSE CNT<=CNT+1;
		  END IF;
		END IF;
	END PROCESS;
	PROCESS(CNT) IS --计数溢出信号控制
		BEGIN
		IF CNT=10#29999# THEN NEWCLK<='1';
		--IF CNT=10#29# THEN NEWCLK<='1';
		ELSE NEWCLK<='0';
		END IF;
	END PROCESS;
END ARCHITECTURE ART;

2.3  DTTIMES(数字秒表顶层文件)的VHDL源程序

LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY TIMER IS
	PORT(CLR: IN STD_LOGIC;
		  CLK1: IN STD_LOGIC;
		  ENA: IN STD_LOGIC;
		  CLK2:IN STD_LOGIC;
		  COM:OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
		  SEG:OUT STD_LOGIC_VECTOR(7 DOWNTO 0));
		  
END ENTITY TIMER;
ARCHITECTURE ART OF TIMER IS
	COMPONENT CLKGEN IS
		PORT(CLK: IN STD_LOGIC;
			  NEWCLK: OUT STD_LOGIC);
	END COMPONENT CLKGEN;
	COMPONENT CNT10 IS
		PORT(CLK, CLR, ENA: IN STD_LOGIC;
			  CQ:OUT STD_LOGIC_VECTOR(3 DOWNTO 0);
			  CO: OUT STD_LOGIC);
	END COMPONENT CNT10;
	COMPONENT CNT6 IS
		PORT(CLK, CLR, ENA: IN STD_LOGIC;
				CQ:OUT STD_LOGIC_VECTOR(3 DOWNTO 0);
				CO: OUT STD_LOGIC);
	END COMPONENT CNT6;
	COMPONENT CTRLS IS
		PORT(CLK:IN STD_LOGIC;
			  SEL:OUT STD_LOGIC_VECTOR(2 DOWNTO 0));
	END COMPONENT CTRLS;
	COMPONENT DISPLAY IS
		PORT(SEL:IN STD_LOGIC_VECTOR(2 DOWNTO 0);
			  DATAIN:IN STD_LOGIC_VECTOR(23 DOWNTO 0);
			  COM: OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
			  SEG: OUT STD_LOGIC_VECTOR(7 DOWNTO 0));
	END COMPONENT DISPLAY;	
	SIGNAL S0: STD_LOGIC;
	SIGNAL S1, S2, S3, S4, S5: STD_LOGIC;
	SIGNAL S:STD_LOGIC_VECTOR(2 DOWNTO 0);
	SIGNAL DOUT:STD_LOGIC_VECTOR(23 DOWNTO 0);
	BEGIN
	UO: CLKGEN PORT MAP(CLK=>CLK1, NEWCLK=>S0);
	U1: CNT10 PORT MAP(S0,CLR,ENA, DOUT(3 DOWNTO 0), S1);
	U2: CNT10 PORT MAP(S1, CLR, ENA,DOUT(7 DOWNTO 4), S2);
	U3: CNT10 PORT MAP(S2, CLR, ENA, DOUT(11 DOWNTO 8), S3);
	U4: CNT6 PORT MAP(S3, CLR, ENA, DOUT(15 DOWNTO 12), S4);
	U5: CNT10 PORT MAP(S4, CLR,ENA, DOUT(19 DOWNTO 16), S5);
	U6: CNT6 PORT MAP(S5, CLR, ENA, DOUT(23 DOWNTO 20));
	U7: CTRLS PORT MAP(CLK2,S(2 DOWNTO 0));
	U8: DISPLAY PORT MAP(S,DOUT,COM,SEG);
END ARCHITECTURE ART;

三:硬件实验现象

EDA实验数字秒表

四:对实验步骤详细分析

对应CNT10、CTRLS部分和DTCNT9999分析一致,可以看我第一篇文章

大家一定要有代码移植的思想,对于之前写过代码要有一个保存,然后当你需要的时候,将该模块代码移植过去即可、引脚锁定与DTCNT9999引脚锁定一致,可参考第一篇文章。

RTL图:可以从RTL图看出整个电路的整体状态,可以看出信号从CLK1进入分频器输入100hz的信号,以0.01s的最小单元进行计数,CNT6一个在第四位和第六位,大家可以可以看到秒表的显示很容易就理解为什么CNT6在第四位和第六位了。

                             图4.1      RTL 整体电路图

          

4.1     CNT6代码分析

和CNT10代码其实是差不多一致的,只是略有修改,就是进位的数值。CNT10是10进制0-9便会产生一个进行信号,而CNT6是计数从0-5便会产生一个进位信号。

 4.2  DISPLAY的源代码分析

由于DTCNT9999只需要4个数码管显示数字,但是数字秒表大家可以发现是六个数码管显示数字,并且俩个数码管显示一个点。这时候就需要大家对数码管显示数字的驱动端代码进行改动。

由于数码管是六个数码管电亮,那我怎么去显示点然后移动他们的位置呢?(很重要)

控制数码管显示数字的信号从4*4=16变到了4*6=24个信号。然后再对显示数字的数码管进行移位操作。其中俩个点其实就是让数码管一直为点。然后可以看到SEL中000-111分别控制一个数码管其中000代表第一个数码管。而我们要对原来的六位显示数字的数码管移位,第三和第六数码管一直显示为0即可。

举例:由于疫情原因不能超过俩个人聚在一起,所以在每俩个人之间需要放置一个挡板,最开始六个人聚在一起,所以你需要俩个俩个的分别用挡板隔开。其中000-111就是对应位置都在那,但是其中俩个位置需要一直放挡板,然后其他六个位置可以使用,但是需要每隔一个位置。

 

    没有控制数码管显示数字的一直显示为点。

 4.3 分频器波形仿真  (重要!)

我们硬件部分要实现是100hz,对应3M的信号输入,所以需要30000分频,即30000个CLK上升沿NEWCLK出现一个跳变,当我们用软件仿真的时候根本看不到30000个输入信号的上升沿(除非你是超人)  ,所以我们需要减小分频系数,但是注意在硬件时候我们还是需要30000分频的,这时候注释的作用就体现出来了。当软件仿真使用分频系数小的,当硬件仿真的时候使用30000分频。

 4.4   顶层文件波形仿真

注意一点:其中CLK2的周期要大于等于8倍的CLK1,这是为什么呢?

答案是:数码管要八个,你需要八个都能点亮的状态,有人会说“哎,小数点不是不用全部点亮么”(小数点也要数码管是一直点亮的状态的,只是不显示数字,而是显示小数点),如果周期小于8倍会出现动态显示的效果,达不到我们所需要的数字秒表效果。

最后:如果需要人数较多,我会对项目进行一个开源,如果对你有用,请给一个点赞,多谢!

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐