1、数字时钟及闹钟 1目录一、实验任务 2实验目的 2实验要求 2二、设计思路 2硬件部分 2软件部分 3三、完成情况 6四、总结与收获 7具体分工 7五、完整程序 8数字时钟及闹钟 2一、实验任务实验目的1. 深入了解基于 EDA 工具的复杂时序逻辑电路的设计。2. 理解并熟练利用 EDA 工具进行综合设计。3. 熟练掌握芯片烧录的流程及步骤。4. 掌握 Verilog HDL 语言的语法规范及时序电路描述方法。5. 掌握多个数码管动态扫描与键盘扫描的显示原理及设计方法。实验要求设计一个带闹钟功能的 24 小时数字钟,它包括以下几个组成部分: 显示屏,由 4 个七段数码管组成,用于显示当前时间(
2、时:分)或设置的闹钟时间; 数字键 09 ,用于输入新的时间或新的闹钟时间; TIME(时间)键,用于确定新的时间设置; ALARM(闹钟)键,用于确定新的闹钟时间设置,或显示已设置的闹钟时间; 扬声器,在当前时钟时间与闹钟时间相同时,发出蜂鸣声。基本要求(1) 计时功能:这是本计时器设计的基本功能,每隔一秒计时一次,并在显示屏上显示当前时间。(2) 闹钟功能:如果当前时间与设置的闹钟时间相同,则扬声器发出蜂鸣声。(3) 设置新的计时器时间:用户用数字键09输入新的时间,然后按“TIME“键确认。发挥部分(1) 设置新的闹钟时间:用户用数字键“0”“9”输入新的时间,然后按“ALARM”键确认
3、。(2) 显示所设置的闹钟时间:在正常计时显示状态下,用户直接按下“ALARM”键,则已设置的闹钟时间将显示在显示屏上。二、设计思路硬件部分本次数字时钟的设计主要在 NC-EDA-2000C 实验箱上完成,应用的芯片为 Altara 公司的 EP1K10TC1003 芯片。该芯片具有低内核电压、低功耗的特点。芯片内门电路高达 1 万门,内部使用 RAM 作电路结构,速度高达几百 MHZ,其输出可用管脚已全部开放,位于芯片的四周,用户可以根据自己的要求和芯片本身的功能自己任意定义管脚。同时为了体现实验箱的可扩展性,在芯片的两边各有一个 34 脚的 IDE 插口,可以通过数据排线与其它应用模块相连
4、接。数字时钟及闹钟 3除了主芯片外,主要包括三大部分:八个数码管组成的显示部分、44 键盘构成的按键输入部分。以及其他输入或输出部分,如:“TIME“键、 “ALARM”键、时钟信号、蜂鸣器等。8 位 7 段数码管:采用 2 个进口共阴高红 7 段数码管组成,其连接管脚位选信号在数码管的左边由连接孔 SEL0、SEL1、SEL2 与其它模块连接。数码管显示的设计示意图如下:八位数码管显示设计示意图44 键盘: 44 键盘主要是通过编程实现 0F 的输入,也可以作为一个控制键。在其上方的连接孔 R1、R2、R3、R4 控制横向 4 位;C1、C2、C3、C4 纵向 4 位。键盘输入设计示意图如下
5、:44 键盘输入设计示意图软件部分软件主要应用软件 quartus,使用 Verilog HDL 语言来编写程序。在老师所给的keyscan 的基础上加入计时部分、设置部分(时间的设置和闹钟的设置)以及闹铃部分。a) 计时部分always(posedge clkl) /计时过程beginhour=Hour;minute=Minute;if(reset) begin hour=0;minute=0;second=0;endelseif(second=59)if(minute=59)if(hour =23) begin second=0;minute=0;hour=0;end数字时钟及闹钟 4el
6、se begin second=0;minute=0;hour=hour+1;endelse begin second=0;minute=minute+1;endelse second=second+1;end其中,clkl 为 1Hz 的时钟信号,当每遇到一个时钟信号的上升沿时,秒钟就加 1 秒;当加到 59 时,分钟就加 1,秒钟自动回到 0 重新计时;当分钟加到 59 时,时钟就加 1,然后分钟回到 0;当计时到 23:59:59 时,则回到 00:00:00 再进入计时。reset 为清零信号,高电平有效。b) 设置部分always (posedge clkh)beginif(w=1)
7、/设置时间begin Hour=num1*10+num2; Minute=num3*10+num4; endelse if(p=1) /设置闹钟begin Ahour=num1*10+num2; Aminute=num3*10+num4; endend将按下的键值存在 num1、num2、num3、num4 中,再通过 w 和 p 即所谓的 TIME(时间)键与 ALARM(闹钟)键将输入的数值赋给初始时间或闹钟时间。c) 闹铃部分always (posedge clkh)/闹钟响beginif(hour=Ahour) else ds=0;end当设置的闹钟时间(时:分)与当前的时间(时:分)
8、相等时,则闹铃发出响声;ds信号可以接在蜂鸣器上或者发光二极管上。本次设计的完整程序已附在报告的最后。整体程序编译无误。程序中涉及的变量名称及其对应的变量意义:数字时钟及闹钟 5引脚配置图数字时钟及闹钟 6三、完成情况在这次实验过程中我们完成了 24 小时数字时钟的设计。时钟的显示屏为七段数码管。显示出的时间格式为小时、分钟、秒钟(如图 1) 。时钟含有闹钟,可以在程序中设置闹钟时间,在实际时间和闹钟时间相吻合时蜂鸣器响。图 2 中的二极管亮即可说明,在闹钟时间可以输出高电平,该输出接在蜂鸣器上即可使蜂鸣器响。本次设计的闹钟为响 1 分钟自动关闭。图 3 中二极管熄灭。图 1 时间显示图 2
9、闹钟响(体现为发光二极管发光)数字时钟及闹钟 7图 3 发光二极管熄灭(本次设计的闹钟为响 1 分钟自动关闭)四、总结与收获在实验设计的过程中,我们首先尝试了树上和老师上课时所讲的例程,在熟悉软件和设计流程后开始了数字时钟的设计。在设计数字时钟时,我们先分设计出来时钟的自动计数显示,实现了 24 小时时钟。之后实验了 4*4 键盘,实现了键盘输入值的扫描读取。最后设计了闹钟部分,包括设置闹钟时间和到时间闹铃响。我们通过本次实验深入了解基于 EDA 工具的复杂时序逻辑电路的设计,理解并熟练利用 quartus 进行 Verilog HDL 语言的设计。掌握了建立工程项目,编译调试程序,下载程序的
10、流程和步骤。在应用的过程中掌握了数码管和键盘扫描的原理和方法。并且对Verilog HDL 语言的语法规则和几种常用语句有了更深入的理解。实验过程中通过合作的方式,小组成员积极讨论,对不同的语句进行了对比,最终确定了本次实验的完整程序。这次完成的数字时钟只是 EDA 实验箱中可以实现的众多功能之一,我们也认识到Verilog HDL 语言可以实现的设计还有很多,本次实验激发了我们对 Verilog HDL 语言的兴趣,也让我们认识到课堂的学习是有限的,想更加深入学习 Verilog HDL 语言,还要在今后的学习中多多自学,勤加练习。五、完整程序module zonghe (clkl,clkh
11、,reset,q,w,p,kr,kc,a,b,c,d,e,f,g,sa,sb,sc,ds);input clkl,clkh,reset; /计数时钟脉冲、扫描频率脉冲与复位信号input q,w,p; /启动设置的控制信号、设置时间的控制信号及设置闹钟的控制信号 inout 3:0kr; /4*4 键盘的行输入/输出信号数字时钟及闹钟 8inout 3:0kc; /4*4 键盘的列输入/输出信号output a,b,c,d,e,f,g,sa,sb,sc,ds; /LED 的 7 个片选信号与 3 个位选信号reg a,b,c,d,e,f,g,sa,sb,sc,ds;reg 3:0kr,kc;r
12、eg 6:0 display ; reg 2:0 dcount,kcount; reg 3:0keyr,keyc; reg kflag1,kflag2; reg 6:0 buff7 ;reg 3:0 shiwei1,gewei1,shiwei2,gewei2,shiwei3,gewei3;reg5:0 hour,minute,second,Ahour,Aminute,Hour,Minute; /储存当前时间的时分秒、闹钟的时分及设置的时间的时分always(posedge clkh) /累加两个计数值begin dcount=dcount+1; kcount=kcount+1;endalway
13、s (posedge clkh) /扫描键盘 begin if(kcount=0) beginkr=4b1111;kc=4b0000;endelse if(kcount=1) beginkeyr=kr; kr=4bZZZZ;endelse if(kcount=2) beginkr=4b0000;kc=4b1111;endelse if(kcount=3) beginkeyc=kc;kc=4bZZZZ;endendalways(posedge clkh) /改变键的标志位 数字时钟及闹钟 9beginif(kcount=4 else if(kcount=4) kflag1=1; kflag2=k
14、flag1;end always(posedge clkh) / 获取相应按键按下的结果begin if(kcount=5) if(keyr=4b1110)case (keyc) 4b1110:buff7=7b0111111; /在 LED 上显示 04b1101:buff7=7b0000110; /在 LED 上显示 14b1011:buff7=7b1011011; /在 LED 上显示 24b0111:buff7=7b1001111; /在 LED 上显示 3default :buff7=buff7; /无变化endcaseelse if (keyr=4b1101) case (keyc)
15、4b1110:buff7=7b1100110; /在 LED 上显示 44b1101:buff7=7b1101101; /在 LED 上显示 54b1011:buff7=7b1111101; /在 LED 上显示 64b0111:buff7=7b0000111; /在 LED 上显示 7default :buff7=buff7; / 无变化endcaseelse if(keyr=4b1011) case (keyc) 4b1110:buff7=7b1111111; / 在 LED 上显示 84b1101:buff7=7b1101111; / 在 LED 上显示 94b1011:buff7=7b
16、1110111; /在 LED 上显示 a4b0111:buff7=7b1111100; /在 LED 上显示 bdefault :buff7=buff7; / 无变化endcaseelse if(keyr=4b0111)case (keyc) 4b1110:buff7=7b0111001; /在 LED 上显示 c4b1101:buff7=7b1011110; /在 LED 上显示 d4b1011:buff7=7b1111001; /在 LED 上显示 e4b0111:buff7=7b1110001; / 在 LED 上显示 fdefault:buff7=buff7; /无变化endcase
17、 end数字时钟及闹钟 10always(posedge clkh) /显示过程begin sa=dcount0; /将 dcount 赋给 LED 的三个片选信号sb=dcount1;sc=dcount2;shiwei1=hour/10;gewei1=hour%10;shiwei2=minute/10;gewei2=minute%10;shiwei3=second/10;gewei3=second%10;if(dcount=3b111)/判断位选 dcount 的值,并将此位上的值输出到数码管case(shiwei1) /在第一数码管上显示时钟的十位4b0000: display = 7b0
18、111_111;4b0001: display= 7b0000_110;4b0010: display = 7b1011_011;4b0011: display = 7b1001_111;4b0100: display = 7b1100_110;4b0101: display = 7b1101_101;4b0110: display = 7b1111_101;4b0111: display = 7b0000_111;4b1000: display = 7b1111_111;4b1001: display = 7b1101_111; default: display = 7b0000_000;e
19、ndcaseif(dcount=3b000) /在第二个数码管上显示时钟的个位case(gewei1)4b0000: display = 7b0111_111;4b0001: display = 7b0000_110;4b0010: display = 7b1011_011;4b0011: display = 7b1001_111;4b0100: display = 7b1100_110;4b0101: display = 7b1101_101;4b0110: display = 7b1111_101;4b0111: display = 7b0000_111;4b1000: display =
20、 7b1111_111;4b1001: display = 7b1101_111; default: display = 7b0000_000;endcaseif(dcount=3b001) /在第三个数码管上显示分钟的十位数字时钟及闹钟 11case(shiwei2)4b0000: display = 7b0111_111;4b0001: display = 7b0000_110;4b0010: display = 7b1011_011;4b0011: display = 7b1001_111;4b0100: display = 7b1100_110;4b0101: display = 7b
21、1101_101;4b0110: display = 7b1111_101;4b0111: display = 7b0000_111;4b1000: display = 7b1111_111;4b1001: display = 7b1101_111; default: display = 7b0000_000;endcaseif(dcount=3b010) /在第四个数码管上显示分钟的个位case(gewei2)4b0000: display = 7b0111_111;4b0001: display = 7b0000_110;4b0010: display = 7b1011_011;4b001
22、1: display = 7b1001_111;4b0100: display = 7b1100_110;4b0101: display = 7b1101_101;4b0110: display = 7b1111_101;4b0111: display = 7b0000_111;4b1000: display = 7b1111_111;4b1001: display = 7b1101_111; default: display = 7b0000_000;endcaseif(dcount=3b011) /在第五个数码管上显示秒钟的十位case(shiwei3)4b0000: display =
23、7b0111_111;4b0001: display = 7b0000_110;4b0010: display = 7b1011_011;4b0011: display = 7b1001_111;4b0100: display = 7b1100_110;4b0101: display = 7b1101_101;4b0110: display = 7b1111_101;4b0111: display = 7b0000_111;4b1000: display = 7b1111_111;4b1001: display = 7b1101_111; default: display = 7b0000_0
24、00;endcaseif(dcount=3b100) /在第六个数码管上显示秒钟的个位case(gewei3)数字时钟及闹钟 124b0000: display = 7b0111_111;4b0001: display = 7b0000_110;4b0010: display = 7b1011_011;4b0011: display = 7b1001_111;4b0100: display = 7b1100_110;4b0101: display = 7b1101_101;4b0110: display = 7b1111_101;4b0111: display = 7b0000_111;4b1
25、000: display = 7b1111_111;4b1001: display = 7b1101_111; default: display = 7b0000_000;endcase if(dcount=3b101) display =7b1000_000; /在第七个数码管上显示“”if(dcount=3b110) display =buff7; /在第八个数码管上显示按下的键值endalways (posedge clkh) /将 display 中存的值赋给 LED 的七个片选信号 begin a=display0;b=display1;c=display2;d=display3;
26、e=display4;f=display5;g=display6;end always(posedge clkl) /计时过程 clkl 的频率为 1Hzbeginhour=Hour;minute=Minute; /将设置的时间(时、分)赋给 hour 和 minuteif(reset) begin hour=0;minute=0;second=0; end /当 reset 为 1 时,将时间清零即为 00:00:00else /正常计时if(second=59)if(minute=59)if(hour =23) begin second=0;minute=0;hour=0;endelse
27、begin second=0;minute=0;hour=hour+1;endelse begin second=0;minute=minute+1;endelse second=second+1;数字时钟及闹钟 13endinteger i; /记录按键按下的次数reg 3:0num1,num2,num3,num4; /储存按键的键值always (posedge clkh)/储存按下的键值beginif(q=1)/启动设置begini=0;if(keyc!=4b1111) i=i+1; /当有键按下时, i 自动加 1if(i=1) /将第一个按下的按键值存入 num1begincase
28、(keyr,keyc) 4b1110_1110:num1=0; 4b1110_1101:num1=1; 4b1110_1011:num1=2; 4b1110_0111:num1=3; 4b1101_1110:num1=4; 4b1101_1101:num1=5; 4b1101_1011:num1=6; 4b1101_0111:num1=7; 4b1011_1110:num1=8; 4b1011_1101:num1=9; default:num1=num1; endcaseendif(i=2) /将第二个按下的按键值存入 num2begincase (keyr,keyc) 4b1110_1110
29、:num2=0; 4b1110_1101:num2=1; 4b1110_1011:num2=2; 4b1110_0111:num2=3; 4b1101_1110:num2=4; 4b1101_1101:num2=5; 4b1101_1011:num2=6; 4b1101_0111:num2=7; 4b1011_1110:num2=8; 4b1011_1101:num2=9; default:num2=num2; endcaseendif(i=3) /将第三个按下的按键值存入 num3数字时钟及闹钟 14begincase (keyr,keyc) 4b1110_1110:num3=0; 4b11
30、10_1101:num3=1; 4b1110_1011:num3=2; 4b1110_0111:num3=3; 4b1101_1110:num3=4; 4b1101_1101:num3=5; 4b1101_1011:num3=6; 4b1101_0111:num3=7; 4b1011_1110:num3=8; 4b1011_1101:num3=9; default:num3=num3; endcaseendif(i=4) /将第四个按下的按键值存入 num4begincase (keyr,keyc) 4b1110_1110:num4=0; 4b1110_1101:num4=1; 4b1110_
31、1011:num4=2; 4b1110_0111:num4=3; 4b1101_1110:num4=4; 4b1101_1101:num4=5; 4b1101_1011:num4=6; 4b1101_0111:num4=7; 4b1011_1110:num4=8; 4b1011_1101:num4=9; default:num4=num4; endcaseendendendalways (posedge clkh) /设置部分beginif(w=1)/设置时间begin Hour=num1*10+num2; Minute=num3*10+num4; endelse if(p=1) /设置闹钟时间begin Ahour=num1*10+num2; Aminute=num3*10+num4; endendalways (posedge clkh)/闹钟响begin数字时钟及闹钟 15if(hour=Ahour) /当设置的闹钟时间与当前时间相同时发出警报else ds=0;endendmodule