数字钟张港.docx
- 文档编号:25599226
- 上传时间:2023-06-10
- 格式:DOCX
- 页数:22
- 大小:201.40KB
数字钟张港.docx
《数字钟张港.docx》由会员分享,可在线阅读,更多相关《数字钟张港.docx(22页珍藏版)》请在冰豆网上搜索。
数字钟张港
1、前言
1.1EDA简介
EDA是电子设计自动化(ElectronicDesignAutomation)的缩写,在20世纪90年代初从计算机辅助设计(CAD)、计算机辅助制造(CAM)、计算机辅助测试(CAT)和计算机辅助工程(CAE)的概念发展而来的。
EDA技术就是以计算机为工具,设计者在EDA软件平台上,用硬件描述语言HDL完成设计文件,然后由计算机自动地完成逻辑编译、化简、分割、综合、优化、布局、布线和仿真,直至对于特定目标芯片的适配编译、逻辑映射和编程下载等工作。
1.2数字钟简介
数字钟亦称数显钟(数字显示钟),是一种用数字电路技术实现时、分、秒计时的装置,与机械时钟相比,直观性为其主要显著特点,且因非机械驱动,具有更长的使用寿命,相较石英钟的石英机芯驱动,更具准确性。
数字钟已成为人们日常生活中必不可少的必需品,广泛用于个人家庭以及车站、码头、剧院、办公室等公共场所,给人们的生活、学习、工作、娱乐带来极大地方便。
相对于其他时钟类型,它的特点可归结为“两强一弱”:
比机械钟强在观时显著,比石英钟强在走时准确,但是它的弱点为显时较为单调。
1.3VerilogHDL简介
VerilogHDL是一种硬件描述语言(HDL:
HardwareDiscriptionLanguage),是一种以文本形式来描述数字系统硬件的结构和行为的语言,用它可以表示逻辑电路图、逻辑表达式,还可以表示数字逻辑系统所完成的逻辑功能。
VerilogHDL和VHDL是目前世界上最流行的两种硬件描述语言,都是在20世纪80年代中期开发出来的。
前者由GatewayDesignAutomation公司(该公司于1989年被Cadence公司收购)开发。
两种HDL均为IEEE标准。
2、总体设计方案
2.1设计内容
设计一个多功能的数字钟,该数字钟具有下述功能:
(1)计时功能:
包括时,分,秒。
(2)定时与闹钟功能:
能在设定的时间发出闹铃音。
(3)校时功能:
对小时,分钟和秒能手动调整以校准时间。
(4)整点报时功能:
每逢整点,产生“嘀嘀嘀嘀—嘟”,四短一长的报时音。
2.2方案比较
方案一(用数字电路搭建电子钟)
数字钟实际上是一个对标准频率(1HZ)进行计数的计数电路。
由于计数的起始时间不可能与标准时间(如北京时间)一致,故需要在电路上加一个校时电路,同时标准的1HZ时间信号必须做到准确稳定。
通常使用石英晶体振荡器电路构成数字钟。
总体方案设计如下图所
图2.1总体系统框图
方案二:
(采用的是CPLD芯片及外围电路实现)
系统总体构成包括最小系统部分、晶振模块、电源模块、JTAG下载模块、时间显示模块、闹钟报警模块,CPLD不仅完成对脉冲计数,完成时钟功能,还能同时对信号进行译码,能设定闹钟时间,和对设定时间比较闹时
图2.2系统组成框图
图2.3CPLD内部原理框图
2.3方案论证
方案一:
该系统是利用数字电路中的进制计数器、译码、触发器、锁存器,比较器实现。
这种小规模数字电路搭建起来比较复杂。
在设计中用到的芯片多,控制复杂,功耗大,在一些小型的设计中还可以,电路稍微复杂,则很难控制其时序,况且输入组数
不能很好的扩展。
方案二:
本方案是使用复杂可编程逻辑器件的CPLD芯片实现。
实现起来比较简单,一些功能模块在CPLD里面用VerilogHDL编程实现,比如这次实现的电子钟模块CPLD一块芯片就完成了包括七段译码,进制计数,设定闹时时间模块和比较闹时模块,其实我们还可以在CPLD内再扩展许多功能,设计方便,利于修改,且开发难度不高,很适合对于大规模的系统设计,还可以很容易在QuetusII中仿真系统工作时序
2.4方案选择
上述两个方案最大的区别就是:
方案一采用的是数字编码器等芯片,而方案二是用复杂可编程逻辑器件CPLD。
由于本设计针对电子钟设计使用,而且要求根据相应的要求进行功能扩展,使用CPLD在此方面更加有优势,,而且要维护方便,调试简单,稳定性好,功耗低。
基于上述两方案比较,论证,发现方案二更容易实现本次设计的要求,并且方案二的电路较简单,程序容易控制,,而且是EDA的热门技术,所以最终选择方案二。
3、设计实现
3.1晶体振荡电路模块
EP2C70F896的时钟电路比较简单,在其引脚DCLOCK输入时钟信号即可。
本系统采用的50M有源晶振。
3.3V电源电压对其供电,其原理图如图3.1所示:
图3.1晶振电路模
3.2电源电路模块
电源电路主要是为系统提供电源,因为CPLD是3.3V,故整个系统用3.3V,其主要结构是由220V市电通过一个变压器(TT)降压,再通过由二极管构成的整流桥转(B1212S)换成直流电,再通过滤波电路滤波和稳压芯片7805稳压,最后再经过滤波电路滤波后输出我们需要的5V直流电压。
其电路如图3.2。
图3.25V电源电路
图3.33.3V电源电路
3.3JTAG下载电路模块
JTAG下载电路是为EP2C70F896在程序用的,其原理图如图3.2所示:
图3.4JTAG下载电路
3.4显示电路模块
显示电路主要作用是显示延时间和抢答组数。
直接用CPLD驱动两个数码管显示,数码管为共阴极管,其电路原理图如下:
图3.5显示电路
3.5闹钟驱动电路模
报警电路用一个三极管驱动一个蜂鸣器产生,当时钟走到设定的闹钟时间后,CPLD的beer管脚会自动的给出高电平,驱动三极管,使蜂鸣器响:
图3.6蜂鸣报警电路
4、
/*引脚锁定基于DE2-70,芯片为EP2C70F896,信号定义如下:
clk50m:
50MHz时钟输入
mode:
模式选择0:
计时模式1:
设置闹钟模式
mcheck:
手动调整时间
turn:
手动调整时间时,在时、分之间选择
change:
对选中的数据调整
led_hour1,led_hour0,led_minu1,led_minu0,led_sec1,led_sec0:
时、分、秒的led输出
alert:
闹铃输出
ld_alert:
是否设置了闹铃
ld_hour,ld_min,ld_sec:
在调整时,指示选中了时、分还是秒*/
moduleclock(clk50m,mode,turn,change,mreset,led_hour1,led_hour0,led_minu1,
led_minu0,led_sec1,led_sec0,alert,ld_alert,ld_check,ld_hour,ld_min,ld_sec);
inputclk50m;
inputmode;//接key0键
inputturn;//接key1键
inputchange;//接key2键
inputmreset;//switch0复位,低电平有效
outputalert;//gpio0->IOA0
outputld_alert;//ledg0-led19
outputld_check;//ledg1-led22
outputld_hour;//ledr3-led13
outputld_min;//ledr9-led9
outputld_sec;//ledr7-led7
output[7:
0]led_hour1;
output[7:
0]led_hour0;
output[7:
0]led_minu1;
output[7:
0]led_minu0;
output[7:
0]led_sec1;
output[7:
0]led_sec0;
reg[1:
0]modestate;
//00:
计时模式;10:
闹钟模式;01:
手动调整模式;11:
非法模式
wirenowmode;//记录当前模式,0:
计时模式;1:
设置闹钟模式
wireischecking;//是否在手动调整时间
assign{nowmode,ischecking}=modestate;
always@(negedgemode)//两个按钮都是低电平有效
begin
case(modestate)
2'b00:
modestate<=2'b10;//设置闹钟模式优先
2'b10:
modestate<=2'b01;//手动调整模式
2'b01:
modestate<=2'b00;
default:
modestate<=2'b00;
endcase
end
wirereset,clk_1hz;
switch#(8)rmjitter(clk50m,mreset,reset);//reset=1时复位
clk50mto1gen1hz(clk50m,clk_1hz);//生成1Hz的时钟
wire[2:
0]selcode;//对turn信号在不同模式下的解码
bitselseldecoder(nowmode,ischecking,turn,selcode,reset);
wire[3:
0]clocktime0,clocktime1,clocktime2,clocktime3,clocktime4,clocktime5;
//计时输出的时钟数值
wireclockalarmon;//整点报时的闹钟输出
wire[2:
0]counterselcode;
assigncounterselcode=(modestate==2'b01)?
selcode:
3'b000;
counter_timeclock_time(clk_1hz,counterselcode,~change,clocktime5,
clocktime4,clocktime3,clocktime2,clocktime1,clocktime0,clockalarmon,reset);
wire[3:
0]alarmtime0,alarmtime1,alarmtime2,alarmtime3;//闹钟时间
wirealarmon;
alarm_timealarm_time(clk_1hz,nowmode,selcode[2:
1],change,
{clocktime5,clocktime4,clocktime3,clocktime2,clocktime1},
{alarmtime3,alarmtime2,alarmtime1,alarmtime0},alarmon,reset);
wirevoiceout;
alarmalarmvoice(clk50m,{clockalarmon,alarmon},voiceout,reset);
//显示输出部分
//调整位显示
assign{ld_hour,ld_min,ld_sec}=(ischecking||nowmode)?
selcode:
3'b000;
assignalert=voiceout;
reg[3:
0]showout2,showout3,showout4,showout5;
ledled5(showout5,1'b1,led_hour1);//led译码显示
ledled4(showout4,1'b0,led_hour0);
ledled3(showout3,1'b1,led_minu1);
ledled2(showout2,1'b0,led_minu0);
ledled1(clocktime1,1'b1,led_sec1);
ledled0(clocktime0,1'b1,led_sec0);
always
beginif(nowmode)//闹钟模式
beginshowout5=alarmtime3;showout4=alarmtime2;
showout3=alarmtime1;showout2=alarmtime0;end
elsebegin
showout5=clocktime5;showout4=clocktime4;
showout3=clocktime3;showout2=clocktime2;end
end
assignld_alert=nowmode;assignld_check=ischecking;
endmodule
/*alarm.v:
闹铃模块
clk50m:
50MHz输入时钟
alarmon:
闹铃是否打开,2'b00:
不打开;2'b01:
闹钟;2'b10:
整点报时
alarmout:
闹铃声音输出*/
modulealarm(clk50m,alarmon,alarmout,reset);
input[1:
0]alarmon;inputclk50m,reset;
outputregalarmout;reg[15:
0]counter_1k;wireclk_1k;
assignclk_1k=counter_1k[15];
always@(posedgeclk50m)
beginif(counter_1k==50000)counter_1k<=0;
elsecounter_1k<=counter_1k+1'b1;end
wireddd_du_out,ddd_out;
sound_ddd_duddd_du(clk_1k,alarmon[1],ddd_du_out);
sound_dddddd(clk_1k,alarmon[0],ddd_out);
always
beginif(!
reset)
beginif(alarmon[0]==1'b1)//ddd,闹钟的响铃优先级更高
alarmout=ddd_out;
elseif(alarmon==2'b10)alarmout=ddd_du_out;
elsealarmout=0;
endelsealarmout=0;
end
endmodule
/*alarm_time.v:
闹钟时间设定模块
enable:
使能信号
sel:
在时、分之间切换选择10:
时;01:
分
inc:
对选中的信号自增
basetime:
基准时钟*/
modulealarm_time(clk_1hz,enable,sel,inc,basetime,alarmouttime,alarm_on,reset);
inputclk_1hz,enable,inc,reset;
input[1:
0]sel;input[4*5-1:
0]basetime;outputregalarm_on;
output[4*4-1:
0]alarmouttime;
reg[3:
0]hour1,hour0,minu1,minu0;//存储的设定时间
always@(posedgeincorposedgereset)
beginif(reset)//reset=1时复位
begin{hour1,hour0,minu1,minu0}<=16'h0;end
elsebegin
if(enable)begin
if(sel==2'b10)//设置时
beginif({hour1,hour0}==8'h23){hour1,hour0}<=8'h00;
elseif(hour0==9)
beginhour0<=0;hour1<=hour1+1'b1;end
elsehour0<=hour0+1'b1;
end
elseif(sel==2'b01)//设置分
beginif({minu1,minu0}==8'h59){minu1,minu0}<=8'h00;
elseif(minu0==4'h9)
beginminu0<=4'h0;minu1<=minu1+4'h1;end
elseminu0<=minu0+4'h1;end
else{hour1,hour0,minu1,minu0}<=16'h0;
endend
end
always//闹钟开始条件
begin
if(({hour1,hour0,minu1,minu0}==basetime[(4*5-1):
4])&&(basetime[3:
0]<2))
alarm_on=1'b1;
elsealarm_on=1'b0;end
assignalarmouttime={hour1,hour0,minu1,minu0};
endmodule
/*counter_time.v:
计时模块,并留有调整接口;
check:
调整信号,3位,分别调整时、分、秒,调整方法:
将计数输出给加法器,把调整信息
转换成异步置数信息,将加法器的输出作为置数值;
hour1,hour0,minu1,minu0,sec1,sec0:
输出的计时时钟;
alarmout:
整点报时输出*/
modulecounter_time(clk_1hz,check,inc,hour1,hour0,minu1,minu0,sec1,sec0,
alarmout,reset);
inputclk_1hz,inc,reset;input[2:
0]check;
output[3:
0]hour1,hour0,minu1,minu0,sec1,sec0;
outputregalarmout;
regclk_1hz_md;wire[6:
0]carryclk;
reg[5:
0]incplus;//自增脉冲
wire[5:
0]carry;//进位时钟
wire[3:
0]adderout0,adderout1,adderout2,adderout3,adderout4,adderout5;
wire[3:
0]timerout0,timerout1,timerout2,timerout3,timerout4,timerout5;
hexcountercounter_sec0(carryclk[0],reset,4'd9,4'b0,timerout0,carry[0]);
hexcountercounter_sec1(carryclk[1],reset,4'd5,4'b0,timerout1,carry[1]);
hexcountercounter_minu0(carryclk[2],reset,4'd9,4'b0,timerout2,carry[2]);
hexcountercounter_minu1(carryclk[3],reset,4'd5,4'b0,timerout3,carry[3]);
wire[3:
0]hour0max;
assignhour0max=(timerout5==4'h2)?
(4'h3):
(4'h9);
hexcountercounter_hour0(carryclk[4],reset,hour0max,4'b0,timerout4,carry[4]);
hexcountercounter_hour1(carryclk[5],reset,4'd2,4'b0,timerout5,carry[5]);
//每个计时器的时钟,由前级进位和自增脉冲相加得到
assigncarryclk[0]=clk_1hz_md|incplus[0];
assigncarryclk[1]=carry[0]|incplus[1];
assigncarryclk[2]=carry[1]|incplus[2];
assigncarryclk[3]=carry[2]|incplus[3];
assigncarryclk[4]=carry[3]|incplus[4];
assigncarryclk[5]=carry[4]|incplus[5];
always//对异步置位信号进行解码
begincase(check)
3'b001:
beginclk_1hz_md=0;
incplus={5'b00000,inc};end
3'b010:
beginclk_1hz_md=0;
incplus={3'b000,inc,2'b00};end
3'b100:
begin//在正常的调节状态中
clk_1hz_md=0;
incplus={1'b0,inc,4'b000};end
default:
beginincplus=6'b000000;
clk_1hz_md=clk_1hz;end
endcaseend
always
beginif((timerout3==0)&&(timerout2==0)&&(timerout1<2))alarmout=1;
//时间小于20秒的时间内
elsealarmout=0;end
assignhour1=timerout5;assignhour0=timerout4;
assignminu1=timerout3;assignminu0=timerout2;
assignsec1=timerout1;assignsec0=timerout0;
endmodule
/*clk50mto1.v:
50mhz时钟分频到1hz*/
moduleclk50mto1(clk50m,clk1hz);
inputclk50m;outputclk1hz;
reg[25:
0]counter_1hz;//从50mhz分频到1hz的计数器
assignclk1hz=counter_1hz[25];
always@(posedgeclk50m)
beginif(counter_1hz==50000000)counter_1hz<=0;
elsecounter_1hz<=counter_1hz+1'b1;end
endmodule
/*led.v:
led译码显示模块,该模块与上节数字跑表中的led模块相同*/
moduleled(datain,dotin,ledout);
parameterINWIDTH=4;
parameterOUTWIDTH=8;
input[INWIDTH-1:
0]datain;inputdotin;
output[OUTWIDTH-1:
0]ledout;reg[OUTWIDTH-2:
0]dataout;wiredotout;
assignledout[OUTWIDTH-1:
1]=dataout;
assignledout[0]=dotout;
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数字钟 张港 数字