资源描述
《EDA课程设计》
实验报告
多功能数字钟
姓 名:
学 号:
联系方式:
成 绩:
1.摘要
在当代,随着人类社会进入到高度发达的信息化社会。信息技术的发展起着越来越大的作用,它几乎涉及到我们日常生活的每个领域,可以说要衡量一个当今社会的发展文明程度信息化技术的发展程度是一个非常重要的指标。众所周知,信息化社会的发展离不开电子信息技术产品的开发、产品品质的提高和改善。电子信息产品随着科学技术的进步,其电子器件和设计方法更新、换代的速度快的惊人,几乎是日新月异。然而实现这种进步的主要原因就是电子设计技术和电子制造技术的发展,其核心就是电子设计自动化(EDA,Electronics Design Automation)技术,EDA技术的发展和推广应用又极大地推动了电子信息产业的发展。为保证电子系统设计的速度和质量,适应“第一时间推出产品”的设计要求,EDA技术正逐渐成为不可缺少的一项先进技术和重要工具。目前,在国内电子技术教学和产业界的技术推广中已形成“EDA热”,完全可以说,掌握EDA技术是电子信息类专业学生、工程技术人员所必备的基本能力和技能。
由于基于PLD的EDA技术的发展和应用领域的扩大和深入,EDA技术在电子信息、通信、自动控制及计算机应用领域的重要性日益提高。
EDA技术在电子系统设计领域越来越普及,本设计主要利用VHDL语言在EDA平台上设计一个电子数字钟,它的计时为24小时小时制,显示满刻度为23时59分59秒,另外还具有校时功能和闹钟功能。总的程序由几个各具不同功能的单元模块程序拼接而成,其中包括分频程序模块,时、分、秒计数和校时程序模块、数据选择器程序模块、显示程序模块和例化程序模块。并且使用QUARTUS II软件进行电路波形仿真,下载到EDA实验箱进行验证。
作为现在的大学生应熟练掌握这门技术,为以后的发展打下良好的基础,本实验设计是应用QuartusII环境及VHDL语言设计一个时间可调的数字时钟。使自己熟练使用QuartusII环境来进行设计,掌握VHDL语言的设计方法。注重理论与实践之间的不同,从而培养自己的实践能力!
关键字:EDA,数字钟,QUARTUS II,VHDL,PLD,模块化,分频,校时,仿真,
2.概括
多功能数字钟应该具有的功能有:显示时-分-秒、整点报时、小时和分钟可调等基本功能。首先要知道钟表的工作机理,整个钟表的工作应该是在1Hz信号的作用下进行,这样每来一个时钟信号,秒增加1秒,当秒从59秒跳转到00秒时,分钟增加1分,同时当分钟从59分跳转到00分时,小时增加1小时,但是需要注意的是,小时的范围是从0~23时。
在实验中为了显示的方便,由于分钟和秒钟显示的范围都是从0~59,所以可以用一个3位的二进制码显示十位,用一个四位的二进制码(BCD码)显示个位,对于小时因为它的范围是从0~23,所以可以用一个2位的二进制码显示十位,用4位二进制码(BCD码)显示个位。
实验中由于七段码管是扫描的方式显示,所以虽然时钟需要的是1Hz时钟信号,但是扫描确需要一个比较高频率的信号,因此为了得到准确的1Hz信号,必须对输入的系统时钟进行分频。
对于整点报时功能,用户可以根据系统的硬件结构和自身的具体要求来设计。
本验设计的是当进行整点的倒计时5秒时,让LED来闪烁进行整点报时的提示。
要求显示格式为 小时-分钟-秒钟,整点报时,报时时间为5秒,即从整点前5秒钟开始进行报时提示,LED开始闪烁,过整点后,停止闪烁。系统时钟选择时钟模块的10KHz,要得到1Hz时钟信号,必须对系统时钟进行10,000次分频。调整时间的的按键用按键模块的S1和S2,S1调节小时,每按下一次,小时增加一个小时,S2调整分钟,每按下一次,分钟增加一分钟。另外用S12按键作为系统时钟复位,复位后全部显示00-00-00。
3.总体原理
3.1功能概括
本实验是通过编程实现多功能的数字时钟,其功能包含了基本的时间显示部分(由00—00—00至23—59—59)的基本显示部分;同时期附带有清零(RES)按键功能(这里用F12表示),当 按下F12是所有的数字清零(00—00—00);此外还有整点报时功能模块,当时间还有5秒到达正点的时候通过指示灯的闪烁以及蜂鸣器的发生实现报时的功能;此外,还具有小时,分钟的调节功能(这里用S1,S2分别表示小时和分钟的调节),当按下S1一次的时候小时显示的数字增加‘1’(直至23后清零00),当按下S2一次的时候分钟上面的数字增加‘1’(直至59后归零00);
3.2功能结构图
a.本实验是采用功能分块的模式,通过不同的功能模块的组合,最终实验本实验的功能要求。
时显示器
秒显示器
分显示器
时译码器
秒译码器
分译码器
报时/闹钟
时计数器
分计数器
秒计数器
校时电路
1Hz
5HZ
分频器
振荡器
图1 数字钟的系统框图
b.图为基本功能结构图
c.七段数码管是电子开发过程中常用的输出显示设备。在实验系统中使用的是两个四位一体、共阴极型七段数码管。其单个静态数码管如下图所示。
静态七段数码管
由于七段数码管公共端连接到GND(共阴极型),当数码管的中的那一个段被输入高电平,则相应的这一段被点亮。反之则不亮。四位一体的七段数码管在单个静态数码管的基础上加入了用于选择哪一位数码管的位选信号端口。八个数码管的a、b、c、d、e、f、g、h、dp都连在了一起,8个数码管分别由各自的位选信号来控制,被选通的数码管显示数据,其余关闭。
3.3设计的基本要求及基本参数
系统时钟选择时钟模块的10KHz,要得到1Hz时钟信号,必须对系统时钟进行10,000次分频。从而的到需要的1s的信号。本实验中,所用到的秒,分,时的计时都是采用4位二进制的计数器进行设计计时的。通过设置不同的范围实现对7段数码管的显示设定。
4具体功能分块实现及介绍
4.1分频功能模块(这里将所有用到的端口名在此同时给出)
实现该功能是通过对系统的自身的1kHZ的信号的采用10000次的分频从而获得1s的所需要的信号。
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY LG IS
PORT( Clk : IN STD_LOGIC; --时钟输入
S12 : IN STD_LOGIC; --复位输入
S1,S2 : IN STD_LOGIC; --时间调节输入
spk : OUT STD_LOGIC;
led : OUT STD_LOGIC_VECTOR(3 DOWNTO 0); --整点输报时输出
Display : OUT STD_LOGIC_VECTOR(7 DOWNTO 0); --七段码管显示输出
SEG_SEL : BUFFER STD_LOGIC_VECTOR(2 DOWNTO 0) --七段码管扫描动
);
END LG;
ARCHITECTURE ART OF LG IS
SIGNAL Disp_Temp : STD_LOGIC_VECTOR(3 DOWNTO 0);
SIGNAL Disp_Decode : STD_LOGIC_VECTOR(7 DOWNTO 0);
SIGNAL SEC1,MIN1, : STD_LOGIC_VECTOR(3 DOWNTO 0);
SIGNAL SEC10,MIN10 : STD_LOGIC_VECTOR(3 DOWNTO 0);
SIGNAL HOUR10 HOUR1 : STD_LOGIC_VECTOR(3 DOWNTO 0);
SIGNAL Music_Count : STD_LOGIC_VECTOR(2 DOWNTO 0);
SIGNAL Clk_Count1 : STD_LOGIC_VECTOR(13 DOWNTO 0); --产生1Hz时钟的分频计数器
SIGNAL Clk1Hz : STD_LOGIC;
SIGNAL led_count : STD_LOGIC_VECTOR(2 DOWNTO 0);
SIGNAL led_display : STD_LOGIC_VECTOR(3 DOWNTO 0);
SIGNAL T : INTEGER RANGE 0 TO 15;
BEGIN
PROCESS(Clk)
BEGIN
IF(Clk'EVENT AND Clk='1') THEN
IF(Clk_Count1<10000) THEN
Clk_Count1<=Clk_Count1+1;
ELSE
Clk_Count1<="00000000000001";
END IF;
END IF;
END PROCESS;
4.2整点报时功能
Clk1Hz<=Clk_Count1(13);
PROCESS(Clk1Hz,S12)
BEGIN
IF(S12='0') THEN --系统复位
SEC1<="0000";
SEC10<="0000";
MIN1<="0000";
MIN10<="0000";
HOUR1<="0000";
HOUR10<="0000";
ELSIF(Clk1Hz'EVENT AND Clk1Hz='1') THEN --正常运行
IF(S1='0') THEN --调节小时
IF(HOUR1="1001") THEN
HOUR1<="0000";
HOUR10<=HOUR10+1;
ELSIF(HOUR10="0010" AND HOUR1="0011") THEN
HOUR1<="0000";
HOUR10<="0000";
ELSE
HOUR1<=HOUR1+1;
END IF;
ELSIF(S2='0') THEN --调节分钟
IF(MIN1="1001") THEN
MIN1<="0000";
IF(MIN10="0101") THEN
MIN10<="0000";
ELSE
MIN10<=MIN10+1;
END IF;
ELSE
MIN1<=MIN1+1;
END IF;
ELSIF(SEC1="1001") THEN
SEC1<="0000";
IF(SEC10="0101") THEN
SEC10<="0000";
IF(MIN1="1001") THEN
MIN1<="0000";
IF(MIN10="0101") THEN
MIN10<="0000";
IF(HOUR1="1001") THEN
HOUR1<="0000";
HOUR10<=HOUR10+1;
ELSIF(HOUR10="0010" AND HOUR1="0011") THEN
HOUR1<="0000";
HOUR10<="0000";
ELSE
HOUR1<=HOUR1+1;
END IF;
ELSE
MIN10<=MIN10+1;
END IF;
ELSE
MIN1<=MIN1+1;
END IF;
ELSE
SEC10<=SEC10+1;
END IF;
ELSE
SEC1<=SEC1+1;
END IF;
END IF;
END PROCESS;
----------------------------------------------------------------------
PROCESS(SEC1,T)
BEGIN
CASE SEC1 IS
WHEN "0000"=>T<=0;
WHEN "0001"=>T<=1;
WHEN "0010"=>T<=2;
WHEN "0011"=>T<=3;
WHEN "0100"=>T<=4;
WHEN "0101"=>T<=5;
WHEN "0110"=>T<=6;
WHEN "0111"=>T<=7;
WHEN "1000"=>T<=8;
WHEN "1001"=>T<=9;
WHEN OTHERS=>T<=0;
END CASE;
END PROCESS;
---------------------------------------------------------------------
PROCESS(Clk,T)
BEGIN
IF(Clk'EVENT AND Clk='1') THEN
Music_Count<=Music_Count+1;
IF(MIN10="0101" AND MIN1="1001" AND SEC10="0101") THEN --在59分50秒开始提示
IF((T MOD 2)=0) THEN --在偶数秒开始发声
SPK<=Music_Count(2); --嘀
ELSE
SPK<='0';
END IF;
ELSIF(MIN10="0000" AND MIN1="0000" AND SEC10="0000" AND SEC1="0000") THEN
SPK<=Music_Count(1); --嗒
ELSE
SPK<='0';
END IF;
END IF;
END PROCESS;
PROCESS(Clk)
BEGIN
IF(Clk1hz'EVENT AND Clk1hz='1') THEN
IF(MIN10="0101" AND MIN1="1001" AND SEC10="0101" AND sec1="0101") THEN --在59分55秒开始提示
led_Count<=led_Count+1;
ELSE
led_count<="000";
END IF;
END IF;
END PROCESS;
4.3复位和时间调节功能
Clk1Hz<=Clk_Count1(13);
PROCESS(Clk1Hz,S12)
BEGIN
IF(S12='0') THEN --系统复位
SEC1<="0000";
SEC10<="0000";
MIN1<="0000";
MIN10<="0000";
HOUR1<="0000";
HOUR10<="0000";
ELSIF(Clk1Hz'EVENT AND Clk1Hz='1') THEN --正常运行
IF(S1='0') THEN --调节小时
IF(HOUR1="1001") THEN
HOUR1<="0000";
HOUR10<=HOUR10+1;
ELSIF(HOUR10="0010" AND HOUR1="0011") THEN
HOUR1<="0000";
HOUR10<="0000";
ELSE
HOUR1<=HOUR1+1;
END IF;
ELSIF(S2='0') THEN --调节分钟
IF(MIN1="1001") THEN
MIN1<="0000";
IF(MIN10="0101") THEN
MIN10<="0000";
4.4时间显示功能
PROCESS(led_count)
BEGIN
CASE (led_count) IS
WHEN "000"=>led_display<="0000";
WHEN "001"=>led_display<="1111";
WHEN "010"=>led_display<="0111";
WHEN "011"=>led_display<="0011";
WHEN "100"=>led_display<="0001";
WHEN "101"=>led_display<="1111";
WHEN OTHERS=>led_display<="0000";
END CASE;
led<=led_display;
END PROCESS;
--------------------------------------------------------------------------
PROCESS(SEG_SEL)
BEGIN
CASE (SEG_SEL+1) IS
WHEN "000"=>Disp_Temp<=HOUR10;
WHEN "001"=>Disp_Temp<=HOUR1;
WHEN "010"=>Disp_Temp<="1010";
WHEN "011"=>Disp_Temp<=MIN10;
WHEN "100"=>Disp_Temp<=MIN1;
WHEN "101"=>Disp_Temp<="1010";
WHEN "110"=>Disp_Temp<=SEC10;
WHEN OTHERS=>Disp_Temp<=SEC1;
END CASE;
END PROCESS;
----------------------------------------------------------------------- --扫描累加
PROCESS(Clk)
BEGIN
IF(Clk'EVENT AND Clk='1') THEN
SEG_SEL<=SEG_SEL+1;
Display<=Disp_Decode;
END IF;
END PROCESS;
--------------------------------------------------------------------------显示转换
PROCESS(Disp_Temp)
BEGIN
CASE Disp_Temp IS
WHEN "0000"=>Disp_Decode<="00111111"; --0
WHEN "0001"=>Disp_Decode<="00000110"; --1
WHEN "0010"=>Disp_Decode<="01011011"; --2
WHEN "0011"=>Disp_Decode<="01001111"; --3
WHEN "0100"=>Disp_Decode<="01100110"; --4
WHEN "0101"=>Disp_Decode<="01101101"; --5
WHEN "0110"=>Disp_Decode<="01111101"; --6
WHEN "0111"=>Disp_Decode<="00000111"; --7
WHEN "1000"=>Disp_Decode<="01111111"; --8
WHEN "1001"=>Disp_Decode<="01101111"; --9
WHEN "1010"=>Disp_Decode<="01000000"; ---
WHEN OTHERS=>Disp_Decode<="00000000"; --全灭
END CASE;
END PROCESS;
END ART;
5.实验总结及心得
通过这次实验是我学习到了许多知识,首先是对EDA课程设计的基本要求以及对实验过程的具体实现方法,其次是对VHDL编程语言的语法掌握和认识有了更加深刻的理解和认识,再次是对QUARTUSII软件的基本操作和工作有了一定的了解和认识,还有就是对实验的过程收获了许多,受益了许多。
经过两周EDA课程设计,使我受益匪浅。这不仅增强了我对EDA设计的兴趣,更巩固了基本的电路设计流程、方法以及技巧。具备了这些基本知识,为今后的自主学习奠定了良好的基础。在编写时可以相互借鉴,这样可以节省一定的时间,但在一个问题上纠结了很久,现还未明白,为什么一个变量在进程中只能被一个边沿信号触发进行修改,无奈之下选择了另一种方法,通过一个控制端来进行选频,以实现快速调时,在闹钟的处理上使用了数据选择,设置闹铃时数码管显示闹钟时间。
在设计中还是需要注意一些常见的问题,比如实体名、项目名等,还有在编写VHDL文件时,一些文件名也是需要注意的;在编写程序的过程中,信号与变量的使用是一个特需要注意的,进程中一个信号不应有多个复制源,信号的复值是在进程结束之时,而变量的复值是立即的,在书写时容易出错的地方是,信号的赋值与变量的赋值符号,信号作为全局的联络线,信号往往不允许在多个进程中被赋值,因为进程之间是并行的。
通过实验也彻底的认识到了自己的不足,以及许多自己有待加强和努力的地方,比如说相关语法的具体实验过程,不同设计的优点分析等。还有就是对自己以后应该学习掌握的知识还有许多,自己懂得的还知识皮毛而已,如果真的要用于实际工程及设计中要走的路还是很长的。
最后在这里要感谢我的指导老师,感谢您的耐心指导和教诲,是您的耐心指导才使得我收获了这么多,学会了很多不懂得知识,掌握了这么多的专业知识,以及这么多有用的专业技巧和处理问题的方法和能力,正式由于您的努力才能帮助我的课程设计顺利的进行并能够最终完成自己的课程设计。在这里要表达我的感激之情以及感恩之意,是您让我又一次的成长了许多,此致敬礼!
6.源程序
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
--------------------------------------------------------------------
ENTITY LG IS
PORT( Clk : IN STD_LOGIC; --时钟输入
S12 : IN STD_LOGIC; --复位输入
S1,S2 : IN STD_LOGIC; --时间调节输入
spk : OUT STD_LOGIC;
led : OUT STD_LOGIC_VECTOR(3 DOWNTO 0); --整点输报时输出
Display : OUT STD_LOGIC_VECTOR(7 DOWNTO 0); --七段码管显示输出
SEG_SEL : BUFFER STD_LOGIC_VECTOR(2 DOWNTO 0) --七段码管扫描驱动
);
END LG;
--------------------------------------------------------------------
ARCHITECTURE ART OF LG IS
SIGNAL Disp_Temp : STD_LOGIC_VECTOR(3 DOWNTO 0);
SIGNAL Disp_Decode : STD_LOGIC_VECTOR(7 DOWNTO 0);
SIGNAL SEC1,MIN1, : STD_LOGIC_VECTOR(3 DOWNTO 0);
SIGNAL SEC10,MIN10 : STD_LOGIC_VECTOR(3 DOWNTO 0);
SIGNAL HOUR10 HOUR1 : STD_LOGIC_VECTOR(3 DOWNTO 0);
SIGNAL Music_Count : STD_LOGIC_VECTOR(2 DOWNTO 0);
SIGNAL Clk_Count1 : STD_LOGIC_VECTOR(13 DOWNTO 0); --产生1Hz时钟的分频计数器
SIGNAL Clk1Hz : STD_LOGIC;
SIGNAL led_count : STD_LOGIC_VECTOR(2 DOWNTO 0);
SIGNAL led_display : STD_LOGIC_VECTOR(3 DOWNTO 0);
SIGNAL T : INTEGER RANGE 0 TO 15;
BEGIN
PROCESS(Clk)
BEGIN
IF(Clk'EVENT AND Clk='1') THEN
IF(Clk_Count1<10000) THEN
Clk_Count1<=Clk_Count1+1;
ELSE
Clk_Count1<="00000000000001";
END IF;
END IF;
END PROCESS;
----------------------------------------------------------------------------------
Clk1Hz<=Clk_Count1(13);
PROCESS(Clk1Hz,S12)
BEGIN
IF(S12='0') THEN --系统复位
SEC1<="0000";
SEC10<="0000";
MIN1<="0000";
MIN10<="0000";
HOUR1<="0000";
HOUR10<="0000";
ELSIF(Clk1Hz'EVENT AND Clk1Hz='1') THEN --正常运行
IF(S1='0') THEN --调节小时
IF(HOUR1="1001") THEN
HOUR1<="0000";
HOUR10<=HOUR10+1;
ELSIF(HOUR10="0010" AND HOUR1="0011") THEN
HOUR1<="0000";
HOUR10<="0000";
ELSE
HOUR1<=HOUR1+1;
END IF;
ELSIF(S2='0') THEN --调节分钟
IF(MIN1="1001") THEN
MIN1<="0000";
IF(MIN10="0101") THEN
MIN10<="0000";
ELSE
MIN10<=MIN10+1;
END IF;
ELSE
MIN1<=MIN1+1;
END IF;
ELSIF(SEC1="1001") THEN
SEC1<="0000";
IF(SEC10="0101") THEN
SEC10<="0000";
IF(MIN1="1001") THEN
MIN1<="0000";
IF(MIN10="0101") THEN
MIN10<="0000";
IF(HOUR1="1001") THEN
HOUR1<="0000";
HOUR10<=HOUR10+1;
ELSIF(HOUR10="0010" AND HOUR1="0011") THEN
HOUR1<="0000";
HOUR10<="0000";
ELSE
HOUR1<=HOUR1+1;
END IF;
ELSE
MIN10<=MIN10+1;
END IF;
ELSE
MIN1<=MIN1+1;
END IF;
ELSE
SEC10<=SEC10+1;
END IF;
ELSE
SEC1<=SEC1+1;
END IF;
END IF;
END PROCESS;
----------------------------------------------------------------------
PROCESS(SEC1,T)
BEGIN
CASE SEC1 IS
WHEN "0000"=>T<=0;
WHEN "0001"=>T<=1;
WHEN "0010"=>T<=2;
WHEN "0011"=>T<=3;
WHEN "0100"=>T<=4;
WHEN "0101"=>T<=5;
WHEN "0110"=>T<=6;
WHEN "0111"=>T<=7;
WHEN "1000"=>T<=8;
WHEN "1001"=>T<=9;
WHEN OTHERS=>T<=0;
END CASE;
END PROCESS;
---------------------------------------------------------------------
PROCESS(Clk,T)
BEGIN
IF(Clk'EVENT AND Clk='1') THEN
Music_Count<=Music_Count+1;
IF(MIN10="0101" AND MIN1="1001" AND SEC10="0101") THEN --在59分50秒开始提示
IF((T MOD 2)=0) THEN --在偶数秒开始发声
SPK<=Music_Count(2); --嘀
ELSE
展开阅读全文