数电课程设计报告.docx
《数电课程设计报告.docx》由会员分享,可在线阅读,更多相关《数电课程设计报告.docx(32页珍藏版)》请在冰豆网上搜索。
数电课程设计报告
数字电子技术课程设计
设计题目:
数字电子钟设计
姓名:
学号:
班级:
2013级自动化
指导教师:
刘兰军、周丽芹、陈家林
摘要
本论文是关于数字电子钟的设计的研究,数字电子钟主要实现计时功能、校时功能、整点报时功能、闹钟功能。
数字电子钟设计是基于QuartusII仿真设计通过VHDL语言编程的电子钟电路,其中包含了计时显示模块、校时模块、秒表模块、闹钟模块、整点报时模快等五个模块。
计时模块是整个电子钟的核心模块,其余几个模块都是基于计时模块来完成工作;计时模块是把由振荡器产生的脉冲经过分频器后的脉冲作为时钟周期,然后通过两个60进制和一个24进制的计数器来是实现计时。
通过VHDL语言和搭建电路实现上述各个模块的功能,对每个模块进行仿真,确保每个模块完全正确后。
将顶层设计图下载到FPGA开发板上,通过调试和修改,实现电子钟的功能。
关键词:
分频器;时钟周期;累加器;FPGA;QuartusII
目录
摘要2
1设计指标4
1.1基本要求4
1.2提高要求4
2方案论证5
2.1方案设计图5
2.2电路联系框图6
3设计实现6
3.1分频模块6
3.2消抖模块8
3.3秒表模块9
3.4闹钟、整点报时模块10
3.5显示模块12
4设计验证13
4.1蜂鸣器仿真波形13
4.2分频器功能仿真13
4.3.秒表功能仿真13
4.4按键模块输入输出波形仿真14
4.5Led数码管显示部分:
14
5设计总结15
5.1系统实现的功能15
5.2展望15
参考文献16
附录17
1附顶层原理图17
2分频17
3消抖19
4显示20
5译码24
6闹钟25
7模式选择26
8秒表27
1设计指标
1.1基本要求
数字电子钟要具备的基本功能:
1.计时功能—正常的星期、时、分、秒计时,并由7只8段数码管分别显示;
2.校时功能---任意设置时钟的星期、时、分、秒,被设置项在设置时闪烁。
长按按键时,被设置项迅速增加;
3.整点报时功能----当计时达到59分53秒时开始报时,蜂鸣器频率为2Hz,当到达59分59秒时,蜂鸣器频率为1kHz。
半点报时----当计时达到30分00秒时,蜂鸣器频率2Hz。
4.闹钟功能----设置任意时间,时钟到达时,闹钟功能开启。
5.秒表功能----通过功能键切换进入秒表功能时,按start键后,开始以ms为单位进行计时,并在数码管显示。
1.2提高要求
除了电子钟具备的一般功能外,还应具备以下提高功能:
1.数字钟有上午、下午之分,计“时”范围调整为00至11;
2.实现万年历功能。
3.不显示高位无效零。
2方案论证
2.1方案设计图
图1
图1是整个电子钟设计的方案图。
根据系统框图我们就可以大致明白整个电子钟的设计流程。
从上图中我们可以看出,首先我们将系统时钟信号经过分频模块,分出所需的频率。
然后在将分出的频率作为每个模块的时钟信号,使每个模块进行工作。
看似电子钟各个模块相互独立,其实他们都存在内在的联系。
通过这个较为完整的设计方案图,我们便可以进行电子钟的顶层设计,再进行各个模块的编程。
最后通过仿真、调试便可实现电子钟的相应功能。
系统时钟提供50mhz的信号以后,通过分频电路产生不同频率的信号分别用于正常计时的秒单位,秒表的毫秒单位,动态数码管扫描,以及蜂鸣器发生,通过消抖以后的按键控制功能的选择;时间进制,分别采用不同进制的计数器,实现正常时间的显示;万年历,先赋予一个初始的时间,再将正常时间的时的进位赋给万年历的天,实现时间的加减;校时部分通过按键控制位选,以及单加连加;整点报时半点报时部分基本原理相同,将闹钟设定的时间,或者整点时间,半点时间,存储于存储器当中,再与当前正常显示时间进行比较,如果相同则蜂鸣器报时。
2.2电路联系框图
闹钟模块
模式选择模块
计时模块
秒表模块
显示模块
分频模块
图2
图2是各个模块之间的联系框图。
通过模式选择模块来控制计时模块的工作,最开始的时候是最基本的计时电路,然后就是校时模式,在然后是闹钟模式,最后是秒表模式。
而分频模块跟每个电路模块都有关系,在此我就没有将其与其他模块一起连接起来。
计时模块输出BCD码给显示模块,再在编码之后来控制数码管的显示。
秒表模式是当切到了秒表模式就开始计时。
闹钟模式类似于校时模式,当调好闹钟时间后,转换模式就是表示已经输入了闹钟时间。
3设计实现
3.1分频模块
图3
图3为分频模块的顶层图,输入的clk为50MHZ的系统时钟频率,通过分频模块,可以分成1KHZ、100HZ、10HZ、2HZ、1HZ的频率。
这几种不同的频率将会为不同的模块提供时钟信号。
50MHZ分频为1HZ的流程图可表示如下,其他的分频类似。
如果要分出其他频率信号,只需要改变计算值的临界值即可,通过改变计数临界值就可以获得不同的频率。
3.2消抖模块
图4
图4为消抖模块的顶层路图。
按键在按下时会产生抖动,释放时也会产生抖动,所以在设计键盘扫描程序时必须考虑按键的消抖,一般只考虑按下时的抖动,而放弃对释放时抖动的消抖。
抖动时间一般为20ms左右。
按下的最终结果是低电平。
按键按下时会有抖动,也就是说我们其实只按一次,但是实际产生的“按下”却是许多次的,这些许多次集中在这20ms里。
按的只是一次,而实际却产生了许多次,那么就必须滤除其他的次数。
为了得到真正的“按下”,通过延时20ms,把其他的“按下”(也就是抖动)给滤除了。
然后再次判断是否有按下。
在FPGA中,程序里检测按键是否按下的方法是脉冲边沿检法。
FPGA过20ms检测按键是否按下,存储检测到的值,并且按位取反与前一个20ms检测的值相与,得到一个值,如果为1,则判断按键按下,否则则无按下。
消抖的流程图可表示为
3.3秒表模块
图5
图5为秒表模块的顶层图。
从图中可以看出,由CLK1HZ和key[1..0]两个输入,CLK1HZ是时钟信号,用于计时,即秒表的形成。
而key[1..0]是按键的输入,也即只有当特定按键按下时,秒表才启动。
输出进位信号co1、秒的地位cl、秒的高位ch。
当cl=9时。
产生进位信号,使秒的高位加1。
在此处设计中,并没有设计秒向分进位。
秒表流程图可表示为
3.4闹钟、整点报时模块
图6
图6是闹钟、整点报时模块顶层图,通过自己设置的闹钟时间与当前的时间进行比较,当当前的时间和设置的闹钟时间相同时,就会输出特定的频率给蜂鸣器,鸣器电路开始工作,从而产生闹钟响铃。
闹钟模块和整点报时的原理相同。
可以把整点报时模块看做一个已经设置好时间的闹钟。
闹钟模块由闹钟设置和闹钟比较两部分组成,整点报时是只有时间的比较部分。
闹钟的设置部分的输入端为key,即模式选择,当key为高电平时,设置功能开启,按键调节闹钟设置模块。
Move为位选,add为数值的增加。
输出位为小时的十位和个位,分钟的十位和个位。
输出端连接显示模块和闹钟比较部分。
闹钟比较部分为时钟模块中小时的十位和个位,分钟的十位和个位,闹钟设置部分的小时的十位和个位,分钟的十位和个位。
将以上对应的数据相互比较,如果都相等,则输出一定频率的脉冲到蜂鸣器。
整点报时和半点报时的输入端为系统时钟信号和时钟模块中小时的十位和个位,分钟的十位和个位,将输入的信号与要求的时间作比较,如果都相等,则输出一定频率的脉冲到蜂鸣器。
使蜂鸣器发声需要输出一定频率的脉冲,用到的原理与分频器相同,因为要输出的方波的占空比为50%,输出1KHz是将50MHz的时钟信号均分为100000份,设立一个整数型的中间变量k,范围为0至99999,检测系统时钟信号的上升沿,当为上升沿时,k自加1,当k加至99999时,将输出信号取反,并将中间变量置零。
循环往复,分频器可以输出一个1KHz,占空比为50%的时钟信号。
输出50Hz的信号原理也相同,只要修改相应的中间变量范围就可以实现。
最后通过一个或门输出至蜂鸣器。
3.5显示模块
图7是显示模块的顶层图。
输入是时、分、秒二进制码,通过对数码管进行动态扫描可以在数码管上进行显示。
虽然这些字符是在不同时刻出现的,而且同一时刻,只有一位显示,其它各位熄灭,但由于数码管具有余辉特性和人眼有视觉暂留现象,只要每位数码管显示间隔足够短,给人眼的视觉印象就会是连续稳定地显示。
数码管不同位显示的时间间隔可以通过调整延时程序的延时长短来完成。
数码管显示的时间间隔也能够确定数码管显示时的亮度,若显示的时间间隔长,显示时数码管的亮度将亮些,若显示的时间间隔短,显示时数码管的亮度将暗些。
若显示的时间间隔过长的话,数码管显示时将产生闪烁现象。
所以,在调整显示的时间间隔时,即要考虑到显示时数码管的亮度,又要数码管显示时不产生闪烁现象。
4设计验证
4.1蜂鸣器仿真波形
4.2分频器功能仿真
4.3.秒表功能仿真
4.4按键模块输入输出波形仿真
4.5Led数码管显示部分:
5设计总结
5.1系统实现的功能
整个系统实现了以下功能:
1.计时功能—正常的星期、时、分、秒计时,并由7只8段数码管分别显示;
2.校时功能---任意设置时钟的星期、时、分、秒;
3.整点报时功能----当计时达到59分53秒时开始报时,蜂鸣器频率为2Hz,当到达59分59秒时,蜂鸣器频率为1kHz。
半点报时----当计时达到30分00秒时,蜂鸣器频率2Hz。
4.闹钟功能----设置任意时间,时钟到达时,闹钟功能开启;
5.秒表功能----通过功能键切换进入秒表功能时,按start键后,开始以ms为单位进行计时,并在数码管显示;
6.不显示高位无效零。
5.2展望
通过此次的电子钟课程设计,学会了很多东西,最主要的是自顶向下的设计方法,先从全局入手,将整个电路分为若干个相互独立的子模块,再在子模块中分的更细,直到可以通过简单的电路就能实现的功能。
这样的设计方法化繁为简,层层深入,有助于构建设计方案,自己心中也有清晰的思路,最主要的是:
从全局入手无论什么时候都能考虑到全局而不会顾此失彼。
这次的课程设计中,还是有很多不尽人意的地方,比如说消抖程序,做的不是很好,以至于在秒表计时模块出现问题,如果一直按秒表功能键,数码管就会一直闪烁。
这就是由于消抖没有做好。
此次电子课程设计,是检验我们的一个机会。
通过此次的数字电子钟的设计,我找到了自己的不足之处。
让我明白了作为一个工科学生,应该多动手、多思考。
因为只有这样,我们才能学好我们的专业知识。
参考文献
[1]任文平,梁竹关.EDA技术与FPGA工程实例开发.北京:
机械工业出版社,2013
[2]潘松,黄继业,等.EDA技术实用教程[M].北京:
科学出版社,2010.
[3]冯建国,俞一鸣.FPGA现代数字系统设计[M].北京:
清华大学出版社,2010.
[4]焦素敏.EDA技术基础.北京:
清华大学出版社,2009.
[5]王穿新.FPGA设计基础.北京:
高等教育出版社,2009.
[6]王振红.VHDL数字电路设计与应用实践教程.北京:
机械工业出版社,2006.
附录
1附顶层原理图
2分频
libraryieee;
useieee.std_logic_1164.all;
useieee.std_logic_arith.all;
useieee.std_logic_unsigned.all;
entityfenpinis
port(clk:
instd_logic;
clk_1khz:
outstd_logic;
clk_100hz:
outstd_logic;
clk_10hz:
outstd_logic;
clk_2hz:
outstd_logic;
clk_1hz:
outstd_logic
);
endentityfenpin;
architecturefen_noffenpinis
signalcnter0:
integerrange0to24999:
=0;
signalcnter1:
integerrange0to4:
=0;
signalcnter2:
integerrange0to4:
=0;
signalcnter3:
integerrange0to4:
=0;
signalcnter4:
integerrange0to4:
=0;
signalcnter5:
integerrange0to24:
=0;
signalclk_1khztmp,clk_100hztmp,clk_10hztmp,clk_2hztmp,clk_1hztmp,clk_0_1hztmp:
std_logic:
='0';
begin
process(clk)is
begin
ifclk'eventandclk='1'then
ifcnter0=24999then
cnter0<=0;
clk_1khztmp<=notclk_1khztmp;
else
cnter0<=cnter0+1;
endif;
endif;
endprocess;
clk_1khz<=clk_1khztmp;
process(clk_1khztmp)is
begin
ifclk_1khztmp'eventandclk_1khztmp='1'then
ifcnter1=4then
cnter1<=0;
clk_100hztmp<=notclk_100hztmp;
else
cnter1<=cnter1+1;
endif;
endif;
endprocess;
clk_100hz<=clk_100hztmp;
process(clk_100hztmp)is
begin
ifclk_100hztmp'eventandclk_100hztmp='1'then
ifcnter2=4then
cnter2<=0;
clk_10hztmp<=notclk_10hztmp;
else
cnter2<=cnter2+1;
endif;
endif;
endprocess;
clk_10hz<=clk_10hztmp;
process(clk_100hztmp)is
begin
ifclk_100hztmp'eventandclk_100hztmp='1'then
ifcnter5=24then
cnter5<=0;
clk_2hztmp<=notclk_2hztmp;
else
cnter5<=cnter5+1;
endif;
endif;
endprocess;
clk_2hz<=clk_2hztmp;
process(clk_10hztmp)is
begin
ifclk_10hztmp'eventandclk_10hztmp='1'then
ifcnter3=4then
cnter3<=0;
clk_1hztmp<=notclk_1hztmp;
else
cnter3<=cnter3+1;
endif;
endif;
endprocess;
clk_1hz<=clk_1hztmp;
endfen_n;
3消抖
LIBRARYIEEE;
USEIEEE.STD_LOGIC_1164.ALL;
USEIEEE.STD_LOGIC_UNSIGNED.ALL;
USEIEEE.STD_LOGIC_ARITH.ALL;
entityxiaodouis
port(clk1:
instd_logic;
key:
instd_logic;
key_out:
OUTSTD_LOGIC
);
endentityxiaodou;
ARCHITECTUREbehaveOFxiaodouIS
begin
PROCESS(CLK1,key)
VARIABLECOUNT1:
INTEGERRANGE0TO99;
BEGIN
IFkey='0'THEN
IFclk1'eventandclk1='1'THEN
IFCOUNT1<99THENCOUNT1:
=COUNT1+1;
ELSECOUNT1:
=0;ENDIF;
IFCOUNT1=98THENkey_out<='0';
ELSEkey_out<='1';ENDIF;
ENDIF;
ELSECOUNT1:
=0;
ENDIF;
ENDPROCESS;
ENDBEHAVE;
4显示
LIBRARYIEEE;
USEIEEE.STD_LOGIC_1164.ALL;
USEIEEE.STD_LOGIC_UNSIGNED.ALL;
entityxianshiis
port(clk:
instd_logic;
miaoge:
instd_logic_vector(3downto0);
miaoshi:
instd_logic_vector(3downto0);
fenge:
instd_logic_vector(3downto0);
fenshi:
instd_logic_vector(3downto0);
xiaoge:
instd_logic_vector(3downto0);
xiaoshi:
instd_logic_vector(3downto0);
zhou:
instd_logic_vector(3downto0);
mb0:
instd_logic_vector(3downto0);
mb1:
instd_logic_vector(3downto0);
mb2:
instd_logic_vector(3downto0);
mb3:
instd_logic_vector(3downto0);
mb4:
instd_logic_vector(3downto0);
mb5:
instd_logic_vector(3downto0);
mb6:
instd_logic_vector(3downto0);
amh:
instd_logic_vector(3downto0);
aml:
instd_logic_vector(3downto0);
afh:
instd_logic_vector(3downto0);
afl:
instd_logic_vector(3downto0);
ahh:
instd_logic_vector(3downto0);
ahl:
instd_logic_vector(3downto0);
key:
instd_logic_vector(1downto0);
shanshuo:
instd_logic_vector(1downto0);
Q:
BUFFERSTD_LOGIC_VECTOR(2DOWNTO0);
DOUT:
OUTSTD_LOGIC_VECTOR(4DOWNTO0)
);
endentityxianshi;
ARCHITECTUREbehaveOFxianshiIS
signalQIN:
INTEGERRANGE6DOWNTO0;
signalcount:
INTEGERRANGE0TO999;
begin
p1:
process(clk)
begin
ifclk'eventandclk='1'then
IFQIN>6THEN
QIN<=0;
ELSE
QIN<=QIN+1;
ENDIF;
ifcount>999then
count<=0;
else
count<=count+1;
endif;
ENDIF;
ENDPROCESSP1;
P2:
PROCESS(QIN)
BEGIN
ifkey="00"then
CASEQINIS
WHEN0=>DOUT<='0'&mb0(3DOWNTO0);Q<="000";
WHEN1=>DOUT<='0'&mb1(3DOWNTO0);Q<="001";
WHEN2=>DOUT<='0'&mb2(3DOWNTO0);Q<="010";
WHEN3=>DOUT<='1'&mb3(3DOWNTO0);Q<="011";
WHEN4=>DOUT<='0'&mb4(3DOWNTO0);Q<="100";
WHEN5=>DOUT<='0'&mb5(3DOWNTO0);Q<="101";
WHEN6=>DOUT<="11111";Q<="111";
WHENOTHERS=>NULL;
ENDCASE;
elsifkey="01"then
ifshanshuo="00"then
ifcount<499then
CASEQINIS
WHEN0=>DOUT<='0'&MIAOGE(3DOWNTO0);Q<="000";
WHEN1=>DOUT<='0'&MIAOSHI(3DOWNTO0);Q<="001";
WHEN2=>DOUT<='1'&FENGE(3downto0);Q<="010";
WHEN3=>DOUT<='0'&FENSHI(3DOWNTO0);Q<="011";
WHEN4=>DOUT<='1'&XIAOGE(3DOWNTO0);Q<="100";
WHEN5=>DOUT<='0'&XIAOSHI(3DOWNTO0);Q<="101";
WHEN6=>DOUT<='1'&ZHOU(3DOWNTO0);Q<="110";
WHENOTHERS=>NULL;
ENDCASE;
elsifcount>499then
CASEQINIS
WHEN0=>DOUT<='0'&MIAOGE(3DOWNTO0);Q<="000";
WHEN1=>DOUT<='0'&MIAOSHI(3DOWNTO0);Q<="001";
WHEN2=>DOUT<="11111";Q<="111";
WHEN3=>DOUT<='0'&FENSHI(3DOWNTO0);Q<="011";
WHEN4=>DOUT<='1'&XIAOGE(3DOWNTO0);Q<="100";
WHEN5=>DOUT<='0'&XIAOSHI(3DOWNTO0);Q<="101";
WHEN6=>DOUT<='1'&ZHOU(3DOWNTO0);Q<="110";
WHENOTHERS=>NULL;
ENDCASE;