基于VHDL的多功能电子钟.docx
- 文档编号:5891023
- 上传时间:2023-05-09
- 格式:DOCX
- 页数:46
- 大小:1.82MB
基于VHDL的多功能电子钟.docx
《基于VHDL的多功能电子钟.docx》由会员分享,可在线阅读,更多相关《基于VHDL的多功能电子钟.docx(46页珍藏版)》请在冰点文库上搜索。
基于VHDL的多功能电子钟
数字系统课程设计报告
课程设计题目:
基于vhdl语言的电子钟
组员:
陈洪彬,麦俊辉,缪超
课程设计要求:
设计一个用4位数码管显示的电子钟,包括整点报时,闹钟功能,4按键输入
采用VHDL语言描述系统功能,并在QUARTUSII工具软件中进行仿真,下载到EDA实验板进行验证。
编写设计报告,要求包括方案选择、程序代码清单、调试过程、测试结果及心得体会。
一、软硬件资源分析
实验室提供了Altera公司的cyclone系列EP1C6Q240C8实验开发板,该开发板提供了四个自由按键,八个发光LED,蜂鸣器,四个七段数码管,四位拨码开关等等硬件资源。
我们所设计的数字钟用到了四个自由按键用于对显示的选择,对设置时间的选择,还有用于用于设置时间时的加一操作,四个七段数码管用于显示,蜂鸣器用于整点报时和闹钟,还有四个发光LED用于判断自由按键的通断。
以下列表对数字钟中用到的硬件资源进行说明:
硬件名称
程序中的标识符
开发板中的标号
对应芯片中管脚数
功能
操作方式
备注
EP1C6Q240C8
----------
----------
----------
----------
----------
Alter公司Cyclone系列
发光LED
Led1
LED[0]
P_113
Key1in按下时点亮
----------
指示作用
发光LED
Led2
LED[1]
P_114
Key2in按下时点亮
----------
指示作用
发光LED
Led3
LED[2]
P_115
Key3in按下时点亮
----------
指示作用
发光LED
Led4
LED[3]
P_116
Key4in按下时点亮
----------
指示作用
蜂鸣器
Speak
beep
P_124
当低电平时发声
当低电平时发声
指示作用
自由按键
Key1in
Key0
P_125
确定工作状态(见下表)
长按一下
脉冲来时改变,消抖
自由按键
Key2in
Key1
P_126
确定工作状态(见下表)
长按一下
脉冲来时改变,消抖
自由按键
Key3in
Key2
P_127
确定工作状态(见下表)
长按一下
脉冲来时改变,消抖
自由按键
Key4in
Key3
P_128
修改时间时加一,停止闹钟
长按一下
脉冲来时改变,消抖
七段数码管
dout,selout
7LED1_C1~C3
P_168
P_169
P_170
P_173
显示正常时间及修改状态
动态扫描法实现显示
四个数码管全用
总体设计框图:
操作说明:
按键
状态
Key4out
Key3out
Key2out
Key1out
实现功能
上升沿
1
0
0
修改小时(时钟)
上升沿
1
1
0
修改分钟(时钟)
上升沿
1
0
1
修改小时(闹钟)
上升沿
1
1
1
修改分钟(闹钟)
X(0或1)
0
1
0
显示时分(时钟)
x
0
0
0
显示分秒(时钟)
x
0
0
1
显示时分(闹钟)
x
0
1
1
显示分(闹钟)
注:
1.key3的1表示修改,0表示显示;
Key1的1表示闹钟,0表示时钟;
Key2则是‘时-分’切换或者‘时分-分秒’切换。
各模块介绍
(1)分频器
在数字钟的设计中,采用了芯片内部提供的50MHz全局时钟,将其分频率后产生一个接近1Hz秒时钟clk1,一个2Hz左右的闪烁时钟clk2,一个显示模块800Hz的clk3,一个用于消抖模块的20000Hz的clk4。
clk1作用是:
每秒产生一个脉冲,触发“秒”的累加。
clk2作用是:
在修改状态下通过判断clk2的电平值来决定数码管的亮灭。
clk3作用是:
作为扫描频率刷新数码管的示数。
具体做法是令clk不断产生50MHz的方波,同时clk作为累加器的触发源。
当累加器累计到一定数目时,使clk1,clk2,clk3,clk4的电平发生跳转,从而输出不同频率的方波。
设计要点:
例如要产生20000Hz,即周期50us。
50,000,000/20000=2500,即使50MHz的晶振频率作为累加触发源,累计到1250个方波则使clk4状态反转。
程序:
LIBRARYIEEE;
USEIEEE.STD_LOGIC_1164.ALL;
USEIEEE.STD_LOGIC_UNSIGNED.ALL;
USEIEEE.STD_LOGIC_ARITH.ALL;
ENTITYdistribu1IS
PORT(
clk:
INSTD_LOGIC;--晶振时钟
clk1:
BUFFERSTD_LOGIC;--1Hz,用于秒的增加
clk2:
BUFFERSTD_LOGIC;--2Hz,用于修改时间的闪烁
clk3:
BUFFERSTD_LOGIC;--800Hz,显示模块的扫描时钟
clk4:
BUFFERSTD_LOGIC);--20000Hz消除抖动的扫描时钟
ENDENTITYdistribu1;
ARCHITECTUREoneOFdistribu1IS
BEGIN
dividefreq1Hz:
PROCESS(clk)--1Hz
VARIABLEz1:
integerrange0to25000000;
BEGIN
IF(clk'eventANDclk='1')THEN
z1:
=z1+1;
ifz1=25000000then
z1:
=0;
clk1<=notclk1;--25,000,000
ENDIF;
ENDIF;
ENDPROCESSdividefreq1Hz;
dividefreq2Hz:
PROCESS(clk)--2Hz
VARIABLEz2:
integerrange0to12500000;
BEGIN
IF(clk'eventANDclk='1')THEN
z2:
=z2+1;
ifz2=12500000then
z2:
=0;
clk2<=notclk2;
ENDIF;
ENDIF;
ENDPROCESSdividefreq2Hz;
dividefreq800Hz:
PROCESS(clk)--800Hz
VARIABLEz3:
integerrange0to31250;
BEGIN
IF(clk'eventANDclk='1')THEN
z3:
=z3+1;
ifz3=31250then
z3:
=0;
clk3<=notclk3;
ENDIF;
ENDIF;
ENDPROCESSdividefreq800Hz;
dividefreq02MS:
PROCESS(clk)--0.05ms,20000Hz
VARIABLEz4:
integerrange0to1250;
BEGIN
IF(clk'eventANDclk='1')THEN
z4:
=z4+1;
ifz4=1250then
z4:
=0;
clk4<=notclk4;
ENDIF;
ENDIF;
ENDPROCESSdividefreq02mS;
ENDone;
仿真:
由于信号频率相差较大,所以仿真结果以clk4为代表,另外几个信号没有显示得出来:
(2)消除抖动模块
该数字钟将用到4个自由按键,故程序只对这四个开关进行去抖。
去抖原理如下:
机械开关在按下时都会一定的抖动,对应信号线电平的变化有一个不稳定期,在读取按键状态时必须避开这个不稳定期,以免造成误判。
本文采用了这延迟算法进行去抖。
利用频率较高的时钟(本文采用了扫描时钟clk)反复读取按键状态,并利用一个寄存器来记录当前状态出现的次数,如果当前状态与前一次读取的状态不一样,则将计数寄存器清零;如果当前状态与前一次读取的状态一致,刚计数寄存器加1。
当计数寄存器达到一定值N时便认为按键已按下并产生了一个电平改变。
设计要点:
虽然我们采用4位自由开关,实际上其中key1,key2,和key3充当拨码开关的功能,而key4实现按键功能拨码开关与自由按键的处理是不同的,因为拨码开关是有两个稳定状态的,即可任意长时间处于‘0’或‘1’态,而自由按键只有一个稳态,例如在实验板上,未进行操作时自由按键的输出默认是高电平,如果按一下,变为低电平,操作者一旦松手,按键输出自动恢复为高电平。
因此在处理时,让自由按键一次按便输出一个脉冲(相当于进行了两次电平转换,而不是一次)。
程序:
LIBRARYIEEE;
USEIEEE.STD_LOGIC_1164.ALL;
USEIEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITYdebounce2IS
PORT(
clk4:
INSTD_LOGIC;--消除抖动的扫描时钟
key1in:
INSTD_LOGIC;--按键的输入
key1out:
BUFFERSTD_LOGIC;--按键的输出
key2in:
INSTD_LOGIC;
key2out:
BUFFERSTD_LOGIC;
key3in:
INSTD_LOGIC;
key3out:
BUFFERSTD_LOGIC;
key4in:
INSTD_LOGIC;
key4out:
BUFFERSTD_LOGIC);
ENDdebounce2;
ARCHITECTUREbehaveOFdebounce2IS
BEGIN
pkey1:
PROCESS(clk4,key1out)
VARIABLEcount1:
integerrange0to100;---处理抖动的时为0.2msX100=20ms
BEGIN
ifkey1in='0'then
IF(clk4'EVENTANDclk4='1')THEN
ifcount1=100thencount1:
=count1;--20ms后结束处理
elsecount1:
=count1+1;
endif;
ifcount1=99thenkey1out<=notkey1out;--延时到后状态反转
elsekey1out<=key1out;
endif;
endif;
elsecount1:
=0;
endif;
ENDPROCESSpkey1;
pkey2:
PROCESS(clk4,key2out)
VARIABLEcount2:
integerrange0to100;
BEGIN
ifkey2in='0'then
IF(clk4'EVENTANDclk4='1')THEN
ifcount2=100thencount2:
=count2;
elsecount2:
=count2+1;
endif;
ifcount2=99thenkey2out<=notkey2out;
elsekey2out<=key2out;
endif;
endif;
elsecount2:
=0;
endif;
ENDPROCESSpkey2;
pkey3:
PROCESS(clk4,key3out)
VARIABLEcount3:
integerrange0to100;
begin
ifkey3in='0'then
IF(clk4'EVENTANDclk4='1')THEN
ifcount3=100thencount3:
=count3;
elsecount3:
=count3+1;
endif;
ifcount3=99thenkey3out<=notkey3out;
elsekey3out<=key3out;
endif;
endif;
elsecount3:
=0;
endif;
ENDPROCESSpkey3;
pkey4:
PROCESS(clk4,key4out)--Key4out不同以上处理
VARIABLEcount4:
integerrange0to100;
BEGIN
ifkey4in='0'then
IF(clk4'EVENTANDclk4='1')THEN
ifcount4=100thencount4:
=count4;
elsecount4:
=count4+1;
endif;
ifcount4=99thenkey4out<='1';--延时20ms后给key4out一个上升沿
elsekey4out<='0';---其余时间key4out都为'0'
endif;
endif;
elsecount4:
=0;
endif;
ENDPROCESSpkey4;
ENDbehave;
我们在仿真时,由于消抖时时钟周期要求过大,我们对消抖时间对应的时钟周期进行改动,将其改小,从而从仿真中可以看出消抖的效果,我们设消抖的延迟时间为八个时钟周期,则仿真结果如下:
从图中看出,已经实现消抖。
(3)时间设置模块:
主要分为手动增值和自动增值两个进程。
当key4按下,且key3out=’1’时进入手动增值模式。
Key2和key1在不同状态对应不同的情况,分别是时钟小时,时钟分钟,闹钟小时,闹钟分钟。
自动增值和手动增值都要在更新了要加的值之后才进行上述的增值。
由于更新的需要,要把输出端的“a”和“b”互相传输,所以设置了一组“ain”和“bin”来过渡,且VHDL不能把输出口值赋给输入口,所以在原理图上强制把输出口连接到输入口。
小时部分:
将小时分成两位分别设置,当小时十位为0010,个位是0011,即为23点的时候,再加一就将十位个位都设置为0000。
而其他情况中,小时将加从0000到0010
(2)循环运行。
而小时个位为从0000到1001(即为9)循环运行。
当分钟部分,十位为0101,而个位为1001(即59分)再加一时,小时个位加一;当小时个位从1001(9)加一时,小时十位加一。
时间设置时,选定设置位,key4in按下时,选定位加一。
分钟部分:
分钟部分也分为十位及个位分别设置,当小时为十位0101而个位是1001(即59分)时,再加一就将十位和个位都清零。
而其他情况,十位按照0000到0101(0到5)循环,个位从0000到1001(0到9)循环。
当秒钟部分,十位为0101,而个位为1001(即59秒)再加一时,分钟个位加一;当分钟个位从1001(9)加一时,分钟十位加一。
时间设置时,选定设置位,key4in按下时,选定位加一。
秒钟部分:
跟分钟一样,秒钟部分也分为十位及个位分别设置,当十位0101而个位是1001(即59分)时,再加一就将十位和个位都清零。
而其他情况,十位按照0000到0101循环,个位从0000到1001(0到9)循环。
其正常时间工作时个位在1HZ脉冲上升沿来到时加一。
时间设置时,选定设置位,key4in按下时,选定位加一。
闹钟时间设置:
本模块分4个进程,分别对闹钟时间的小时十位,小时个位,分钟十位,分钟个位进行检测,每个进程均以芯片的晶振50MHz进行触发。
对分钟个位,来一个时钟的上升沿,检测按键输出状态,当key1out='1'andkey2out='0'andkey3out='1'时每输入一个key4in信号脉冲使得key4out来上升沿则闹钟设置的分钟个位加1,当个位加到9,再加一次则复位为0;下一个进程检测分钟十位,每来一个时钟上升沿,在对应的按键状态下,当个位为9时,再来一个key4out上升沿脉冲则分钟十位加1,当加到十位为5,个位为9,则再加一次就复位为0。
同样原理设计闹钟小时部分。
自动增值则是由每一个1Hz的clk上升沿触发,每秒加一次。
程序如下:
libraryieee;
useieee.std_logic_1164.all;
useIEEE.STD_LOGIC_ARITH.ALL;
useieee.std_logic_unsigned.all;
entityshijian2is
port(
clk:
instd_logic;
key1out:
instd_logic;---按键状态
key2out:
instd_logic;
key3out:
instd_logic;
key4out:
instd_logic;
hou1a:
bufferstd_logic_vector(3downto0);--手动修改后的时间数据
hou2a:
bufferstd_logic_vector(3downto0);
min1a:
bufferstd_logic_vector(3downto0);
min2a:
bufferstd_logic_vector(3downto0);
seth1a:
bufferstd_logic_vector(3downto0);---手动修改后或没有修改的闹钟数据
seth2a:
bufferstd_logic_vector(3downto0);
setm1a:
bufferstd_logic_vector(3downto0);
setm2a:
bufferstd_logic_vector(3downto0);
hou1b:
bufferstd_logic_vector(3downto0);---每1秒自动加1的时钟数据
hou2b:
bufferstd_logic_vector(3downto0);
min1b:
bufferstd_logic_vector(3downto0);
min2b:
bufferstd_logic_vector(3downto0);
sec1b:
bufferstd_logic_vector(3downto0);
sec2b:
bufferstd_logic_vector(3downto0);
hou1ain:
instd_logic_vector(3downto0);--若之前为手动修改时间模式的数据,
hou2ain:
instd_logic_vector(3downto0);--要把修改后的时钟数据赋值给“b”代表显示模式的数据(即刷新)
min1ain:
instd_logic_vector(3downto0);
min2ain:
instd_logic_vector(3downto0);
hou1bin:
instd_logic_vector(3downto0);----用于更新a的值
hou2bin:
instd_logic_vector(3downto0);
min1bin:
instd_logic_vector(3downto0);
min2bin:
instd_logic_vector(3downto0)
);
endentityshijian2;
architectureoneofshijian2is
begin
--hou1ain<=hou1a;-----已在电路图上连线
--hou2ain<=hou2a;
--min1ain<=min1a;
--min2ain<=min2a;
--hou1bin<=hou1b;
--hou2bin<=hou2b;
--min1bin<=min1b;
--min2bin<=min2b;
shoudong:
process(key1out,key2out,key3out,key4out)----手动修改
begin
ifkey3out='0'then
hou1a<=hou1bin;----更新a的值
hou2a<=hou2bin;
min1a<=min1bin;
min2a<=min2bin;
elsif(key4out'eventandkey4out='1')then
if(key3out='1'ANDkey2out='0'ANDkey1out='0')then----校时钟小时位,手动加1脉冲
ifhou2a="0011"andhou1a="0010"then----检查进位,“a"代表手动修改模式的数据
hou2a<="0000";
hou1a<="0000";
elsifhou2a="1001"then
hou1a<=hou1a+1;
hou2a<="0000";
elsehou2a<=hou2a+1;
endif;
elsif(key3out='1'ANDkey2out='1'ANDkey1out='0')then-----校时钟分钟位,手动加1脉冲
ifmin2a="1001"andmin1a="0101"then----检查进位
min2a<="0000";
min1a<="0000";
elsifmin2a="1001"then
min2a<="0000";
min1a<=min1a+1;
elsemin2a<=min2a+1;
endif;
elsif(key3out='1'ANDkey2out='0'ANDkey1out='1')then------校闹钟小时位,手动加1脉冲
ifseth2a="0011"andseth1a="0010"then----检查进位
seth2a<="0000";
seth1a<="0000";
elsifseth2a="1001"then
seth1a<=seth1a+1;
seth2a<="0000";
elseseth2a<=seth2a+1;
endif;
elsif(key3out='1'ANDkey2out='1'ANDkey1out='1')then------校闹钟分钟位,手动加1脉冲
ifsetm2a="1001"andsetm1a="0101"then----检查进位
setm2a<="0000";
setm1a<="0000";
elsifsetm2a="1001"then
setm2a<="0000";
setm1a<=setm1a+1;
elsesetm2a<=setm2a+1;
endif;
endif;
endif;
endprocess;
zidong:
process(key1out,key3out,key4out,clk)----每1秒自动加1
begin
if(key3out='1'andkey1out='0')t
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 基于 VHDL 多功能 电子钟