1系统分析 1.1功能 本文设计一款采用LED显示器件显示的电子时钟,有效克服了时钟存在的误差问题,并能在夜间不必其它照明就能看到时间,且以60只发光管实现秒显示,接近于传统的秒针来显示秒的形式。另加七只装饰用的LED灯,使整个时钟显的相当美观新颖,故还可作为室内装饰用。 电子钟的外观如图1所示。周边60只发光管顺时旋转来显示秒,中间四只LED数码管用于显示时间,中下方的七只LED灯顺时旋转,供装饰用。其主要功能有: (1)整点报时; (2)四只LED数码管显示当前时分; (3)每隔一秒钟周边的60只LED发光管旋转一格,装饰用的LED每隔一秒旋转一次; (4)当发生停电事件时,由后备电池供电,系统进入低功耗状态,所有显示部件停止显示,这样即延长了电池的寿命,同时又保证了CPU继续计数,不至于因停电而时钟停止运行。当恢复供电后,系统自动恢复工作状态,不影响计时。
1.2方案论证 电脑钟的原理框图如图2所示。它由以下几个部件组成:单片机89C2051、电源、时分显示部件、60秒旋转译码驱动电路。 file:///C:/Users/jiaxin/AppData/Local/Temp/msohtmlclip1/01/clip_image002.png
时分显示采用动态扫描,以降低对单片机端口数的要求,同时也降低系统的功耗。时分显示模块、60秒旋转译码驱动电路以及显示驱动都通过89C2051的I/O口控制。 电源部分:电源部分有二部分组成。一部分是由220V的市电通过变压、整流稳压来得到+5V电压,维持系统的正常工作;另一部分是由3V的电池供电,以保证停电时正常走时。正常情况下电池是不提供电能的,以保证电池的寿命。
2 系统设计 2.1 系统硬件电路的设计 本系统的应用程序主要由主程序、中断服务程序和子程序组成。主程序的任务是对系统进行初始化,实现参数输入,并控制电加热炉的正常运行。主程序主要由系统初始化、数据 2.1.1 60秒旋转译码驱动原理 按常规传统设计,需60进制译码驱动电路才能实现60秒旋转译码驱动,若用六片十进制计数译码器构成六十进制计数译码电路,则电路连线多(需要120根连线),硬件电路庞大,开销大。为此,本文巧妙地采用了两片CD4017进行六十进制计数译码,实现60秒旋转译码驱动。既减少了电路的复杂程度又可降低了成本。图3为CD4017功能引脚图和工作时序图。
CD4017集成电路是十进制计数/时序译码器,共有10个译码输出Q0~Q9;每个译码输出通常处于低电平,且在时钟脉冲由低到高的上升沿输出高电平;每个高电平输出维持1个时钟周期;每输入10个时钟脉冲,输出一个进位脉冲,因此进位输出信号可作为下一级计数器的时钟信号。在清零输入端(R)加高电平或正脉冲时,只有输出端Q0为高电平,其余各输出端均为低电平“0”。 为实现对发光二极管的驱动,将每一个译码输出端口接一只发光二极管,并将二极管串联限流电阻后接地。当译码端口Q0~Q9中任一端口为高电平,则对应的发光二极管点亮,如图4(左)所示。根据CD4017的功能,可发现其10个输出的高电平是相互排斥的,即任一时刻只有一只发光二极管点亮,因此可电路进一步简化为如图4(右)所示,从而简化电路设计。
在本电子钟设计中,每秒点亮一个发光二极管,循环点亮一周共需60个发光二极管,若用上述的6片CD4017实现驱动,显然电路复杂。为此我们选用两片CD4017和一片6反相器,采用“纵横双译码”技术,巧妙地实现60秒旋转译码驱动,其中一片接成10进制,一片接成6进制,实现6×10=60的功能,具体连接方法如图5所示。
将周期为1秒的输入脉冲作为其中一片CD4017的时钟脉冲,而此片的级联进位输出端(QC)作为另一片的时钟输入,并将Q6与复位端相连。在两片译码输出端交叉点上接入发光二极管,构成6×10矩阵。根据CD4017时序特点,在初始状态,作为高位(纵)的CD4017译码器输出端口Q0处于高平,经反相器反相后为低电平。当作为低位(横)的CD4017译码器输出端口Q0~Q9依次输出高电平后,则对应的二极管LD1~LD10依次点亮;此后由于QC端的进位,高位CD4017译码输出端口Q1输出高电平,反相后输出低电平,当低位的CD4017译码输出端口Q0~Q9依次输出高电平后,二极管LD11~LD20依次点亮。如此往复,直至高位Q6向复位端输入高电平,CD4017复位,60秒循环点亮重新开始。 2.1.2 时分显示部件 由于系统要显示的内容较简单,显示量不多,所以选用数码管既方便又经济。LED有共阴极和共阳极两种。二极管的阴极连接在一起,通常此公共阴极接地,而共阳极则将发光二极管的阳极连接在一起,接入+5V的电压。一位显示器由8个发光二极管组成,其中7个发光二极管构成字型“8”的各个笔划(段)a~g,另一个小数点为dp发光二极管。当在某段发光二极管施加一定的正向电压时,该段笔划即亮;不加电压则暗。为了保护各段LED不被损坏,需外加限流电阻,如图6所示。
众所周知,LED显示数码管通常由硬件7段译码集成电路,完成从数字到显示码的译码驱动。本系统采用软件译码,以减小体积,降低成本和功耗,软件译码的另一优势还在于比硬件译码有更大的灵活性。所谓软件译码,即由单片机软件完成从数字到显示码的转换。从LED数码管结构原理可知,为了显示字符,要为LED显示数码管提供显示段码,组成一个“8”字形字符的7段,再加上1个小数点位,共计8段,因此提供给LED数码管的显示段码为1个字节。各段码位与显示段的对应关系如表1。 表1 各段码位的对应关系
注:(1)本表所列各字符的显示段码均为小数点不亮的情况。 (2)“空白”字符即没有任何显示。 根据AT89C2051单片机灌电流能力强,拉电流能力弱的特点,我们选用共阳数码管。将AT89C2051的P1.0~P1.7分别与共阳数码管的a~g及dp相连,高电平的位对应的LED数码管的段暗,低电平的位对应的LED数码管的段亮,这样,当P0口输出不同的段码,就可以控制数码管显示不同的字符。如:当P0口输出的段码为1100 0000,数码管显示的字符为0。 数码管显示器有二种工作方式,即静态显示方式和动态扫描显示方式。为节省端口及降低功耗,本系统采用动态扫描显示方式。动态扫描显示方式需解决多位LED数码管的“段控”和“位控”问题,本电路的“段控”(即要显示的段码的控制)通过P0口实现;而每一位的公共端,即LED数码管的“位控”,则由P3口控制。这种连接方式由于多位字段线连在一起,因此,要想显示不同的内容,必然要采取轮流显示的方式,即在某一瞬间,只让其中的某一位的字位线处于选通状态,其它各位的字位线处于断开状态,同时字段线上输出这一位相应要显示字符的字段码。在这一瞬时,只有这一位在显示,其他几位则暗。在本系统中,字位线的选通与否是通过PNP三极管的导通与截止来控制,即三极管处于“开关”状态。 系统的时分显示部件由4只7段共阳LED数码管构成,前两只用于时的显示,后两只用于分的显示。值得一提的是,在设计中需要实现时与分之间的两个闪烁点,为此,将第三只LED数码管倒置摆放,这样就形成了两个很自然的闪烁点。与此同时,为了能使两点显示能够形象的表示时钟“秒”的变化,设计时,将两个点由P1.7单独控制,每隔一秒使P1.7发送一个正脉冲,从而实现了两个点的闪烁显示,闪烁周期为一秒。 2.2 系统程序的设计 本系统的软件系统主要可分为主程序和定时器中断程序两大模块。在程序过程中,加入了抗干扰措施。下面对部分模块作介绍。 2.1.1 系统主程序设计 主程序的功能是完成系统的初始化,在显示时间之前,对系统是否停电状态进行检测;若停电,将系统进入低功耗状态,用电池电压维持单片机计时工作,但此时不显示时间,用节省用电;若不停电,则将时分发送显示。程序流程如图7所示。 2.2.2 中断程序设计 中断程序(如图8所示)完成时间计数,时间调整,误差消除等功能。中断采用AT89C2051内部T0中断实现,定时时间为125ms,当时间到达125ms×8,即1分钟时,分计数缓冲器MINBUFFER增加1,到达1小时,则时计数缓冲器HOURBUFFER增加1,并将分、时的个位、十位放入显示缓冲器。当分计数缓冲器和时计数缓冲器分别到达60min、24h时,则对它们清零,以便从新计数。在中断设计中,还通过软件实现了累计误差消除功能,使整个系统时间的精确度得到保证。
3 结束语 上述电子钟,无论在外观上还是功能上都实现了较为完善的设计。特别值得一提的是本系统在精度上的设计,突破传统的方法,对可能产生的积累误差采用“抵消法”,从而有效地降低了时间误差。 由于计数时产生的积累误差所导致的时间误差,是所有的电子计时系统共同存在的问题。但在目前市场上的电子时钟产品,如计算机中的时钟,手机中的时钟等并没有有效的采取消除误差的措施。本系统设计的消除积累误差来减少时间误差的软件方法,并不需要任何的硬件,因此在不增加成本的情况下,可以普遍用于所有的电子时钟产品。
附录主要程序清单 - ALARMHBUFF2 EQU 77H ;闹铃时间的时十位计时绶冲
- ALARMHBUFF1 EQU 76H ;闹铃时间的时个位计时绶冲
- ALARMMBUFF2 EQU 75H ;闹铃时间的分十位计时绶冲
- ALARMMBUFF1 EQU 74H ;闹铃时间的分个位计时绶冲
- HBUFF2 EQU 73H ;时十位计时绶冲
- HBUFF1 EQU 72H ;时个位计时绶冲
- MBUFF2 EQU 71H ;分十位计时绶冲
- MBUFF1 EQU 70H ;分个位计时绶冲
- DP EQU 6FH ;控制数码管点的亮暗
- NUM EQU 78H ;前四秒还是后四秒计数
- SBUFF EQU 79H ;秒十进制计时绶冲(低四位对应个位,高四位对应十位)
- MBUFF EQU 7AH ;分十进制计时绶冲
- HBUFF EQU 7BH ;时十进制计时绶冲
- ALARMMBUFF EQU 7CH ;闹铃时间的分十进制计时绶冲
- ALARMHBUFF EQU 7DH ;闹铃时间的时十进制计时绶冲
- NUMT1 EQU 67H;用于控制时间调整时按键p3.2一次按下时,计数器T1中断的次数
- NUMT2 EQU 68H;用于控制时间调整时按键p3.3一次按下时,计数器T1中断的次数
- KEYNUMT1 EQU 69H ;用于存储NUMT1已经计数到第几个半秒
- KEYNUMT2 EQU 6AH ;用于存储NUMT1已经计数到第几个半秒
- STOREKEYNUMT2 EQU 6BH ;用于存储当前KEYNUMT1的值,以和下次做比较,看是否有变化
- STOREKEYNUMT1 EQU 6CH ;用于存储当前KEYNUMT2的值,以和下次做比较,看是否有变化
- ORG 0000H
- AJMP START
- ORG 000BH
- MOV TH0 , #0BH ;设置计数初值,R4用来存储低位的初值
- MOV TL0 , R4
- AJMP INTERT0
- ORG 001BH
- AJMP INTERT1
- ORG 0040H
- START: MOV NUMT1 , #00H
- MOV NUMT2 , #00H
- MOV KEYNUMT1 , #00H
- MOV KEYNUMT2 , #00H
- MOV STOREKEYNUMT2 , #00H
- MOV STOREKEYNUMT1 , #00H
- MOV NUM , #8
- MOV DPTR , #TAB
- MOV ALARMHBUFF , #18H ;置闹铃时间初始值为18:55
- MOV ALARMMBUFF , #55H
- MOV ALARMHBUFF2, #01H
- MOV ALARMHBUFF1, #08H
- MOV ALARMMBUFF2 , #05H
- MOV ALARMMBUFF1 , #05H
- MOV HBUFF2, #01H ;置闹钟时间为18:53
- MOV HBUFF1, #08H
- MOV MBUFF2 , #05H
- MOV MBUFF1 , #03H
- MOV HBUFF , #18H
- MOV MBUFF , #53H
- MOV SBUFF , #3CH ;置初始秒为60,计时时减
- MOV TCON , #05H ;下降沿触发
- MOV TMOD , #11H ;初始化定时器,T0,T1 16位计时
- MOV TH0 , #0BH ;设置计数初值,125ms计时
- MOV TL0 , #0DBH
- MOV TH1 , #3CH ;T1置初值,进行100ms计时,用于调整时间
- MOV TL1 , #0B0H
- MOV IE , #82H ;开T0中断
- SETB PT0 ;T0中断优先级最高
- SETB TR0 ;允许T0计数
- SETB P3.2
- SETB P3.3
- START1:MOV A , HBUFF ; 显示时,7点以前及21点以后亮度调暗
- SUBB A , #7H
- JC START2
- MOV A , HBUFF
- SUBB A, #21H
- JNC START2
- ACALL DISPLAY
- ACALL ZDBS
- AJMP START3
- START2:ACALL NIGHTDISPLAY
- START3:MOV A ,ALARMHBUFF ;检测是否是定闹时间
- CJNE A , HBUFF , START4
- MOV A , ALARMMBUFF
- CJNE A , MBUFF ,START4
- MOV C, DP ;若是定闹时间,则利用dp的值来决定蜂鸣
- MOV P3.2, C
- MOV A , SBUFF
- JNZ START1 ;若还没到1分钟,则继续蜂鸣
- SETB P3.2
- START4:JNB P3.2,ADJUSTTIME1 ;循环等待中断,并检测是否键按下,若是,则进入相应程序
- JNB P3.3,ADJUSTTIME2
- AJMP START1
- AJMP START1
- ;****************
- ;*int0中断子程序*
- ;****************
- ADJUSTTIME1:NOP
- MOV KEYNUMT1 ,#00H
- MOV TH1 , #3CH ;T1置初值,进行100ms计时,用于调整时间
- MOV TL1 , #0B0H
- SETB ET1 ;开T1中断
- SETB PT1 ;设T1中断优先级最高
- SETB TR1 ;允许T1计时
- MOV STOREKEYNUMT1 , KEYNUMT1 ;存储当前次KEYNUMT1的值
- TIME1_1:ACALL DISPLAY
- MOV A , KEYNUMT1
- CJNE A , STOREKEYNUMT1,TIME1_2 ;若当前KEYNUMT1的值与上一次的值不等,则时间加1分,否则继续循环,等等至半分钟
- AJMP TIME1_3
- TIME1_2:MOV STOREKEYNUMT1 , KEYNUMT1 ;加1后存储当前的KEYNUMT1的值
- ACALL ADDBUFF0 ;分加1
- TIME1_3:JNB P3.2,TIME1_1 ;若p3.2已关,则退出增时,否则继续循环
- CLR ET1
- CLR PT1
- CLR TR1
- AJMP START1
- ;********************
- ;*****时间增1分******
- ;********************
- ADDBUFF0:MOV A , MBUFF ; 若按键小于1s,则分增1
- ADD A , #1
- DA A
- MOV MBUFF , A
- ANL A , #0FH
- MOV MBUFF1 , A
- MOV A , MBUFF
- SWAP A
- ANL A , #0FH
- MOV MBUFF2 , A
- MOV A , MBUFF
- CJNE A , #60H , ADDBUFF1
- MOV MBUFF , #00H
- MOV MBUFF2 , #00H
- MOV MBUFF1 , #00H
- MOV A , HBUFF ;时增1
- ADD A , #1
- DA A
- MOV HBUFF , A
- ANL A , #0FH
- MOV HBUFF1 , A
- MOV A , HBUFF
- SWAP A
- ANL A , #0FH
- MOV HBUFF2 , A
- MOV A , HBUFF
- CJNE A , #24H , ADDBUFF1 ;若没到24小时,则不必初值置0
- MOV HBUFF , #00H
- MOV HBUFF2 , #00H
- MOV HBUFF1 , #00H
- ADDBUFF1:RET
- ;*********************************
- ;*int1中断子程序******************
- ;*********************************
-
- ADJUSTTIME2:NOP
- ACALL DL100MS
- MOV C , P3.3
- JC TIME2_6 ;如果(P3.3按键<100ms以上) 则不做处理
- MOV KEYNUMT2 , #00H ;否则进入定闹设置
- MOV STOREKEYNUMT2 , KEYNUMT2 ;记录当前NUMT2的数据,以看下次有没改变
- TIME2_1:NOP
- MOV TH1 , #3CH ;T1置初值,进行100ms计时,用于调整时间
- MOV TL1 , #0B0H
- SETB ET1 ;开T1中断
- SETB PT1 ;设T1中断优先级最高
- SETB TR1 ;允许T1计时
- TIME2_2:ACALL ALARMDISPLAY
- MOV A , KEYNUMT2
- CJNE A , STOREKEYNUMT2 ,TIME2_3
- AJMP TIME2_4
- TIME2_3:MOV STOREKEYNUMT2 , KEYNUMT2
- MOV A , ALARMMBUFF ; 若按键小于1s,则分增1
- ADD A , #1
- DA A
- MOV ALARMMBUFF , A
- ANL A , #0FH
- MOV ALARMMBUFF1 , A
- MOV A , ALARMMBUFF
- SWAP A
- ANL A , #0FH
- MOV ALARMMBUFF2 , A
- MOV A , ALARMMBUFF
- CJNE A , #60H , TIME2_4
- MOV ALARMMBUFF , #00H
- MOV ALARMMBUFF2 , #00H
- MOV ALARMMBUFF1 , #00H
- MOV A , ALARMHBUFF ;时增1
- ADD A , #1
- DA A
- MOV ALARMHBUFF , A
- ANL A , #0FH
- MOV ALARMHBUFF1 , A
- MOV A , ALARMHBUFF
- SWAP A
- ANL A , #0FH
- MOV ALARMHBUFF2 , A
- MOV A , ALARMHBUFF
- CJNE A , #24H , TIME2_4 ;若没到24小时,则初值不必置0
- MOV ALARMHBUFF , #00H
- MOV ALARMHBUFF2 , #00H
- MOV ALARMHBUFF1 , #00H
- TIME2_4:NOP
- JNB P3.3,TIME2_2 ;若按键已经未按,则退出循环
- CLR ET1
- CLR TR1
- MOV KEYNUMT2 , #00H
- MOV NUMT2 , #00H
- MOV R2 , #10 ; 直到p3.3 20s钟内都是未按,此时复原数据,即退出设置
- TIME2_7:MOV R1 , #200
- TIME2_5:ACALL ALARMDISPLAY
- ACALL DL1MS
- JNB P3.3 , TIME2_1
- DJNZ R1 , TIME2_5
- DJNZ R2 , TIME2_7
- TIME2_6:CLR ET1
- CLR PT1
- CLR TR1
- LJMP START1
- ;***********************************
- ;**T1中断子程序*********************
- ;***********************************
- INTERT1:NOP
- MOV TH1 , #3CH ;T1置初值,进行100ms计时,用于调整时间
- MOV TL1 , #0B0H
- PUSH ACC
- PUSH PSW
- CLR ET0
- CLR ET1 ;关T1中断
- MOV A , NUMT1
- INC A
- MOV NUMT1 , A ;中断一次则相应的增加NUMT1
- CJNE A , #5 , INTERT1NEXT ;每中断五次,即半秒,都增加KEYNUMT1
- MOV A ,KEYNUMT1
- INC A
- MOV KEYNUMT1 , A
- MOV NUMT1 , #00H ;NUMT1已经是5了,则处理过KEYNUMT1后,重置NUMT1
- INTERT1NEXT:NOP
- MOV A , NUMT2 ;中断一次则相应的增加NUMT1
- INC A
- MOV NUMT2 , A
- CJNE A, #5,ENDINTERT1 ;每中断五次,即半秒,都增加KEYNUMT1
- MOV A , KEYNUMT2
- INC A
- MOV KEYNUMT2 , A
- MOV NUMT2 , #00H ;NUMT1已经是5了,则处理过KEYNUMT1后,重置NUMT1
- ENDINTERT1:SETB ET1
- SETB ET0
- POP ACC
- POP PSW
- RETI
- ;**************
- ;** 整点报时**
- ;**************
- ZDBS: MOV A , MBUFF ;在整点时,响半秒
- JNZ ZDBSEND
- MOV A , SBUFF
- CJNE A , #3CH , ZDBSEND
- CLR P3.2
- ACALL DL0FIVE
- SETB P3.2
- ZDBSEND:RET
- ;**************
- ;**定闹显示子程序**
- ;**************
- ALARMDISPLAY:MOV P1 ,#0FFH ;使时的十位亮
- MOV A , ALARMHBUFF2
- MOVC A , @A+DPTR
- SETB ACC.7
- MOV P1 , A
- CLR P3.0
- ACALL DL1MS
- SETB P3.0
- MOV A , ALARMHBUFF1 ;使时的个位亮
- MOVC A , @A+DPTR
- MOV C , DP
- MOV ACC.7 , C
- MOV P1 , A
- CLR P3.1
- ACALL DL1MS
- SETB P3.1
- MOV A ,ALARMMBUFF2 ;使分的十位亮
- MOVC A , @A+DPTR
- MOV C , DP
- MOV ACC.7 , C
- MOV P1 , A
- CLR P3.4
- ACALL DL1MS
- SETB P3.4
- MOV A , ALARMMBUFF1 ;使时的个位亮
- MOVC A , @A+DPTR
- SETB ACC.7
- MOV P1,A
- CLR P3.5
- ACALL DL1MS
- SETB P3.5
- RET
- ;********************************
- ;**晚上显示子程序****************
- ;******************************** ;降低显示的占空比,数码管进入节能
- NIGHTDISPLAY: NOP
- MOV P1 ,#0FFH
- MOV A , HBUFF2
- MOVC A , @A+DPTR
- SETB ACC.7
- MOV P1 , A
- CLR P3.0
- ACALL DL1MS ;亮1ms
- SETB P3.0
- ACALL DL1MS
- ACALL DL1MS ;暗2ms
- MOV A , HBUFF1
- MOVC A , @A+DPTR
- MOV C , DP
- MOV ACC.7 , C
- MOV P1 , A
- CLR P3.1
- ACALL DL1MS
- SETB P3.1
- ACALL DL1MS
- ACALL DL1MS
- MOV A ,MBUFF2
- MOVC A , @A+DPTR
- MOV C , DP
- MOV ACC.7 , C
- MOV P1 , A
- CLR P3.4
- ACALL DL1MS
- SETB P3.4
- ACALL DL1MS
- ACALL DL1MS
- MOV A , MBUFF1
- MOVC A , @A+DPTR
- SETB ACC.7
- MOV P1,A
- CLR P3.5
- ACALL DL1MS
- SETB P3.5
- ACALL DL1MS
- ACALL DL1MS
- RET
- ;**************
- ;**显示子程序**
- ;**************
- DISPLAY:MOV P1 ,#0FFH
- MOV A , HBUFF2
- MOVC A , @A+DPTR
- SETB ACC.7
- MOV P1 , A
- CLR P3.0
- ACALL DL1MS
- SETB P3.0
- MOV A , HBUFF1
- MOVC A , @A+DPTR
- MOV C , DP
- MOV ACC.7 , C
- MOV P1 , A
- CLR P3.1
- ACALL DL1MS
- SETB P3.1
- MOV A ,MBUFF2
- MOVC A , @A+DPTR
- MOV C , DP
- MOV ACC.7 , C
- MOV P1 , A
- CLR P3.4
- ACALL DL1MS
- SETB P3.4
- MOV A , MBUFF1
- MOVC A , @A+DPTR
- SETB ACC.7
- MOV P1,A
- CLR P3.5
- ACALL DL1MS
- SETB P3.5
- RET
- TAB: DB 88H,0BBH,94H,91H,0A3H ; 0 1 2 3 4
- DB 0C1H,0C0H,9BH,80H,81H ; 5 6 7 8 9
- ;**************
- ;***延时程序***
- ;**************
- DL1MS: MOV R6 , #20 ;延时1ms
- DL11: MOV R7 , #25
- DL12: DJNZ R7 , DL12
- DJNZ R6 , DL11
- RET
- DL100MS:MOV R6 , #200 ;延时100ms
- DL100MS1:MOV R7 , #250
- DL100MS2:DJNZ R7 , DL100MS2
- DJNZ R6 , DL100MS1
- RET
- DL11S: MOV R5 , #10
- DL1S0: MOV R6 , #200 ;延时1s 10*250*200
- DL1S1: MOV R7 , #250
- DL1S2: DJNZ R7 , DL1S2
- DJNZ R6 , DL1S1
- DJNZ R5 , DL1S0
- RET
- DL0FIVE:MOV R5 , #5
- DL0: MOV R6 , #100 ;延时0.5s
- DL1: MOV R7 , #250
- DL2: DJNZ R7 , DL2
- DJNZ R6 , DL1
- DJNZ R5 , DL0
- RET
- ;**************
- ;*T0中断子程序*
- ;**************
- INTERT0:PUSH ACC
- PUSH PSW
- CLR ET0 ;关T0中断
- MOV A , SBUFF
- CJNE A ,#028H, SET1
- MOV R4 , #0DCH ;后四十秒的初值
- SET1: DJNZ NUM , ENDINTT0 ;若还没到1s,则退出该次中断
- MOV NUM , #8 ;设置NUM初值
- CPL DP
- DJNZ SBUFF , ENDINTT0 ; 若还没到60s,则退出该次中断
- MOV SBUFF , #03CH
- MOV R4 , #0DBH ;前20秒的初值
- ACALL ADDBUFF0
- ENDINTT0:MOV A , NUM
- CJNE A , #04H , ENDT0OUT ;0.5秒的时候dp取反
- CPL DP
- ENDT0OUT:POP PSW
- POP ACC
- SETB ET0
- RETI
- END
复制代码
|