数字时钟设计.docx
《数字时钟设计.docx》由会员分享,可在线阅读,更多相关《数字时钟设计.docx(11页珍藏版)》请在冰豆网上搜索。
![数字时钟设计.docx](https://file1.bdocx.com/fileroot1/2022-11/19/91f45f53-3c33-4029-a9f4-6f1b79b68776/91f45f53-3c33-4029-a9f4-6f1b79b687761.gif)
数字时钟设计
数字时钟电路设计
1设计任务
题目:
数字时钟设计
基本功能要求:
1.能够计到分和秒。
2.有一个开始计时、一个暂停计时、一个复位按键
发挥要求:
有预置和校时功能
其他要求:
1.系统时钟采用12MHz有源晶振
2.主芯片采用CPLD器件,型号为ALTERA的EPM7064SL-44
3.采用数码管显示
2设计方案
该设计主要包括几个部分:
电源部分、数码管显示部分、时钟电路部分、按键部分、主芯片部分、程序下载电路部分。
本实验用到的实验仪器是3.3V稳压供电电源、PC机、JTAG下载线,以及基于FPGA的Altera公司的实验开发试验箱。
焊电路板时还需要电烙铁、焊锡、镊子等。
设计原理框图如下:
图1系统原理框图
时钟电路
晶体振荡器,简称晶振,是利用了晶体的压电效应制造的,当在晶片的两面上加交变电压时,晶片会反复的机械变形而产生振动,而这种机械振动又会反过来产生交变电压。
当外加交变电压的频率为某一特定值时,振幅明显加大,比其它频率下的振幅大得附加外部时钟电路,一般是一个放大反馈电路,只有一片晶振是不能实现震荡的多,产生共振,这种现象称为压电谐。
图2.系统原理图
晶体振荡器电路给数字钟提供一个品种稳定准确的方波信号,可保证数字钟的走私准确及稳定。
与晶振并联的电阻的作用——与晶振并联的电阻R17是反馈电阻,是为了保证反相器输入端的工作点电压在VDD/2,这样在振荡信号反馈在输入端时,能保证反相器工作在适当的工作区。
虽然去掉该电阻时,振荡电路仍工作了。
但是如果从示波器看振荡波形就会不一致了,而且可能会造成振荡电路因工作点不合适而停振。
所以千万不要省略此电阻。
这个电阻是为了使本来为逻辑反相器的器件工作在线性区,以获得增益,在饱和区是没有增益的,没有增益是无法振荡的。
如果用芯片中的反相器来作振荡,必须外接这个电阻,对于CMOS而言可以是1M以上,对于TTL则比较复杂,视不同类型(S,LS…)而定。
图3.晶振电路
按键电路
按键电路为了实现该设计的基本功能,通过按键电路实现计数时钟的的开启和暂停功能。
图4.按键电路
电源电路
本次课程设计所使用的电源是由外界直接提供的,直接给板子供电。
显示电路
在应用数码管显示时,首先需要考虑的问题就是驱动电流,与发光二极管相同,数码管的发光段也需要串联限流电阻,共阳极数码管为例,串联的限流阻值越大,电流越小,亮度越低;电阻值越小,电流越大,亮度越高。
在使用限流电阻时需要在每一段线上都串联限流电阻,而不要在公共端上串联电阻,如果只是在公共端上串联一个限流电阻,则显示不同数字是,将会造成数码管亮度的不同。
在动态显示时,每个数码管的断连线是对应连接在一起的,同时由于数码管不存在同时点亮状态,所以只需在段连线的引出端上串联限流电阻即可。
图9.数码管驱动电路
芯片EPM7064简介
CPLD(ComplexProgrammableLogicDevice)复杂可编程逻辑器件,是从PAL和GAL器件发展出来的器件,相对而言规模大,结构复杂,属于大规模集成电路范围。
是一种用户根据各自需要而自行构造逻辑功能的数字集成电路。
其基本设计方法是借助集成开发软件平台,用原理图、硬件描述语言等方法,生成相应的目标文件,通过下载电缆(“在系统”编程)将代码传送到目标芯片中,实现设计的数字系统.本文采用ALTERA公司的MAX7000s,它是基于第二代MAX结构的高精度、高性能、在系统中可编程的CPLD芯片,采用CMOS技术加工而成,内含电可擦除只读存储器,可提供600~5000个可用选通引脚、ISP、速度仅有5ns的延迟以及频率可达175.4MHZ的高速计数器。
图10.EPM7064
3设计程序
引脚配置
总结及心得
遇到的问题:
1焊接时,由于三极管的管脚距离太近,焊接时很容易管脚发生连焊.
2焊好后,JTAG接口无法正常下载程序(经检查,是当时焊接时,烙铁温度过高,导致一个管脚的焊盘脱落,不导电所致)
3:
数码管有的不亮,可能是有虚焊,用手按着某个器件会发现数码管会亮。
解决方法:
1我们通过把电烙铁侧拿、只用一个角与三极管和焊锡接触,以此来避免出现管脚相。
连的现象发生。
2:
通过先把芯片放在别人的能下载的电路板上下载程序,再放到我们的电路板上。
3:
重点检查芯片座是否明显虚焊,一般故障发生在插座上。
检查虚焊的方法:
1:
用电压表的两个表笔分别同时接触三极管的任意两个管脚,检测是否有连焊的现象:
2:
用电压表的两个表笔分别测量电路,看是否有虚焊;当检测一条线路时,若电压/电流表发出蜂鸣声,说明此线路没有虚焊的部分,反之,则需要逐段检查,直到找出为止。
测试结果:
给焊好的电路板供3.3V的电压,然后通过JTAG接口用PC机给EPM7064的电路主芯片下载程序,看电路板芯片是否正常工作,时钟是否能正确显示,暂停、复位等功能是否能用。
经测试,在本电路板上能正常工作,且能实现暂停、复位功能。
心得:
这次课程设计让我把这学期的所学,像Verilog仿真,数字系统的设计等重新复习一遍,为以后的其他课程的开展奠定了良好的基础。
更让我初步掌握了EPM7064系列芯片的结构、功能和使用方法,老师说过这门功课本来就是很实用的一门技术,这次的课程设计不仅加强了我的专业知识,而且增强了迎接未来可能碰到的难题的信心。
通过这次专业实践,受益匪浅,感谢老师们给我们提供这样的机会。
参考文献
【1】《Verilog数字系统设计教程》夏雨闻北航出版社;
【2】《电子技术基础》康华光高等教育出版社;
【3】黄正瑾,徐坚,章小丽,等.CPLD系统设计技术入门与应用[M].北京:
电子工业社.2002.
附录一:
源程序
moduleclock(clk,key,dig,seg);//模块名clock
inputclk;//输入时钟
input[1:
0]key;//输入按键
output[3:
0]dig;//数码管选择输出引脚
output[7:
0]seg;//数码管段输出引脚
reg[7:
0]seg_r;//定义数码管输出寄存器
reg[3:
0]dig_r;//定义数码管选择输出寄存器
reg[3:
0]disp_dat;//定义显示数据寄存器
reg[22:
0]count;//定义计数寄存器
reg[15:
0]hour;//定义现在时刻寄存器
regsec,keyen;//定义标志位
reg[1:
0]dout1,dout2,dout3;//寄存器
wire[1:
0]key_done;//按键消抖输出
assigndig=dig_r;//输出数码管选择
assignseg=seg_r;//输出数码管译码结果
//秒信号产生部分
always@(posedgeclk)//定义clock上升沿触发
begin
count=count+1'b1;
if(count==23'd6000000)//0.5S到了吗?
begin
count=23'd0;//计数器清零
sec=~sec;//置位秒标志
end
end
//按键消抖处理部分
assignkey_done=(dout1|dout2|dout3);//按键消抖输出
always@(posedgecount[17])
begin
dout1<=key;
dout2<=dout1;
dout3<=dout2;
end
always@(negedgekey_done[0])
begin
keyen=~keyen;//将琴键开关转换为乒乓开关
end
//数码管动态扫描显示部分
always@(posedgeclk)//count[17:
15]大约1ms改变一次
begin
case(count[17:
15])//选择扫描显示数据
3'd0:
disp_dat=hour[3:
0];//秒个位
3'd1:
disp_dat=hour[7:
4];//秒十位
//3'd2:
disp_dat=4'ha;//显示"-"
3'd2:
disp_dat=hour[11:
8];//分个位
3'd3:
disp_dat=hour[15:
12];//分十位
//3'd5:
disp_dat=4'ha;显示"-"
//3'd6:
disp_dat=hour[19:
16];时的个位
//3'd7:
disp_dat=hour[23:
20];时的十位
endcase
case(count[17:
15])//选择数码管显示位
3'd0:
dig_r=4'b1110;//选择第一个数码管显示
3'd1:
dig_r=4'b1101;//选择第二个数码管显示
3'd2:
dig_r=4'b1011;//选择第三个数码管显示
3'd3:
dig_r=4'b0111;//选择第四个数码管显示
//3'd4:
dig_r=4'b1111;//选择第五个数码管显示
//3'd5:
dig_r=8'b11011111;//选择第六个数码管显示
//3'd6:
dig_r=8'b10111111;//选择第七个数码管显示
//3'd7:
dig_r=8'b01111111;//选择第八个数码管显示
endcase
end
always@(posedgeclk)
begin
case(disp_dat)
4'h0:
seg_r=8'hc0;//显示0
4'h1:
seg_r=8'hf9;//显示1
4'h2:
seg_r=8'ha4;//显示2
4'h3:
seg_r=8'hb0;//显示3
4'h4:
seg_r=8'h99;//显示4
4'h5:
seg_r=8'h92;//显示5
4'h6:
seg_r=8'h82;//显示6
4'h7:
seg_r=8'hf8;//显示7
4'h8:
seg_r=8'h80;//显示8
4'h9:
seg_r=8'h90;//显示9
//4'ha:
seg_r=8'hbf;//显示-
default:
seg_r=8'hff;//不显示
endcase
//if((count[17:
15]==3'd2)&sec)
//seg_r=8'hff;
end
//计时处理部分
always@(negedgesecornegedgekey_done[1])//计时处理
begin
if(!
key_done[1])//是清零键吗?
begin
hour=23'h0;//是,则清零
end
elseif(!
keyen)
begin
hour[3:
0]=hour[3:
0]+1'b1;//秒加1
if(hour[3:
0]=