汇编 此代码非彼代码

2016/11/17

下午答辩完了最后一门课程设计,老师是个非常严苛的人,不仅要我们对汇编程序理解透彻,还要问硬件相关的问题。恰巧对电路这种东西真的是一脸懵逼的我,异常痛苦。我可以很专注的写一天的程序,但是单片机这门课,尽管注释那么多还是懒得去理解。兴趣这东西真的很重要呐。

;带温度检测功能的数字时钟的控制程序  
	ORG  0000H	;复位入口	  
	LJMP  MAIN	;转往主程序  
    
	ORG  001BH	;定时器1中断服务子程序入口
  	LJMP  IT1P	;定时中断:进行实时钟计时  
  
	ORG  0030H	;主程序  
  
MAIN:  
	MOV SP,#6FH	 ;总初始化,设定栈底指针  
  
	LCALL D60MS	 ;稍加延时(60mS),以待各芯片均退出复位状态  
  
	MOV DPTR,#0FEFFH ;对8255A(U3)接口芯片初始化  
	MOV A,#89H	 ;设定为A输出(驱动字段)、B口输出(驱动字位),C口输入  
   	MOVX  @DPTR,A	 ;写入方式控制字	  

	MOV DPTR,#0FEFCH ;DPTR指向U3-A口  
	MOV A,#0FFH	 ;置八段均不亮的字段码(8255A初始化后输出寄存器全‘0')  
	MOVX @DPTR,A	 ;输出,关数码显示器(段输出口初始驱动全为‘1'无效)  
  
	MOV DPTR,#0FDFFH ;对8255A(U5)接口芯片初始化
	MOV A,#8BH	 ;设定为A口输出(驱L8~15),B口输入(按钮PB0~7),C口输入(开关SW0~7)  
   	MOVX  @DPTR,A	 ;写入方式控制字  
  
    MOV DPTR,#0FDFCH ;DPTR指向U5-A口  
	MOV A,#0FFH	 ;置八位输出均为‘1'无效  
	MOVX @DPTR,A	 ;输出,令L8-15初始不亮	  
	  
	CLR P3.2	 ;蜂鸣器响		  
   	LCALL D1S	 ;延时1S  
   	SETB P3.2	 ;关蜂鸣器  
	MOV P1,#00H	 ;P1口输出全‘0',所驱动的L0~L7指示灯全亮  
	LCALL D1S	 ;延时1S  
	MOV P1,#0FFH	 ;熄L0~L7指示灯  
		  
	MOV 20H,#01H	;界面显示码,默认设置为显示实时钟  
	MOV 21H,#00H	;讯响进程码,用于蜂鸣器的声音控制  
  
	MOV DPTR,#0FDFDH;输入P0-P7的电平,送给29H-2FH单元做初始值  
	MOVX A,@DPTR    
	MOV 2FH,A		;XDPB 5次滚存滤波消抖动,按键未按下  
	MOV 2EH,A
	MOV 2DH,A
	MOV 2CH,A  
	MOV 2BH,A  
	MOV 2AH,A
	MOV 29H,A  
	mov R1,#00H
  
	MOV 30H,#10H	 ;30H-37H为显示缓冲单元,初始值令显示‘- 8951 -’  
	MOV 31H,#12H  
	MOV 32H,#01H  
	MOV 33H,#05H  
	MOV 34H,#09H  
	MOV 35H,#08H  
	MOV 36H,#12H  
	MOV 37H,#10H  
  
	MOV 38H,#00H	;38H单元为实时钟200uS计数单元,清0  
    MOV 39H,#00H	;39H单元为10mS计数单元,清0  
	MOV 3AH,#45H	;秒单元初值  
	MOV 3BH,#59H	;分单元初值  
	MOV 3CH,#08H	;时单元初值,时钟初值08:59:45	  
  
	MOV 40H,#09H    ;设置显示时钟的秒数  
	MOV 41H,#00H    ;记录时钟已经显示了多少秒  
  
	MOV 42H,#10H	;采集温度值  
	MOV 44H,#82H    ;温度显示初始值  
	MOV 46H,#40H    ;设置温度报警值  
  
	MOV 48H,#10H	;设置采集温度滚存初值  
	MOV 49H,#10H  
	MOV 4AH,#10H  
	MOV 4BH,#10H  
  
	MOV 4FH,#00H	;记录操作的时间30S无操作返回  
	MOV 50H,#00H	;  
	MOV 51H,#00H  
 	CLR 23H.0       ;记录是否切换为温度显示状态  
	CLR 23H.1  
    MOV TMOD,#20H	;初始化T1为定时方式2  
	MOV TL1,#00H	;置T1计数初值  
    MOV TH1,#00H    ;即每约256TM中断一次。(TM=12×1/11.0592MHZ=1.085069444μS)  
	SETB EA			;开中断总允许 	  
	SETB ET1 		;开T1中断允许  
	SETB TR1		;启动T1定时工作  
  
;主工作流程:  
LOOP:  
   	LCALL XDPB	;五次滚存滤波消抖动  
	LCALL CZ    	;调用显示内容送显缓子模块程序(拆字)(将时分秒送右6位显示缓冲单元)  
 	LCALL DISP  	;调用显示更新子程序 (动态驱动8位数码显示器一遍,约8mS)	  
	LCALL CJWD 	;采集温度子模块程序  
   	LCALL CXWD		;调用穿插温度子模块程序  
	LCALL GWJS	;调用高温警示子模块程序  
	LCALL PB	  
	LCALL WCZFH	;无操作返回子程序  
	LCALL XX		;蜂鸣器模块  
 	SJMP LOOP       ;跳转到LOOP 循环  
  
XDPB:  
	MOV 2FH,2EH	;上一轮新态存为前态  
	MOV 2DH,2CH	;前四次输入的电平推至2AH-2DH单元  
	MOV 2CH,2BH	;  
	MOV 2BH,2AH	;  
	MOV 2AH,29H	;  
  
	MOV DPTR,#0FDFDH ;输出P0-P7的新电平  
	MOVX A,@DPTR  
	MOV 29H,A  
  
	MOV A,2DH  
	CJNE A,2CH,XDR  
	CJNE A,2BH,XDR  
	CJNE A,2AH,XDR  
	CJNE A,29H,XDR  
	MOV 2EH,A	 ;进屋次输入的电平值一致则存为新态  
XDR:RET		  
  
;拆字模块  
CZ:  
	MOV A,20H   	;显示内容送显缓子模块程序(拆字)。	  
	CJNE A,#01H,CZP1;为#01H则拆字实时钟,否者判断是否为#02H,  
	LCALL CZS  
CZP1:  
	CJNE A,#02H,CZP2;为#02H则拆字温度,否者判断是否为#10H,  
   	LCALL CZW  
CZP2:  
	CJNE A,#10H,CZP3;为#10H则拆字 调时钟 时钟 ,否者判断是否为#11H,  
   	LCALL CZTS  
CZP3:  
	CJNE A,#11H,CZP4;为#11H则拆字 调时钟 分钟 ,否者判断是否为#12H,  
   	LCALL CZTS  
CZP4:  
	CJNE A,#12H,CZR;为#12H则拆字 调温度最大警示值 ,否者则结束  
	LCALL CZTW  
CZR:  
	RET  
  
CZS:  
	MOV R0,#3AH	;显示内容送显缓子模块程序(拆字)。置时钟数据单元首地址(秒单元)  
	MOV R1,#30H    	;置显示缓冲单元首地址(对应于最右显示位)	  
CZ1:  
	MOV A,@R0    	;取当前数据单元BCD码  
	ANL A,#0FH   	;保留低4位(个位)  
	MOV @R1,A     	;送显缓当前个位单元  
	INC R1          ;指向显缓当前十位单元  
	MOV A,@R0   	;再取当前数据单元BCD码  
	ANL A,#0F0H  	;保留高4位(十位)  
	SWAP A         	;交换到低4位  
	MOV @R1,A     	;送显缓当前十位单元  
	INC R1          ;指向显缓下一个个位单元  
	MOV @R1,#10H	;送显缓内容 - 
    INC R1		;指向显缓下一个个位单元  
	INC R0          ;指向下一个时钟数据单元  
	CJNE R0,#3DH,CZ1 ;未完继续  
	RET  
  
CZW:  
	MOV 37H,#12H	;空  
    MOV 36H,#12H	;空  
	MOV 35H,#12H	;空  
	MOV 34H,#12H	;空  
	MOV 30H,#0CH	;C  
	MOV 31H,#13H	;。	  
	MOV A,44H	;获取(44H)单元显示温度值  
	ANL A,#0FH   	;保留低4位(个位)  
	MOV 32H,A     	;送显缓当前个位单元  
	MOV A,44H   	;再取当前数据单元BCD码  
	ANL A,#0F0H  	;保留高4位(十位)  
	SWAP A         	;交换到低4位  
	MOV 33H,A     	;送显缓当前十位单元  
	RET  
  
CZTW:  
	MOV 37H,#0CH	;空  
    MOV 36H,#12H	;空  
	MOV 35H,#12H	;空  
	MOV 34H,#12H	;空  
	MOV 30H,#0CH	;C  
	MOV 31H,#13H	;。	  
	MOV A,46H	;获取(46H)单元最高温度警示值  
	ANL A,#0FH   	;保留低4位(个位)  
	MOV 32H,A     	;送显缓当前个位单元  
	MOV A,46H   	;再取当前数据单元BCD码  
	ANL A,#0F0H  	;保留高4位(十位)  
	SWAP A         	;交换到低4位  
	MOV 33H,A     	;送显缓当前十位单元  
	RET  
  
CZTS:  
	MOV 37H,#0CH	;C  
	MOV 36H,#12H	;空  
	MOV 35H,#12H	;空  
	MOV 32H,#10H	;-  
  
    MOV A,3CH	;获取(3CH)单元  小时单元的值  
	ANL A,#0FH   	;保留低4位(个位)  
	MOV 33H,A     	;送显缓当前个位单元  
	MOV A,3CH   	;再取当前数据单元BCD码  
	ANL A,#0F0H  	;保留高4位(十位)  
	SWAP A         	;交换到低4位  
	MOV 34H,A     	;送显缓当前十位单元  
	  
    MOV A,3BH	;获取(3BH)单元  分钟单元的值  
	ANL A,#0FH   	;保留低4位(个位)  
	MOV 30H,A     	;送显缓当前个位单元  
	MOV A,3BH   	;再取当前数据单元BCD码  
	ANL A,#0F0H  	;保留高4位(十位)  
	SWAP A         	;交换到低4位  
	MOV 31H,A     	;送显缓当前十位单元  
	RET             ;子程序返回  
  
;显示模块  
DISP:  
	MOV DPTR,#0FEFCH   ;关显示  
	MOV A,#0FFH  
	MOVX @DPTR,A  
  
	MOV R0,#30H        ;显示更新子程序。置显示缓冲单元首地址(对应最右位)  
	MOV R3,#01H        ;位码初值(从最右位起)  
	MOV A,R3  
DISP1:  
	MOV DPTR,#0FEFDH   	; 8255-B口(位码输出口)  
	MOVX @DPTR,A      	; 输出当前字位码  
	MOV A,@R0           	; 取当前位显示数据码  
    ADD A,#TAB-NEXTPC 	; 加TAB与NEXTPC差址  
    MOVC A,@A+PC      	; 查表得相应字段码  
NEXTPC:  
	MOV DPTR,#0FEFCH   	; 8255-A口(字段码输出口)  
 	MOVX @DPTR,A       	; 输出字段码  
	LCALL D1MS           	; 保持显示1毫秒  
	LCALL GAOL  
	MOV DPTR,#0FEFCH   ;关显示  
	MOV A,#0FFH  
	MOVX @DPTR,A  
  
	INC R0                	; 指向下一显示缓冲单元  
	MOV A,R3             	; 取出原来的位码  
	JB ACC.7,DISP2        	; 判断若已显示到最左位则结束  
	RL A                    ; 未完,字位码左移1位  
	MOV R3,A             	; 回存新的位码  
	LJMP DISP1            	; 转下一位的显示驱动  
 
DISP2:RET  
  
;字段码表  
TAB:  
	DB 0C0H,0F9H,0A4H,0B0H,99H,92H,82H	;字段码表。"0"~"6" 
	DB 0F8H,80H,90H,88H,83H,0C6H,0A1H	;"7"~"9","A"~"D"   
    DB 86H,8EH,0BFH,00H,0FFH,9CH		;"E","F","-",全亮,空格,温度的度值符号  
  
;根据进程码(20H地址单元)进行相应操作(10 调小时并且高亮  11 调分钟并高亮  12 调温度并高亮)  
GAOL:  
	MOV A,20H		;获取(20H)的界面进程码  
   	CJNE A,#10H,GAOL2	;判断是否为#10H,若是则调小时的两个单元(33H,34H)高亮,,否则跳转判断是否为#11H  
    CJNE R0,#33H,GAOL1	;判断R0是否为#33H,即小时个位单位  
	LCALL D1MS		;多延时1ms  
GAOL1:  
	CJNE R0,#34H,GAOLR	;判断R0是否为#34H,即小时十位单位  
	LCALL D1MS		;多延时1ms  
  	SJMP GAOLR  
GAOL2:  
	CJNE A,#11H,GAOL4	;判断是否为#11H,若是则调分钟的两个单元(30H,31H)高亮,,否则跳转判断是否为#12H  
    CJNE R0,#30H,GAOL3	;判断R0是否为#30H,即分钟个位单位  
	LCALL D1MS		;多延时1ms  
GAOL3:  
	CJNE R0,#31H,GAOLR	;判断R0是否为#31H,即分钟十位单位  
	LCALL D1MS		;多延时1ms  
  	SJMP GAOLR  
GAOL4:  
	CJNE A,#12H,GAOLR	;判断是否为#12H,若是则调最大高温报警温度的两个单元(32H,33H)高亮,,否则跳转结束  
    CJNE R0,#32H,GAOL5	;判断R0是否为#32H,即最大高温报警温度值个位单位  
	LCALL D1MS		;多延时1ms  
GAOL5:  
	CJNE R0,#33H,GAOLR	;判断R0是否为#33H,即最大高温报警温度值十位单位  
	LCALL D1MS		;多延时1ms  
GAOLR:RET  
  
;软件延时1mS子程序  
D1MS:  
	MOV R7,#115         	  
D1MS1:  
	NOP			;(1+8*115+2)*12/11059.2KHz=1.0015mS  
  	NOP       
	NOP  
	NOP  
	NOP  
	NOP  
	DJNZ R7,D1MS1  
	RET  
	  
CXWD:  
	MOV A,20H			;获取20H的界面进程码  
   	MOV R0,41H			;获取41H单元的值存R0  
   	CJNE A,#01H,CXWD1	;20H单元为#01H则判断R0是否大于9s,否则判断20H单元是否为#02H  
	CJNE R0,#09H,CXWDR	;R0不等于9s则结束.相等则往下执行.显示温度  
	MOV 20H,#02H		;切换界面进程码为显示温度a   
	MOV 44H,42H			;将采集到的温度赋给44H单元,供CZ用  
	MOV 41H,#00H		;41H单元清零,经行新一轮显示温度时间计算  
	SETB 23H.0			;23H.0置1,表示已经从实时钟显示界面切换到了温度显示界面,供温度警示(WDJSW)子模块程序判断用  
	SJMP CXWD2			;每一轮完成后要跳到将41H清零后结束  
CXWD1:  
	CJNE A,#02H,CXWD2	;20H单元为#02H则判断R0是否大于2s,否则结束  
  	CJNE R0,#02H,CXWDR	;R0大于2s则切换显示实时钟,否则结束  
	MOV 20H,#01H		;切换界面显示码为显示实时钟  
CXWD2:  
	MOV 41H,#00H		;41H单元清零,经行新一轮  
CXWDR:RET  
  
GWJS:  
	JNB 23H.0,GWJSR		;判断是否切换到了温度显示界面,若是则继续,否则结束  
	CLR 23H.0			;23H.0清零	  
	CLR C				;Cy清零,防止受干扰  
	MOV A,46H			;将44H单元温度显示值,送给A  
	SUBB A,44H			;46H温度显示值 - 44H单元设置的最高温度报警值  
	JNC GWJSR			;无借位,46H >= 44H 单元,不需要报警,结束  
	MOV 21H,#01H  
	LCALL XX			;否者有借位 44H < 46H 要报警,调用讯响子模块程序  
GWJSR:RET  
  
;蜂鸣模块  
XX:	  
	MOV A,21H		;获取讯响进程码  
	CJNE  A,#01H,JR0	;  
JR0:JC XXR  
	INC 21H  
	CJNE  A,#20,JR1  
JR1:JC XX1  
	CJNE A,#30,JR2  
JR2:JC XX2  
	CJNE A,#45,JR3  
JR3:JC XX1  
	CJNE A,#60,JR4  
JR4:JC XX2  
	CJNE A,#75,JR5  
JR5:JC XX1  
	CJNE A,#99,JR6  
JR6:JC XX3  
  
XX1:  
	CLR P3.2			;蜂鸣器响		  
    ret  
XX2:  
	SETB P3.2			;蜂鸣器不响  
	ret  
XX3:  
	MOV 21H,#00H  
	SETB P3.2			;蜂鸣器不响  
	ret  
XXR:RET  
  
DDMS1:  
	MOV R5,#25	;[1+(1+(1+2)*200+2)*153+2]*12/11059.2KHz=100.1mS  
DDMS0:  
LCALL CZ  
	LCALL DISP  
	DJNZ R5,DDMS0  
	RET  
;软件延时100ms子程序	  
D100MS:  
	MOV R6,#153	  
D100MS1:  
	MOV R5,#200	;[1+(1+(1+2)*200+2)*153+2]*12/11059.2KHz=100.1mS  
D100MS0:  
	NOP  
	DJNZ R5,D100MS0  
	DJNZ R6,D100MS1  
	RET  
  
;软件延时150ms子程序  
D150MS:  
	MOV R6,#229	;软件延时150ms子程序  
D150MS1:  
	MOV R5,#200	;[1+(1+(1+2)*200+2)*229+2]*12/11059.2KHz=149.8mS  
D150MS0:  
	NOP  
	DJNZ R5,D150MS0  
	DJNZ R6,D150MS1  
	RET  
  
;根据进程码判断要执行操作  
WCZFH:  
	MOV  A,20H		;获取界面进程码  
  	CJNE A,#01H,WCZFH1	;判断若为#01H(实时钟界面)则继续,否则判断是否为#02H(温度显示)  
	MOV  4FH,#00H		;4FH单元记录无操作时间要清零  
	SJMP WCZFHR		;结束  
WCZFH1:  
	CJNE A,#02H,WCZFH2	;判断若为#02H(温度显示界面)则继续,否则判断是否P5(MOD键盘是否有变动)  
	MOV  4FH,#00H		;4FH单元记录无操作时间要清零  
	SJMP WCZFHR		;结束  
WCZFH2:  
	JNB  2FH.0, WCZFH3	;PB5新态为1	  
 	JB   2EH.0, WCZFH3	;PB5前态为0  
	MOV  4FH,#00H		;4FH单元记录无操作时间要清零  
	SJMP WCZFHR		;结束  
WCZFH3:  
	JB   2FH.0, WCZFH4	;PB5新态为0  
 	JNB  2EH.0, WCZFH4	;PB5前态为1  
	MOV  4FH,#00H		;4FH单元记录无操作时间要清零  
	SJMP WCZFHR		;结束  
WCZFH4:  
	JNB  2FH.1, WCZFH5	;PB6新态为1  
 	JB   2EH.1, WCZFH5	;PB6前态为0  
	MOV  4FH,#00H		;4FH单元记录无操作时间要清零  
	SJMP WCZFHR		;结束  
WCZFH5:  
 	JB   2FH.1, WCZFH6	;PB6新态为0  
 	JNB  2EH.1, WCZFH6	;PB6前态为1  
	MOV  4FH,#00H		;4FH单元记录无操作时间要清零  
	SJMP WCZFHR		;结束  
WCZFH6:  
	JB   2FH.1, WCZFH7	;PB6新态为0  
 	JB   2EH.1, WCZFH7	;PB6前态为0  
	MOV  4FH,#00H		;4FH单元记录无操作时间要清零  
	SJMP WCZFHR	 	;结束  
WCZFH7:  
	MOV  A,4FH		;获取无操作时间  
 	SUBB A,#30H		;4FH单元减去30  
	JC   WCZFHR		;有借位,4FH单元小于30s则结束  
	MOV  20H,#01H		;无借位。4FH单元大于30s则切换界面进程为#01H,显示实时钟  
WCZFHR:RET  
  
CJWD:  
	MOV 4BH,4AH	;上一轮新态存为前态  
	MOV 4AH,49H	;前3次的温度值推至49H-4BH单元  
	MOV 49H,48H	;  
	MOV DPTR,#0FBF8H ;A/D子程序。  
	MOVX A,@DPTR	 ;读取A/D转换结果的8位二进制数字值  
	MOV 48H,A  
	MOVX @DPTR,A	 ;启动对IN0输入模拟电压信号的A/D转换  
  
	MOV R1,#00H	;R1存48H~4BH单元相加后的高8位  
	CLR C		;Cy清零  
	MOV A,48H	;取48H单元值  
	ADD A,49H	;加49H单元值  
	JNC CJWD1	;无进位,继续加  
	INC R1		;有进位,R1加1  
CJWD1:  
	CLR C     	;Cy清零  
	ADD A,4AH	;加4AH单元值  
	JNC CJWD2	;无进位,继续加  
	INC R1		;有进位,R1加1  
CJWD2:  
	CLR C		;Cy清零  
  	ADD A,4BH	;加4BH单元值  
	JNC CJWD3  
	INC R1		;有进位,R1加1  
CJWD3:  
	CLR C		;Cy清零  
    RRC A		;低8位右移2位  
    CLR C		;Cy清零  
  	RRC A  
	CLR C		;Cy清零  
  	RRC A  
  
	MOV R2,A	;右移2位后的低8位送R2  
	MOV A,R1	;取R1(相加后的高8位)  
	CLR C		;Cy清零  
	RL A		;高8位左移6位  
  	RL A  
	RL A  
	RL A  
	RL A  
	RL A  
  
	ORL A,R2		;左移6位后的高8位跟右移2位后的低8位进行或运算  
		  
	MOV B,#02H		;给B送2,后续判断奇偶  
	DIV AB			;此时A中存的是A/D转换的结果除以2的商,B中是A/D转换的结果除以2的的余数        
	MOV R1,A		;暂存采集的结果(除以2)  
	MOV A,B	        ;取B中的结果  
    CJNE A,#01H,KEEP;B为0采集结果为偶数,跳KEEP,采集结果(除以2)不加                                                                                                                                                                                                        1  
	INC R1			;B为1采集结果为奇数,采集结果(除以2)加1  
KEEP:  
	MOV A,R1		;暂存采集的结果(除以2)  
	SUBB A,#63H		;判断是否大于100  
	JC CJWD4		;小于100则显示采集的值  
	MOV 42H,#0EEH	;大于100则显示EEH(溢出)  
	SJMP CJWDR  
CJWD4:  
	MOV A,R1  
  	MOV B,#0AH  
	DIV AB  
	SWAP A  
	ORL A,B  
    MOV 42H,A  
CJWDR:RET  
  
;切换模块,检测PB0是否有按下  
PB:  
	MOV A,20H	 	 ;获取界面进程码  
	;用于防止按一下时间过长导致跳转多个界面:PB子模块每10/ms调用一次,若按压时间过长会导致500后的代码会调用多次	,跳转多个界面  
    JNB 2FH.0,PBA    ;新态为1  
	JB 2EH.0,PBA	 ;前态为0  
  
	CJNE A,#01H,PB1	 ;判断是不是实时钟显示界面,若是继续,否转PB1  
	MOV 20H,#10H	 ;切换进程码为#10H,调小时界面  
	SJMP PBR0  
PB1:  
	CJNE A,#02H,PB2	 ;判断是不是温度显示界面,若是继续,否转PB2  
	MOV 20H,#10H	 ;切换进程码为#10H,调小时界面  
	SJMP PBR0  
PB2:  
	CJNE A,#10H,PB3  ;判断是不是调小时界面,若是继续,否转PB3  
	MOV 20H,#11H     ;切换进程码为#11H,调分钟界面  
	SJMP PBR0  
PB3:  
	CJNE A,#11H,PB4  ;判断是不是调分钟界面,若是继续,否转PB4  
	MOV 20H,#12H     ;切换进程码为#12H,调最大高温报警值界面  
	SJMP PBR0  
PB4:  
	CJNE A,#12H,PBR0  ;判断是不是设置 最大高温报警值界面,若是继续,结束  
	MOV 20H,#01H     ;切换进程码为#01H,实时钟显示界面  
	SJMP PBR0  
  
;检测是否有PB1按下,若有:当为时间更改界面时,更改时间  
PBA:  
;用于防止按一下时间过长导致增减多个1:PBA子模块每10/ms调用一次,若按压时间过长会导致5526后的代码会调用多次	,增减多个1  
	JNB 2FH.1,PBB    ;新态为1  
	JB 2EH.1,PBB	 ;前态为0  
  
	CJNE A,#10H,PBA1 ;判断是否为调小时界面  
	;调小时界面  
	MOV A,3CH	;小时单元按BCD码模24加1  
	ADD A,#01H  
	DA A  
	MOV 3CH,A  
	MOV 38H,#00H	;前级计数单元清零  
	MOV 39H,#00H	;1/100s钟数清零  
	MOV 3AH,#00H	;秒钟数清零  
	CJNE A,#24H,PBR0 ;满24小时?  
	MOV 3CH,#00H	;小时数清零  
	SJMP PBR0  
PBA1:  
	CJNE A,#11H,PBA2;判断是否为调分钟界面  
	;调分钟界面  
	MOV A,3BH	;分钟单元按BCD码模60加1  
	ADD A,#01H  
	DA A  
	MOV 3BH,A  
	MOV 38H,#00H	;前级计数单元清零  
	MOV 39H,#00H	;1/100s钟数清零  
	MOV 3AH,#00H	;秒钟数清零  
	CJNE A,#60H,PBR0;满60分钟?  
	MOV 3BH,#00H	;分钟数清零  
	SJMP PBR0  
PBA2:  
	CJNE A,#12H,PBR0 ;判断是否为调最高温度报警界面  
	;调温度界面  
	MOV A,46H	;温度单元按BCD码模60加1  
	ADD A,#01H  
	DA A  
	MOV 46H,A  
	CJNE A,#00H,PBR0;满100度  
	MOV 46H,#00H	;度数清零  
	SJMP PBR0  
PBR0:  
	MOV 50H,#00H    ;  
    MOV 51H,#00H    ;  
    CLR 23H.1  
	RET  
  
;时钟模块  
PBB:  
	JB 2FH.0,PBRR    ;新态为0  
	JB 2EH.1,PBRR	 ;前态为0  
	SETB 23H.1  
	MOV A,20H  
	CJNE A,#10H,PBB1 ;判断是否为调小时界面  
	MOV A,50H  
	CLR C			;Cy清零,防止受干扰  
	SUBB A,#32H  
	JC PBRR  
	MOV A,51H  
	CLR C			;Cy清零,防止受干扰  
	SUBB A,#10H  
	JC PBRR  
	MOV A,3CH	;小时单元按BCD码模24加1  
	ADD A,#01H  
	DA A  
	MOV 51H,#00H  
	MOV 3CH,A  
	MOV 38H,#00H	;前级计数单元清零  
	MOV 39H,#00H	;1/100s钟数清零  
	MOV 3AH,#00H	;秒钟数清零  
	CJNE A,#24H,PBRR ;满24小时?  
	MOV 3CH,#00H	;小时数清零  
PBB1:  
	MOV A,20H  
    CJNE A,#11H,PBB2 ;判断是否为调分钟界面  
	MOV A,50H  
	SUBB A,#32H  
	JC PBRR  
	MOV A,51H  
	SUBB A,#10H  
	JC PBRR  
	MOV A,3BH	;分钟单元按BCD码模60加1  
	ADD A,#01H  
	DA A  
	MOV 51H,#00H  
	MOV 3BH,A  
	MOV 38H,#00H	;前级计数单元清零  
	MOV 39H,#00H	;1/100s钟数清零  
	MOV 3AH,#00H	;秒钟数清零  
	CJNE A,#60H,PBRR;满60分钟?  
	MOV 3BH,#00H	;分钟数清零  
PBB2:  
	CJNE A,#12H,PBRR ;判断是否为调分钟界面  
	MOV A,50H  
	SUBB A,#32H  
	JC PBRR  
	MOV A,51H  
	SUBB A,#10H  
	JC PBRR  
   	MOV A,46H	;温度单元按BCD码模60加1  
	ADD A,#01H  
	DA A  
	MOV 51H,#00H  
	MOV 46H,A  
	CJNE A,#00H,PBRR;满100度  
	MOV 46H,#00H	;度数清零  
PBRR:RET  
  
IT1P:  
	PUSH ACC        ;定时器1服务子程序。保护现场  
    PUSH PSW  
    INC 38H         ;每200uS加1  
    MOV A,38H  
    CJNE A,#36,DONE ;满10mS?  
    MOV 38H,#0	;200uS计数单元清0  
  
	JNB 23H.1,IT1P1	;  
	MOV A,50H  
	SUBB A,#32H  
	JNC IT1P2  
	INC 50H  
	SJMP IT1P2  
IT1P1:  
	MOV 50H,#00H  
IT1P2:  
    INC 51H  
  	INC 39H         ;每10mS加1  
  	MOV A,39H  
    CJNE A,#100,DONE;满1S?  
	MOV 39H,#0 	;10mS计数单元清0  
	  
    MOV A,41H	;显示时钟界面或者温度界面计时秒数按BCD码加1,与秒数同步  
	ADD A,#01H  
	DA A  
	MOV 41H,A  
  
	MOV A,4FH	;无操作计时秒数按BCD码加1,与秒数同步  
	ADD A,#01H  
	DA A  
	MOV 4FH,A  
  
	MOV A,3AH       ;秒单元(按BCD码)加1  
	ADD A,#1            
	DA A  
	MOV 3AH,A  
	CJNE A,#60H,DONE;满1分钟?  
	MOV 3AH,#0      ;秒单元清零  
	MOV A,3BH       ;分钟单元(按BCD码)加1  
	ADD A,#1          
	DA A  
	MOV 3BH,A  
	CJNE A,#60H,DONE;满1小时?  
	MOV 3BH,#0      ;分钟单元清零  
	MOV A,3CH       ;小时单元(按BCD码)加1  
	ADD A,#1          
	DA A  
	MOV 3CH,A  
	CJNE A,#24H,DONE;满24小时?  
	MOV 3CH,#0      ;小时单元清零  
DONE:  
	POP PSW         ;恢复现场  
    POP ACC               
    RETI            ;中断返回  
  
;软件延时1S子程序  
D1S:  
	MOV R7,#8	;软件延时1S子程序  
D1S2:  
	MOV R6,#200	;(1+(1+(1+3*200+2)*200+2)*8+2)*12/11059200Hz=1.047S  
D1S1:  
	MOV R5,#200  
D1S0:  
	NOP  
	DJNZ R5,D1S0  
	DJNZ R6,D1S1  
	DJNZ R7,D1S2  
	RET  
  
;软件延时60mS子程序  
D60MS:  
	MOV R6,#92	  
D60MS1:  
	MOV R5,#200	;[1+(1+(1+2)*200+2)*92+2]*12/11059.2KHz=60.2mS  
D60MS0:  
	NOP  
	DJNZ R5,D60MS0  
	DJNZ R6,D60MS1  
	RET  
   	END