汇编 此代码非彼代码
November 17, 2016下午答辩完了最后一门课程设计,老师是个非常严苛的人,不仅要我们对汇编程序理解透彻,还要问硬件相关的问题。恰巧对电路这种东西真的是一脸懵逼的我,异常痛苦。我可以很专注的写一天的程序,但是单片机这门课,尽管注释那么多还是懒得去理解。兴趣这东西真的很重要呐。
;带温度检测功能的数字时钟的控制程序
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