数字时钟设计含完整程序.docx
《数字时钟设计含完整程序.docx》由会员分享,可在线阅读,更多相关《数字时钟设计含完整程序.docx(19页珍藏版)》请在冰豆网上搜索。
数字时钟设计含完整程序
电子时钟设计
一、实验目的
学习8051定时器时间计时处理、按键扫描及LED数码管显示的设计方法。
二、设计任务及要求
利用实验平台上4个LED数码管,设计带有闹铃功能的数字时钟,要求:
1.在4位数码管上显示当前时间,显示格式为“时时分分”;
2.由LED闪动做秒显示;
3.利用按键可对时间及闹玲进行设置,并可显示闹玲时间。
当闹玲时间到蜂鸣器发出声响,按停止键使可使闹玲声停止。
三、工作原理及设计思路
利用单片机定时器完成计时功能,定时器0计时中断程序每隔5ms中断一次并当作一个计数,每中断一次计数加1,当计数200次时,则表示1s到了,秒变量加1,同理再判断是否1min钟到了,再判断是否1h到了。
为了将时间在LED数码管上显示,可采用静态显示法和动态显示法,由于静态显示法需要数据锁存器等较多硬件,可采用动态显示法实现LED显示。
闹铃声由交流蜂鸣器产生,电路如右图,当P1.7输出不同频率的方波,蜂鸣器便会发出不同的声音。
四、硬件电路设计及描述
由于扩展了外部存储器,P0口只能作地址/数据总线,P2口只能作地址总线高8位,P3.7、P3.6作为外部数据存储器读写信号。
P3.0、P3.1作为串行输入、输出接口,在仿真模式下完成与PC机的通信,故也不可用。
实验仪上单片机可用作I/O的口仅有:
P1.0--P1.7,8位;P3.2、P3.3、P3.4、P3.5,4位。
其中:
P1.0用作数据线SDA,P1.1用作时钟信号CLK,所以P1.0和P1.1应该接对应跳线的A位,即跳线的中间和下面相连。
P1.3、P1.4、P1.5和P1.6是四个数码管的位扫描线,其中P1.6对应数码管W1,显示小时高位;P1.5对应数码管W2,显示小时低位;P1.4对应数码管W3,显示分钟高位;P1.3对应数码管W4,显示分钟低位。
P1.7连接蜂鸣器电路,输出不同频率的方波,使其发出不同的声音。
P1.2用来控制秒的闪烁显示。
故,P1.2也应该接对应跳线的A位。
其显示电路如下图:
P3.2、P3.3、P3.4、P3.5分别连接单刀双掷开关S1、S2、S3、S4,从而输入高低电平。
将S2S1定义为功能模式选择开关;S3定义为分钟数调整开关;S4定义为小时数调整开关。
当S2S1=00时,显示当前时间,不进行任何操作。
当S2S1=01时,显示当前时间,同时可进行时钟调整,若S3=1,分钟数持续加1,若S4=1,小时数持续加1。
当S2S1=10时,显示闹钟时间,同时可进行闹钟调整,若S3=1,分钟数持续加1,若S4=1,小时数持续加1。
当S2S1=11时,显示当前时间,同时关闭闹钟。
音节由不同频率的方波产生,音节与频率的关系如表1所示。
要产生音频方波,只要算出某一音频的周期(1/频率),然后将此周期除以2,即为半周期的时间。
利用计时器计时此半周期时间,每当计时到后就将输出方波的I/0反相,然后重复计时此半周期时间再对I/O反相,就可在I/O脚得到此频率的方波。
在ZKS-03实验仪上,产生方波的I/O脚选用P1.7,通过跳线选择器JP1将单片机的P1.7与蜂鸣器的驱动电路相连。
这样P1.7输出不同频率的方波,蜂鸣器便会发出不同的声音。
另外,音乐的节拍是由延时实现的,如果1拍为0.4秒,1/4拍是0.1秒。
只要设定延时时间,就可求得节拍的时间。
延时作为基本延时时间,节拍值只能是它的整数倍,
每个音节相应的定时器初值X可按下法计算:
(1/2)*(1/f)=(12/fose)*(216-x)
即x=216-(fose/24f)
其中f:
音调频率,当晶振fose=11.0592MHz时,音节“1”相应的定时器初值为x,则可得x=63777D=F921H其它的可同样求得。
在单片机上控制一个音符唱多长可采用循环延时的方法来实现。
首先,我们确定一个基本时长的延时程序,比如说以十六分音符的时长为基本延时时间,那么,对于一个音符,如果它为十六分音符,则只需调用一次延时程序,如果它为八分音符,则只需调用二次延时程序,如果它为四分音符,则只需调用四次延时程序,依次类推。
通过上面关于一个音符音调和节拍的确定方法,我们就可以在单片机上实现演奏音乐了。
具体的实现方法为:
将乐谱中的每个音符的音调及节拍变换成相应的音调参数和节拍参数,将他们做成数据表格,存放在存储器中,通过程序取出一个音符的相关参数,播放该音符,该音符唱完后,接着取出下一个音符的相关参数……,如此直到播放完毕最后一个音符,根据需要也可循环不停地播放整个乐曲。
另外,对于乐曲中的休止符,一般将其音调参数设为FFH,FFH,其节拍参数与其他音符的节拍参数确定方法一致,乐曲结束用节拍参数为00H来表示。
五、软件设计流程及描述
六、源程序代码及注释
注:
首先将单片机用到的主要寄存器做下说明(如下);
P1.2作秒的闪烁控制位;
P1.7作响铃控制电平;
P3.2、P3.3作模式选择键S2、S1;
P3.4作分调整键S3(分钟数+1);
P3.5作时调整键S4(小时数+1);
R0为计数5ms的次数;R1为秒数;R2为分钟数;R3为时钟数;
R4在显示程序中作为向LED传递数据时的左移次数标志位;
R4在音乐闹铃程序中读取TABLE中的数据;
R5作为节拍长度;
40H作显示的分;41H作显示的时;42H作闹钟的分;43H作闹钟的时;
63H、64H存放延时程序DELAY的延时数;
60H、61H作定时器T1的初值。
;******************************主程序*******************************************
S1BITP3.2;定义模式选择键S2、S1
S2BITP3.3
S3BITP3.4;定义时调整键S4,分调整键S3
S4BITP3.5
SDABITP1.0
CLKBITP1.1
ORG0000H
AJMPMAIN
ORG000BH;T0的中断服务程序的入口地址
AJMPTIMER;跳转到时钟走时中断服务程序
ORG001BH;T1的中断服务程序的入口地址
AJMPALARM_OPEN;跳转到闹钟响铃中断服务程序
ORG0030H
MAIN:
MOV40H,#00;显示的分
MOV41H,#00;显示的时
MOV42H,#58;闹钟的分
MOV43H,#23;闹钟的时
MOVR0,#00H;寄存器清零(RO为计数5ms的次数,R1为秒数,
MOVR1,#00H;R2为分钟数,R3为时钟数)
MOVR2,#00H
MOVR3,#00H
MOVTMOD,#11H;设置T0,T1处于工作方式1
MOVTH0,#0EEH;设置定时器的初值
MOVTL0,#00H
SETBEA;允许总中断
SETBET0;允许T0,T1中断
SETBET1
SETBTR0;启动T0
LOOP:
LCALLDISPLAY1;调用显示程序
LCALLALARM;调用闹铃程序
LCALLMODE;调用模式判断程序
AJMPLOOP
;************************************时钟显示部分*******************************
DISPLAY1:
MOVDPTR,#TAB1
MOVA,41H
MOVB,#10
DIVAB
LCALLDISP1
CLRP1.6;LED1数码管显示数码,即小时的高位
LCALLDELAY
SETBP1.6
JBP1.2,TD;控制LED2数码管的小数点"dp"闪烁
AJMPTD1
TD:
MOVA,B
AJMPTD2
TD1:
MOVA,B
ADDA,#10
TD2:
LCALLDISP1;LED2数码管显示数码,即小时的低位
CLRP1.5
LCALLDELAY
SETBP1.5
MOVA,40H
MOVB,#10
DIVAB
LCALLDISP1
CLRP1.4;LED3数码管显示数码,即分钟的高位
LCALLDELAY
SETBP1.4
MOVA,B
LCALLDISP1
CLRP1.3;LED4数码管显示数码,即分钟的低位
LCALLDELAY
SETBP1.3
RET
DISP1:
MOVCA,@A+DPTR;LED串并转换口从P1.0接收
一个8位数码管显示字形数据
MOVR4,#08H;R4记作左循环的次数
DUP1:
RLCA;A带进位左循环移位
MOVSDA,C
CLRCLK;上升沿触发数据接收
SETBCLK
DJNZR4,DUP1
RET
;************************************闹钟显示部分*******************************
DISPLAY2:
MOVDPTR,#TAB1
MOVA,43H
MOVB,#10
DIVAB
LCALLDISP2
CLRP1.6;LED1数码管显示数码,即小时的高位
LCALLDELAY
SETBP1.6
MOVA,B
LCALLDISP2
CLRP1.5;LED2数码管显示数码,即小时的低位
LCALLDELAY
SETBP1.5
MOVA,42H
MOVB,#10
DIVAB
LCALLDISP2
CLRP1.4;LED3数码管显示数码,即分钟的高位
LCALLDELAY
SETBP1.4
MOVA,B
LCALLDISP2
CLRP1.3;LED4数码管显示数码,即分钟的低位
LCALLDELAY
SETBP1.3
RET
DISP2:
MOVCA,@A+DPTR;LED串并转换口从P1.0接收
一个8位数码管显示字形数据
MOVR4,#08H;R4记作左循环的次数
DUP2:
RLCA;A带进位左循环移位
MOVSDA,C
CLRCLK;上升沿触发数据接收
SETBCLK
DJNZR4,DUP2
RET
;********************************判断闹钟时间是否到来*************************
ALARM:
MOVA,40H
CJNEA,#00H,MUSIC;整点闹铃
LJMPB2
MUSIC:
MOVA,43H
CJNEA,41H,B1
MOVA,42H
CJNEA,40H,B1;音乐闹铃
SETBP1.7
MOV70H,#00H
NEXT:
MOVA,70H
MOVDPTR,#TABLE;从TABLE中读取数据——声响时间
MOVCA,@A+DPTR
MOVR4,A;将TABLE中读取的数据存放在R4
JZEND0
ANLA,#0FH
MOVR5,A;R5作为节拍长度
MOVA,R4
SWAPA
ANLA,#0FH
JNZSING
CLRTR1
JMPD1
SING:
DECA
MOV62H,A
RLA
MOVDPTR,#TABLE1;从TABLE1中读取数据——声调
MOVCA,@A+DPTR
MOVTH1,A;设定TH1值
MOV61H,A
MOVA,62H
RLA
INCA
MOVCA,@A+DPTR
MOVTL1,A;设定TL1值
MOV60H,A
MOVTH1,61H
MOVTL1,60H
SETBTR1
D1:
ACALLDELAY0;声音延时
INC70H
JMPNEXT
END0:
CLRTR1
JMPMUSIC
DELAY0:
MOVR7,#2;R5的值就是声响持续时间
D2:
MOVR6,#214
D3:
MOVR4,#245
DJNZR4,$
DJNZR6,D3
DJNZR7,D2
DJNZR5,DELAY0
RET
B1:
CLRTR1
RET
B2:
MOV61H,#0FEH
MOV60H,#033H
MOVTH1,61H
MOVTL1,60H;方波频率设为1KHz
SETBTR1
;********************************闹钟响铃中断服务程序**************************
ALARM_OPEN:
PUSHACC
PUSHPSW
MOVTH1,61H
MOVTL1,60H
CPLP1.7
POPPSW
POPACC
RETI
;********************************时钟走时中断服务程序***************************
TIMER:
MOVTH0,#0ECH;重新对T0赋值,设置中断时间为5ms
MOVTL0,#78H
MOV40H,R2
MOV41H,R3
INCR0;计数5ms的次数加1
CJNER0,#200,BACK;不够200次,跳转到BACK
CPLP1.2;够200次,P1.2翻转控制LED闪动一下
MOVR0,#00H;计数5ms的次数清0,秒数加1
INCR1
CJNER1,#60,BACK;不够60秒,跳转到BACK
MOVR1,#00H;够60秒,秒数清0,分钟加1
INCR2
CJNER2,#60,BACK;够60分钟,跳转到BACK
MOVR2,#00H;够60分钟,分钟数清0,小时数加1
INCR3
CJNER3,#24,BACK;够24小时,跳转到BACK
MOVR3,#00H;够24小时,小时数清0
BACK:
RETI
;************************************按键判断部分*******************************
MODE:
MOVA,P3;软件消抖后再判断
LCALLDELAY
CJNEA,P3,MODE
ANLA,#0CH;对S2、S1的值判断
CJNEA,#00H,LOP1
AJMPT_BACK;模式为00,开T1中断
LOP1:
CJNEA,#04H,LOP2
AJMPT_CHANGE;模式为01,进行时间调整
LOP2:
CJNEA,#08H,LOP3
AJMPA_CHANGE;模式为10,进行闹铃调整
LOP3:
AJMPA_CLOSE;模式为11,关闭闹钟
;.............................时钟调整...............................
T_CHANGE:
LCALLDISPLAY1
LCALLDELAY1
JNBS3,T_HOUR;S3为0,判断S4
T_MIN:
MOVR5,40H
INCR5;S3为1,分钟数加1
CJNER5,#60,LOP4
MOVR5,#00H
LOP4:
MOV40H,R5
MOVR2,40H
AJMPMODE
T_HOUR:
JNBS4,MODE;S4为0,跳转到MODE
MOVR5,41H
INCR5;S4为,小时数加1
CJNER5,#24,LOP5
MOVR5,#00H
LOP5:
MOV41H,R5
MOVR3,41H
AJMPMODE
;.............................闹铃调整................................
A_CHANGE:
LCALLDISPLAY2
LCALLDELAY2
JNBS3,A_HOUR;S3为0,判断S4
A_MIN:
MOVR5,42H
INCR5;S3为1,分钟数加1
CJNER5,#60,LOP6
MOVR5,#00H
LOP6:
MOV42H,R5
AJMPMODE
A_HOUR:
JNBS4,MODE;S4为0,跳转到MODE
MOVR5,43H
INCR5;S4为1,小时数加1
CJNER5,#24,LOP7
MOVR5,#00H
LOP7:
MOV43H,R5
AJMPMODE
;............................返回.................................
T_BACK:
SETBET1;开T1中断
RET
A_CLOSE:
CLRET1;关T1中断
RET
;************************************延时程序********************************
DELAY:
MOV63H,#5H;约2.78ms
D5:
MOV64H,#0FFH
DJNZ64H,$
DJNZ63H,D5
RET
;************************************延时程序1********************************
DELAY1:
MOVR7,#50H
D6:
LCALLDISPLAY1
DJNZR7,D6
RET
;************************************延时程序2********************************
DELAY2:
MOVR7,#50H
D7:
LCALLDISPLAY2
DJNZR7,D7
RET
;********************************数码管显示的字形表***************************
TAB1:
DB0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H;数字0~9,不带小数点"dp"
DB40H,79H,24H,30H,19H,12H,02H,78H,00H,10H;数字0~9,带小数点"dp"
;**********************************音乐的节拍表*******************************
TABLE:
DB82H,01H,81H,94H,84H,0B4H,0A4H,04H
DB82H,01H,81H,94H,84H,0C4H,0B4H,04H
DB82H,01H,81H,0F4H,0D4H,0B4H,0A4H,94H
DB0E2H,01H,0E1H,0D4H,0B4H,0C4H,0B4H,04H
DB82H,01H,81H,94H,84H,0B4H,0A4H,94H
DB0E2H,01H,0E1H,0D4H,0B4H,0C4H,0B4H,04H
DB82H,01H,81H,0F4H,0D4H,0B4H,0A4H,94H
DB0E2H,01H,0E1H,0D4H,0B4H,0C4H,0B4H,04H
DB00H
;***************************由音乐音符设置的T1计数值**************************
TABLE1:
DW64260,64440,64524,64580,64684,64777,64820,64898;音符计数值
DW64968,65030,65058,65110,65157,65178,65217
END
七、实验过程
将P1.0、P1.1、P1.3、P1.4、P1.5、P1.6、P3.0、P3.1的跳线接相应的A位,P1.7的跳线接相应的C位,拔掉其它不用的跳线。
插好电源,插好通信线,打开实验仪电源开关,在实验上将工作模式开关SX拨到“LOAD”一档,按下复位开头RESET,然后启动DPFlash,单击“编程”,在弹出的窗口中选中“编程MON51”,再按“确定”,就将程序下载到单片机的Flash中。
关闭DPFlash,启动Keil,新建一个工程,然后选择芯片(Philips——P80/P87C52X2)。
编写汇编语言程序,保存并添加至工程中,然后进行编译。
将实验台上的工作模式开关SX拨到“MON”位置,按下RESET复位开关,设置S0、S1、S3和S4的状态,再运行程序,拨动S0、S1、S3和S4对应的开头,检查电子时钟功能是否完整。
多次调试、修改程序,直至能正常实现设计的功能为止。
八、实验总结
这次做的单片机实验,有不少需要注意的问题,还遇到了很多问题,在解决问题的过程中也学到了很多东西。
首先是跳线的问题。
在仿真模式下,跳线选择器JP2中的P3.0、P3.1必须置A位。
其次是软件设置的问题。
刚开始没注意,一直出问题。
设置工程的工作环境,要按书上所讲解的进行一步一步设置。
而若是进行调试的话应将“编程MON51”下载到单片机的Flash中,而若要全速运行的话应将汇编程序生产的hex文件载入,并在编程窗口中选编程文件区将hex文件载入在单片机中。
另外还有一点值得注意的是,在进行调试时,编程的起始地址为4000H,对应中断的入口地址为400BH和401BH。
若是全速运行的情况下,编程的起始地址为0000H,对应中断的入口地址为000BH和001BH。
这是因为单片机的实际中断入口地址分别为