资源描述
课 程 设 计 报 告 书
所属课程名称 《EDA技术及应用》课程设计
题 目 数字闹钟系统设计
分 院
专业班级 15级电信1班
学 号
学生姓名
指导教师
20 18 年 1 月 8 日
课 程 设 计( 论 文 )任 务 书
一、课程设计(论文)题目 数字闹钟系统设计
二、课程设计(论文)工作:自 2018 年1 月 8 日起至 2018 年 1 月 10 日止。
三、课程设计(论文)的内容要求:
设计一个24小时制的数字闹钟,该数字闹钟包括几个组成部分:
(1)显示屏:由7段数码管组成;
(2)YES(确认)键:用于输入新的时间或新的闹钟时间;
(3)TIME(时间)键;用于确定新的时间设置;
(4)ALARM(闹钟)键:用于确定新的闹钟时间设置或显示已设置的闹钟时间;
(5)扬声器:在当前时钟时间与闹钟时间相同时,发出蜂鸣声;
目 录
第1章 课程设计内容及要求...................................
第2章 程序设计目的..........................................
第3章 程序实现思路..........................................
第4章 程序清单(或正文)..................................
第5章 课程设计心得..........................................
第6章 参考文献(资料).....................................
第2章 程序设计目的
随着EDA技术的发展和应用领域的扩大与深入,EDA技术在电子信息、通信、自动控制及计算机应用领域的重要性日益突出。EDA技术就是依赖功能强大的计算机,在EDA工具软件平台上,对以硬件描述语言VHDL为系统逻辑描述手段完成的设计文件,自动地完成逻辑优化和仿真测试,直至实现既定的电子线路系统功能。本课设基于VHDL硬件描述语言并选用合适的可编程逻辑器件设计一个24小时制的数字闹钟的思路和技巧。在max+plus2开发环境中编译和仿真了所设计的程序,并逐一调试验证程序的运行状况。仿真和验证的结果表明,该设计方法切实可行,该数字闹钟可以实现调时定时闹钟功能具有一定的实际应用性。
第3章 程序实现思路
根据该数字闹钟的设计要求,可得到其外部端口如图。
各个输入/输出端口的作用如下:
1)CLK为外部时钟信号,RESET为复位信号。
2)当YES为高电平,表示用户选择了某个与置数字。
3)当TIME_BUTTON为高电平时,表示用户按下TIME键。
(5)SEG7是数据动态扫描显示的公共七段数码显示管驱动端;LEDW是数码管的位选
择端,它经过外接的3-8译码器译码后接数码管的公共端COM
(6) SOUND ALARM用于控制扬声器发声,当 SOUND ALARM=1时,扬声器发出
蜂鸣,表示到了设定的闹钟时间。
根据系统的设计要求,整个系统可分为闹钟控制器、预置寄存器、分频电路、时间计数
器、闹钟寄存器、显示驱动控制器等6个模块,各个模块的作用介绍如下
(1)闹钟控制器( CONTROL):它是整个系统正常有序工作的核心,按设计要求产生相
应的控制逻辑,控制其他各部分的协调工作。
(2)预置寄存器( KEYBUFFER):这时一个预置数字产生器和移位寄存器的结合体。
通过对YES进行操作,选择欲输入的数字;暂存用户输入的数字,并且用户每输入一个数
字,暂存数字移位一次,实现用户输入的数字在显示器上从右到左的依次显示
(3)分频电路( DIVIDER):将较高速的外部时钟频率分频成每秒一次的时钟频率,以便
进行时钟计数
(4)时间计数器( OUNTER):这实际上是一个异步复位、异步置数的累加器,通常情
况下进行时钟累加计数,必要时可置入新的时钟值,然后从该值开始新的计数
(5)闹钟寄存器(REG):用于保存用户设置的闹钟时间,是一个异步复位寄存器。
(6)显示驱动器( DRIVER):根据需要显示当前时间、用户设置的闹钟时间或用户输入
的预置时间,同时判断当前时间是否已到了闹钟时间,这实际上是一个多路选择器和比较器
的结合体。具体数据的显示采用的是动态扫描显示方式。
第4章 程序清单或正文
1)程序包P_ALARM:
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
PACKAGE P_ALARM IS
SUBTYPE T_DIGITAL IS INTEGER RANGE 0 TO 9;
SUBTYPE T_SHORT IS INTEGER RANGE 0 TO 65535;
TYPE T_CLOCK_TIME IS ARRAY (5 DOWNTO 0) OF T_DIGITAL;
TYPE T_DISPLAY IS ARRAY (5 DOWNTO 0) OF T_DIGITAL;
END PACKAGE P_ALARM;
2)闹钟控制器外部端口(程序及图):
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE WORK.P_ALARM.ALL;
ENTITY CONTROL IS
PORT ( KEY: IN STD_LOGIC;
ALARM_BUTTON:IN STD_LOGIC;
TIME_BUTTON:IN STD_LOGIC;
CLK:IN STD_LOGIC;
RESET:IN STD_LOGIC;
LOAD_NEW_A:OUT STD_LOGIC;
LOAD_NEW_C:OUT STD_LOGIC;
SHOW_NEW_TIME:OUT STD_LOGIC;
SHOW_A:OUT STD_LOGIC);
END ENTITY CONTROL;
ARCHITECTURE BEHAVE OF CONTROL IS
TYPE T_STATE IS(S0,S1,S2,S3,S4) ;
CONSTANT KEY_TIMEOUT:T_SHORT:=500;
CONSTANT SHOW_ALARM_TIMEOUT:T_SHORT:=500;
SIGNAL CURR_STATE:T_STATE;
SIGNAL NEXT_STATE:T_STATE;
SIGNAL COUNTER_K:T_SHORT;
SIGNAL ENABLE_COUNT_K:STD_LOGIC;
SIGNAL COUNT_K_END:STD_LOGIC ;
SIGNAL COUNTER_A:T_SHORT;
SIGNAL ENABLE_COUNT_A:STD_LOGIC ;
SIGNAL COUNT_A_END:STD_LOGIC;
BEGIN
PROCESS(CLK,RESET) IS
BEGIN
IF RESET ='1' THEN
CURR_STATE<= S0;
ELSIF RISING_EDGE(CLK) THEN
CURR_STATE<= NEXT_STATE;
END IF;
END PROCESS;
PROCESS (KEY,ALARM_BUTTON,TIME_BUTTON,CURR_STATE,
COUNT_A_END,COUNT_K_END )
BEGIN
NEXT_STATE<=CURR_STATE;
LOAD_NEW_A<='0';
LOAD_NEW_C<='0';
SHOW_A <='0';
SHOW_NEW_TIME<='0';
ENABLE_COUNT_K<='0';
ENABLE_COUNT_A <='0';
CASE CURR_STATE IS
WHEN S0=>IF (KEY='0') THEN
NEXT_STATE<= S1;
SHOW_NEW_TIME<='1';
ELSIF (ALARM_BUTTON='1') THEN
NEXT_STATE<= S4;
SHOW_A<='1';
ELSE
NEXT_STATE<= S0;
END IF;
WHEN S1=>IF(KEY='1') THEN
NEXT_STATE<= S1;
ELSIF (ALARM_BUTTON ='1') THEN
NEXT_STATE<= S2;
LOAD_NEW_A<='1';
ELSIF (TIME_BUTTON ='1') THEN
NEXT_STATE<= S3;
LOAD_NEW_C <='1';
ELSE
IF (COUNT_K_END='1') THEN
NEXT_STATE<= S0;
ELSE
NEXT_STATE<= S1;
END IF ;
ENABLE_COUNT_K<='1';
END IF ;
SHOW_NEW_TIME<='1';
WHEN S2=>IF (ALARM_BUTTON ='1') THEN
NEXT_STATE<=S2;
LOAD_NEW_A <='1';
ELSE
NEXT_STATE<= S0;
END IF ;
WHEN S3 =>IF (TIME_BUTTON ='1') THEN
NEXT_STATE<=S3;
LOAD_NEW_C<='1';
ELSE
NEXT_STATE<= S0;
END IF;
WHEN S4=>IF(KEY='1') THEN
NEXT_STATE<= S1;
ELSE
NEXT_STATE<=S4;
IF (COUNT_A_END ='1') THEN
NEXT_STATE<= S0;
ELSE
NEXT_STATE<= S4;
SHOW_A<='1';
END IF ;
ENABLE_COUNT_A <='1';
END IF;
WHEN OTHERS=>NULL;
END CASE;
END PROCESS;
COUNT_KEY:PROCESS(ENABLE_COUNT_K,CLK) IS
BEGIN
IF (ENABLE_COUNT_K ='0') THEN
COUNTER_K<=0;
COUNT_K_END<='0';
ELSIF (RISING_EDGE(CLK)) THEN
IF (COUNTER_K >=KEY_TIMEOUT) THEN
COUNT_K_END<='1';
ELSE
COUNTER_K<=COUNTER_K + 1;
END IF;
END IF;
END PROCESS;
COUNT_ALARM:PROCESS(ENABLE_COUNT_A,CLK) IS
BEGIN
IF (ENABLE_COUNT_A ='0') THEN
COUNTER_A<=0;
COUNT_A_END<='0';
ELSIF RISING_EDGE(CLK) THEN
IF( COUNTER_A>=SHOW_ALARM_TIMEOUT) THEN
COUNT_A_END<='1';
ELSE
COUNTER_A<= COUNTER_A + 1;
END IF;
END IF;
END PROCESS;
END ARCHITECTURE BEHAVE;
3)预设寄存器(程序及图):
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL ;
USE WORK.P_ALARM.ALL ;
ENTITY KEYBUFFER IS
PORT (KEY:IN STD_LOGIC;
CLK:IN STD_LOGIC;
RESET:IN STD_LOGIC;
KEYNUM:OUT STD_LOGIC_VECTOR(3 DOWNTO 0 );
NEW_TIME:OUT T_CLOCK_TIME);
END ENTITY KEYBUFFER;
ARCHITECTURE BEHAVE OF KEYBUFFER IS
SIGNAL N_T:T_CLOCK_TIME;
SIGNAL CNT:STD_LOGIC_VECTOR(3 DOWNTO 0);
SIGNAL TEMP:T_DIGITAL;
BEGIN
PROCESS (CLK) IS
BEGIN
IF (CLK'EVENT AND CLK = '1') THEN
IF CNT =9 THEN
CNT <= "0000" ;
ELSE
CNT<= CNT+'1';
END IF;
END IF;
TEMP<= CONV_INTEGER(CNT);
KEYNUM <= CNT;
END PROCESS;
SHIFT:PROCESS(RESET,KEY) IS
BEGIN
IF (RESET ='1') THEN
N_T(5)<= 0;
N_T(4)<= 0;
N_T(3)<= 0;
N_T(2)<= 0;
N_T(1)<= 0;
N_T(0)<= 0;
ELSIF (KEY'EVENT AND KEY='1') THEN
FOR I IN 5 DOWNTO 1 LOOP
N_T(I)<= N_T(I-1);
END LOOP;
N_T(0)<= TEMP;
END IF;
END PROCESS;
NEW_TIME<= N_T;
END ARCHITECTURE BEHAVE;
4)闹钟寄存器(程序及图):
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE WORK.P_ALARM.ALL;
ENTITY REG IS
PORT (NEW_ALARM_TIME:IN T_CLOCK_TIME;
LOAD_NEW_A:IN STD_LOGIC;
CLK:IN STD_LOGIC;
RESET:IN STD_LOGIC;
ALARM_TIME:OUT T_CLOCK_TIME);
END ENTITY REG;
ARCHITECTURE BEHAVE OF REG IS
BEGIN
PROCESS (CLK,RESET) IS
BEGIN
IF RESET='1' THEN
ALARM_TIME(0)<=0;
ALARM_TIME(1)<= 0;
ALARM_TIME(2)<= 0;
ALARM_TIME(3)<= 0;
ALARM_TIME(4)<= 0;
ALARM_TIME(5)<= 0;
ELSE
IF RISING_EDGE(CLK) THEN
IF LOAD_NEW_A ='1' THEN
ALARM_TIME<= NEW_ALARM_TIME;
END IF;
END IF;
END IF;
END PROCESS;
END ARCHITECTURE BEHAVE;
5)分频器(程序及图):
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE WORK.P_ALARM.ALL;
ENTITY DIVIDER IS
PORT(CLK_IN: IN STD_LOGIC;
RESET: IN STD_LOGIC;
CLK_OUT: OUT STD_LOGIC);
END ENTITY DIVIDER;
ARCHITECTURE BEHAVE OF DIVIDER IS
CONSTANT DIVIDE_PERIOD: T_SHORT:=6000;
BEGIN
PROCESS(CLK_IN,RESET) IS
VARIABLE CNT: T_SHORT;
BEGIN
IF (RESET='1') THEN
CNT:=0;
CLK_OUT<='0';
ELSIF RISING_EDGE(CLK_IN) THEN
IF (CNT<=(DIVIDE_PERIOD/2)) THEN
CLK_OUT<='1';
CNT:=CNT+1;
ELSIF (CNT<(DIVIDE_PERIOD-1)) THEN
CLK_OUT<='0';
CNT:=CNT+1;
ELSE
CNT:=0;
END IF;
END IF;
END PROCESS;
END ARCHITECTURE BEHAVE;
6)时间计数器(程序及图):
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE WORK.P_ALARM.ALL;
ENTITY COUNTER IS
PORT (NEW_CURRENT_TIME:IN T_CLOCK_TIME;
LOAD_NEW_C,CLK,RESET:IN STD_LOGIC;
CURRENT_TIME:OUT T_CLOCK_TIME );
END ENTITY COUNTER;
ARCHITECTURE BEHAVE OF COUNTER IS
SIGNAL I_CURRENT_TIME:T_CLOCK_TIME;
BEGIN
PROCESS(CLK,RESET,LOAD_NEW_C) IS
VARIABLE C_T:T_CLOCK_TIME;
BEGIN
IF RISING_EDGE(CLK) THEN
IF RESET ='1' THEN
I_CURRENT_TIME(5)<= 0;
I_CURRENT_TIME(4)<= 0;
I_CURRENT_TIME(3)<= 0;
I_CURRENT_TIME(2)<= 0;
I_CURRENT_TIME(1)<= 0;
I_CURRENT_TIME(0)<= 0;
ELSIF LOAD_NEW_C ='1' THEN
I_CURRENT_TIME<= NEW_CURRENT_TIME;
ELSE
C_T:= I_CURRENT_TIME;
IF C_T(0)<9 THEN
C_T(0):= C_T(0)+1;
ELSE
C_T(0):= 0;
IF C_T(1)<5 THEN
C_T(1):= C_T(1)+1 ;
ELSE
C_T (1):= 0;
IF C_T(2)<9 THEN
C_T(2):=C_T(2)+1;
ELSE
C_T(2):= 0 ;
IF C_T(3)<5 THEN
C_T(3):= C_T(3)-1;
ELSE
C_T(3):=0;
IF C_T(5)<2 THEN
IF C_T(4)<9 THEN
C_T(4):= C_T(4)+1 ;
ELSE
C_T(4):= 0 ;
C_T(5):=C_T(5)+1;
END IF;
ELSE
IF C_T(4)<3 THEN
C_T(4):=C_T(4)+1;
ELSE
C_T(4):= 0;
C_T(5):=0;
END IF;
END IF;
END IF;
END IF;
END IF;
I_CURRENT_TIME<=C_T;
END IF;
I_CURRENT_TIME<=C_T;
END IF;
END IF;
END PROCESS;
CURRENT_TIME<=I_CURRENT_TIME;
END ARCHITECTURE BEHAVE;
7)显示驱动(程序及图):
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
USE WORK.P_ALARM.ALL;
ENTITY DRIVER IS
PORT (KEYNUM:IN STD_LOGIC_VECTOR(3 DOWNTO 0);
CLK:IN STD_LOGIC;
ALARM_TIME:IN T_CLOCK_TIME ;
CURRENT_TIME:IN T_CLOCK_TIME;
NEW_TIME:IN T_CLOCK_TIME;
SHOW_NEW_TIME:IN STD_LOGIC;
SHOW_A:IN STD_LOGIC;
SOUND_ALARM:OUT STD_LOGIC;
LEDW:OUT STD_LOGIC_VECTOR(2 DOWNTO 0);
SEG7:OUT STD_LOGIC_VECTOR(7 DOWNTO 0));
END ENTITY DRIVER;
ARCHITECTURE BEHAVE OF DRIVER IS
SIGNAL DISPLAY_TIME:T_CLOCK_TIME;
SIGNAL TEMP:INTEGER RANGE 0 TO 9;
SIGNAL CNT:STD_LOGIC_VECTOR(2 DOWNTO 0);
BEGIN
PROCESS (ALARM_TIME,CURRENT_TIME,SHOW_A,SHOW_NEW_TIME) IS
BEGIN
SOUND_LP:FOR I IN ALARM_TIME'RANGE LOOP
IF NOT(ALARM_TIME(I)= CURRENT_TIME(I)) THEN
SOUND_ALARM <='0';
ELSE
SOUND_ALARM <='1';
END IF;
END LOOP SOUND_LP;
IF SHOW_NEW_TIME ='1' THEN
DISPLAY_TIME<=NEW_TIME;
ELSIF SHOW_A='1' THEN
DISPLAY_TIME<=ALARM_TIME;
ELSIF SHOW_A='0' THEN
DISPLAY_TIME<=CURRENT_TIME;
END IF;
END PROCESS;
PROCESS (CLK) IS
BEGIN
IF CLK'EVENT AND CLK ='1' THEN
IF CNT="111" THEN
CNT<="000";
ELSE
CNT<= CNT+'1';
END IF ;
END IF;
END PROCESS;
LEDW<= CNT;
PROCESS(CNT)
BEGIN
CASE CNT IS
WHEN "000"=>TEMP<=DISPLAY_TIME(0);
WHEN "001"=>TEMP<=DISPLAY_TIME(1);
WHEN "010"=>TEMP<=DISPLAY_TIME(2);
WHEN "011"=>TEMP<=DISPLAY_TIME(3);
WHEN "100"=>TEMP<=DISPLAY_TIME(4);
WHEN "101"=>TEMP<=DISPLAY_TIME(5);
WHEN "111"=>TEMP<=CONV_INTEGER (KEYNUM);
WHEN OTHERS =>TEMP<= 0;
END CASE;
CASE TEMP IS
WHEN 0=>SEG7<="00111111";
WHEN 1=>SEG7<="00000110";
WHEN 2=>SEG7<="01011011";
WHEN 3=>SEG7<="01001111";
WHEN 4=>SEG7<="01100110";
WHEN 5=>SEG7<="01101101";
WHEN 6=>SEG7<="01111101";
WHEN 7=>SEG7<="00000111";
WHEN 8=>SEG7<="01111111";
WHEN 9=>SEG7<="01101111";
WHEN OTHERS=>SEG7<="00111111";
END CASE;
END PROCESS;
9)闹钟系统顶层原理图
第5章 课程设计心得
通过这次课程设计使我懂得了理论与实际相结合是很重要的,只有理论知识是远远不够的,只有把所学的理论知识与实践相结合起来,从理论中得出结论,才能真正为社会服务,从而提高自己的实际动手能力和独立思考的能力。在设计的过程中遇到问题,可以说得是困难重重,这毕竟第一次做的,难免会遇到过各种各样的问题,同时在设计的过程中发现了自己的不足之处,对以前所学过的知识理解得不够深刻,掌握得不够牢固。
第6章 参考文献(资料)
[1] 蒋小燕,俞伟钓,张立臣 EDA技术及VHDL 南京:东南大学出版社 2016
致 谢
《EDA技术及应用》课程设计 第 21 页 共 21 页
展开阅读全文