数字钟可编程.docx
《数字钟可编程.docx》由会员分享,可在线阅读,更多相关《数字钟可编程.docx(13页珍藏版)》请在冰点文库上搜索。
数字钟可编程
“数字钟”综合设计实验—采用CPLD/FPGA可编程器件设计
一、实验目的
1.掌握可编程逻辑器件的层次化设计方法;
2.掌握十进制、六十进制、二十四进制计数器的设计方法;
3.掌握多位计数器相连的设计方法;
4.掌握喇叭的驱动方法。
二、设计任务与要求
1.基本功能:
具有小时、分钟、秒计数显示功能,并以24小时循环计时;
2.具有清零和校时的功能,具有整点报时的功能;
3.自由发挥功能:
具有到点闹时功能,并且能够预置闹铃时间;
4.要求小时、分钟、秒在数码管上的显示格式如下:
三、程序设计思路
本设计的难点在于时钟的计数功能和数码管显示功能,
1.60进制和24进制计数器的实现
VHDL实现计数比较简单,我们只要设置好计数的最终数值,通过简单的加法或者减法就可以实现任意数值的计数状态。
2.小时、分钟、秒计数显示的实现
数字钟的小时、分钟、秒共用8个数码管显示,并有2个数码管用来产生隔离符号“—”,为节省逻辑器件的I/O,时间显示采用动态扫描的方法。
动态扫描的基本原理是对于一组数码管动态扫描显示需要由两组信号来控制:
一组是字段输出口输出的字形代码,用来控制显示的字形,称为段码;另一组是位输出口输出的控制信号,用来选择第几位数码管工作,称为位码。
各位数码管的段线并联,段码的输出对各位数码管来说都是相同的。
因此,在同一时刻如果各位数码管的位选线都处于选通状态的话,8位数码管将显示相同的字符。
若要各位数码管能够显示出与本位相应的字符,就只让这一位的位选线处于导通状态,而其它各位的位选线处于关闭状态。
同时,段线上输出相应位要显示字符的字型码。
这样在同一时刻,只有选通的那一位显示出字符,而其它各位则是熄灭的,如此循环下去,就可以使各位数码管显示出将要显示的字符。
3.动态扫描的实现:
基本思路是利用硬件语言编写一个8进制的计数器,根据计数器的值译出位选通信号来选择哪一个数码管显示;段线上显示的时间用一组减计数器实现,通过7段译码程序将计数器的时间信息按照相应的位信息送到段线上。
四、仿真与硬件测试
1.功能仿真
程序编译后要对其进行功能仿真以此来验证各模块设计的正确性,在仿真过程中,分别改变特殊状态按键,观察输出的仿真运行结果,验证电路的逻辑功能是否达到设计要求。
2.硬件测试
功能仿真正确后,进行管脚锁定,锁定管脚时必须对实验箱的硬件资源有一定的了解,锁定时将设计中的输入输出信号和FPGA的具体管脚相对应,实验中选用器件为EPF10K10LC-84,锁定完后再进行一次编译,保证管脚配置起作用。
五、实验报告要求
课题完成后应认真撰写实验报告,其主要内容如下:
1.课题的任务及要求。
2.叙述所设计的数字钟的工作原理
3.课题分析与编程思路。
对课题认真分析,正确理解,明确设计思路。
4.仿真结果分析。
建立测试向量文件,然后编译该文件,进行功能仿真和时序仿真,给出仿真结果并进行分析。
5.实验设计中各功能模块的源程序。
6.总结。
总结课题存在的问题,提出改进的设想;完成本课题后的收获、体会和建议。
LIBRARYIEEE;
USEIEEE.STD_LOGIC_1164.ALL;
USEIEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITYtimerIS
PORT(clk,clk1:
INSTD_LOGIC;
clr,prnh,prnm:
INSTD_LOGIC;
q,y:
OUTSTD_LOGIC_VECTOR(7downto0);
spk:
OUTSTD_LOGIC);
ENDtimer;
ARCHITECTUREbehavOFtimerIS
COMPONENTcnt60IS
PORT(clk,keyclk,clr,prn:
INSTD_LOGIC;
qh,ql:
OUTSTD_LOGIC_VECTOR(3downto0);
qcarry:
OUTSTD_LOGIC);
ENDCOMPONENT;
COMPONENTcnt24IS
PORT(clk,clr:
INSTD_LOGIC;
qh,ql:
OUTSTD_LOGIC_VECTOR(3downto0));
ENDCOMPONENT;
SIGNALshtem,sltem,mhtem,mltem,hhtem,hltem,da:
STD_LOGIC_VECTOR(3downto0);
SIGNALsctem,mctem:
STD_LOGIC;
SIGNALcou:
INTEGERRANGE0to10;
SIGNALdout,tempy:
STD_LOGIC_VECTOR(7DOWNTO0);
BEGIN
U1:
cnt60PORTMAP(CLK1,clk,clr,PRNM,
SHTEM,SLTEM,SCTEM);--clk1is1hz,clkis1024hz
U2:
cnt60PORTMAP(SCTEM,clk,clr,PRNH,
mhtem,mltem,MCTEM);
U3:
cnt24PORTMAP(MCTEM,clr,HHTEM,HLTEM);
PROCESS(clk)
BEGIN
IF(clk'EVENTANDclk='1')THEN--clkis1024hz
IFcou<8THEN
cou<=cou+1;
ELSE
cou<=0;
ENDIF;
CASEcouIS
WHEN0=>da<=HHTEM;
TEMPY<="10000000";
WHEN1=>da<=HLTEM;
TEMPY<="01000000";
WHEN2=>da<="1010";
TEMPY<="00100000";
WHEN3=>da<=mhtem;
TEMPY<="00010000";
WHEN4=>da<=mltem;
TEMPY<="00001000";
WHEN5=>da<="1010";
TEMPY<="00000100";
WHEN6=>da<=SHTEM;
TEMPY<="00000010";
WHEN7=>da<=SLTEM;
TEMPY<="00000001";
WHENOTHERS=>da<="0000";
TEMPY<="00000000";
ENDCASE;
ENDIF;
CASEdaIS
WHEN"0000"=>dout<="00111111";
WHEN"0001"=>dout<="00000110";
WHEN"0010"=>dout<="01011011";
WHEN"0011"=>dout<="01001111";
WHEN"0100"=>dout<="01100110";
WHEN"0101"=>dout<="01101101";
WHEN"0110"=>dout<="01111101";
WHEN"0111"=>dout<="00000111";
WHEN"1000"=>dout<="01111111";
WHEN"1001"=>dout<="01101111";
WHEN"1010"=>dout<="01000000";
WHEN"1011"=>dout<="01111100";
WHEN"1100"=>dout<="00111001";
WHEN"1101"=>dout<="01011110";
WHEN"1110"=>dout<="01111001";
WHEN"1111"=>dout<="01110001";
WHENOTHERS=>dout<="00000000";
ENDCASE;
IF(mhtem="0000"ANDmltem="0000")THEN
spk<=mCTEMANDclkANDCLK1;
ENDIF;
ENDPROCESS;
Q<=dout;y<=TEMPY;
ENDBEHAV;
LIBRARYIEEE;
USEIEEE.STD_LOGIC_1164.ALL;
USEIEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITYcnt60IS
PORT(clk,keyclk,clr,prn:
INSTD_LOGIC;
qh,ql:
OUTSTD_LOGIC_VECTOR(3downto0);
qcarry:
OUTSTD_LOGIC);
ENDcnt60;
ARCHITECTUREbehavOFcnt60IS
SIGNALqtemh,qteml:
STD_LOGIC_VECTOR(3DOWNTO0);
SIGNALqc:
STD_LOGIC;
SIGNALcou:
INTEGERRANGE0TO200;
BEGIN
PROCESS(keyclk)
BEGIN
IF(keyclk'EVENTANDkeyclk='1')THEN
cou<=cou+1;
ENDIF;
ENDPROCESS;
PROCESS(clk,keyclk)
BEGIN
IF(cou=0)AND(PRN='1')THEN
qc<=keyclk;
ELSIFclr='0'THEN
qtemh<=(OTHERS=>'0');
qteml<=(OTHERS=>'0');
ELSIF(clk'EVENTANDclk='1')THEN
IF(qteml<9)THEN
qteml<=qteml+1;
ELSE
qteml<=(OTHERS=>'0');
qc<='0';
IF(qtemh<5)THEN
qtemh<=qtemh+1;
ELSE
qtemh<=(OTHERS=>'0');
qc<='1';
ENDIF;
ENDIF;
ENDIF;
ENDPROCESS;
QH<=qtemh;QL<=qteml;qcARRY<=qc;
ENDbehav;
LIBRARYIEEE;
USEIEEE.STD_LOGIC_1164.ALL;
USEIEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITYcnt24IS
PORT(clk,clr:
INSTD_LOGIC;
qh,ql:
OUTSTD_LOGIC_VECTOR(3downto0));
ENDcnt24;
ARCHITECTUREbehaveOFcnt24IS
SIGNALqtemh,qteml:
STD_LOGIC_VECTOR(3DOWNTO0);
BEGIN
PROCESS(clk)
BEGIN
IFclr='0'THEN
qtemh<=(OTHERS=>'0');
qteml<=(OTHERS=>'0');
ELSIF(clk'EVENTANDclk='1')THEN
IF(qtemh<2)THEN
IFqteml<9THEN
qteml<=qteml+1;
ELSE
qteml<=(OTHERS=>'0');
qtemh<=qtemh+1;
ENDIF;
ELSIF(QTEMh=2)THEN
IFqteml<3THEN
qteml<=qteml+1;
ELSE
qtemh<=(OTHERS=>'0');
qteml<=(OTHERS=>'0');
ENDIF;
ENDIF;
ENDIF;
ENDPROCESS;
QH<=qtemh;QL<=qteml;
ENDbehave;
libraryieee;
useieee.std_logic_1164.all;
useieee.std_logic_unsigned.all;
useieee.std_logic_arith.all;
entitydzzis
port(clk,clk_scan,reset,setm,seth:
instd_logic;
dlh2:
std_logic_vector(3downto0);
time,sm:
outstd_logic_vector(7downto0);
--7段显示段码和位码
spk:
outstd_logic);
enddzz;
architectureSZofdzzis
signalcou:
integerrange0to8;
signalbs,nl:
std_logic;
signalh1,h2,m1,m2,s1,s2:
std_logic_vector(3downto0);
signalda:
std_logic_vector(3downto0);
begin
process(clk)
begin
if(clk'eventandclk='1')then
--清零
ifreset='0'then
h1<="0000";h2<="0000";m1<="0000";m2<="0000";
s1<="0000";s2<="0000";
--校分
elsifsetm='1'then
m2<=m2+1;
ifm2="1001"then
m2<="0000";
m1<=m1+1;
ifm1="0101"then
m1<="0000";
endif;
endif;
--校时
elsifseth='1'then
h2<=h2+1;
ifh2="1001"then
h2<="0000";
h1<=h1+1;
ifh1="0010"andh2<="0011"then
h1<="0000";h2<="0000";
endif;
endif;
endif;
--正常计数
ifs2="1001"then
s2<="0000";
elses2<=s2+1;
endif;
if(s1="0101"ands2="1001")then
s1<="0000";
elsifs2="1001"then--秒低位为9,高位不为5;
s1<=s1+1;
endif;
ifm2="1001"and(s1="0101"ands2="1001")then
m2<="0000";
elsif(s1="0101"ands2="1001")then--分低不为9;
m2<=m2+1;
endif;
if(m1="0101"andm2="1001")and
(s1="0101"ands2="1001")then
--59分59秒
m1<="0000";
elsifm2="1001"and(s1="0101"ands2="1001")then
--分高不为5,分低9,且59秒
m1<=m1+1;
endif;
ifh2="1001"and(m1="0101"andm2="1001")and
(s1="0101"ands2="1001")then
--9时59分秒59秒;
h2<="0000";
elsif(m1="0101"andm2="1001")and
(s1="0101"ands2="1001")then
h2<=h2+1;
endif;
if(h1="0010"andh2="0011")and
(m1="0101"andm2="1001")and
(s1="0101"ands2="1001")then
--23时59分秒59秒
h1<="0000";h2<="0000";
elsifh2="1001"and(m1="0101"andm2="1001")
and(s1="0101"ands2="1001")then
h1<=h1+1;
endif;
endif;
--整点报时
if(m1="0000"andm2="0000")
and(s1="0000"ands2="0000")then
bs<='1';
elsif(m1="0000"andm2="0001")
and(s1="0010"ands2="0000")then
bs<='0';
--报时20秒
endif;
--到点闹钟
ifh2=conv_integer(dlh2)and
(m1="0000"andm2="0000")then
nl<='1';
elsifh2=conv_integer(dlh2)and
(m1="0000"andm2="0001")then
nl<='0';
--闹铃1分钟,
endif;
endprocess;
process(clk_scan)
begin
if(clk_scan'EVENTandclk_scan='1')then
ifcou<7then
cou<=cou+1;
else
cou<=0;
endif;
casecouis
when0=>da<=h1;
sm<="10000000";
when1=>da<=h2;
sm<="01000000";
when2=>da<="1010";
sm<="00100000";
when3=>da<=m1;
sm<="00010000";
when4=>da<=m2;
sm<="00001000";
when5=>da<="1010";
sm<="00000100";
when6=>da<=s1;
sm<="00000010";
when7=>da<=s2;
sm<="00000001";
whenothers=>da<="0000";
sm<="00000000";
endcase;
endif;
casedais
when"0000"=>time<="00111111";
when"0001"=>time<="00000110";
when"0010"=>time<="01011011";
when"0011"=>time<="01001111";
when"0100"=>time<="01100110";
when"0101"=>time<="01101101";
when"0110"=>time<="01111101";
when"0111"=>time<="00000111";
when"1000"=>time<="01111111";
when"1001"=>time<="01101111";
when"1010"=>time<="01000000";
whenothers=>time<="00000000";
endcase;
spk<=(bsornl)andclkandclk_scan;
endprocess;
endSZ;