在做课程设计,其中有一条是需要时间与温度交替显示。
我写好了温度显示和时间显示,分别测试都已经可以实现功能了。
但是,一旦把温度显示和时间显示合并在一个程序中,时间显示是正常的,但是温度显示为“FE”了。
测试了一下,发现没有加进时间中断程序的时候,温度显示是正常的,加进来时间中断程序之后,温度显示就变成了“EF”。
弄了一天都没有找到哪里错了,请大家指出程序的错误,谢谢啦!
下面是代码
- FLAG1 BIT 00H ;FLAG1:标志位,为"1"时表示检测到DS18B20
- TEMPER_NUM EQU 38H ;TEMPER_NUM:保存读出的温度数据
- TEMPER_L EQU 5BH ;温度的低位
- TEMPER_H EQU 5AH ;温度的高位
- TEMP EQU 5DH ;临时存放温度数据的单元
- DIS_TEMP EQU 58H ;58H存放显示温度的个位数,59H存放显示温度的十位数
- DIS_C EQU 5CH
- DQ BIT P1.3 ; DQ:DS18B20的数据总线接脚
- ;DS18B20初始化程序
- ;//*****************************************//
- ;定义区
- ;//===============================
- ;//时间计数缓冲区
- DIS_MIN EQU 50H ;50H,51H
- DIS_HOUR EQU 52H ;52H,53H
- DIS_DAY EQU 54H ;54H,55H
- DIS_MON EQU 56H ;56H,57H
- ;//===============================
- ;//时间储存单元
- MONTH EQU 30H
- DAY EQU 31H
- HOUR EQU 32H
- MINUTE EQU 33H
- COUNT_MIN EQU 4FH
- DL_2S EQU 41H
- ORG 0000H
- LJMP MAIN
- ORG 000BH
- LJMP TIMER_T0
- ORG 0030H
-
- MAIN: MOV R0,#50H
- MOV R2,#8
- CLEAR: MOV @R0,#00
- INC R0
- DJNZ R2,CLEAR ;缓冲区清0
- ACALL INT_TO ;定时器T0初始化
- MOV MONTH,#01H
- MOV DAY,#01H
- MOV HOUR,#00
- MOV MINUTE,#00
- MOV DL_2S,#64H
- MOV A,#00
- MOV TEMPER_NUM,A
- MOV TEMPER_L,#00
- MOV TEMPER_H,#00
- MOV DIS_C,#0CH
- ACALL INIT_1820
- LOOP1: NOP
- CALL DISPLY_CLOCK
- CALL DL10MS
- DJNZ DL_2S,LOOP1
- MOV DL_2S,#64H
- LOOP2: CALL DISPLY_DATE
- CALL DL10MS
- DJNZ DL_2S,LOOP2
- MOV DL_2S,#64H
-
- LOOP3: CALL TEMPER
- CALL DISPLY_TEMP
- CALL DL10MS
- DJNZ DL_2S,LOOP3
- MOV DL_2S,#64H
- LJMP LOOP1
- ;初始化程序
- INIT_1820: SETB DQ
- NOP
- CLR DQ ;主机发出延时540us的复位低脉冲
- MOV R0,#36
- LCALL DELAY
- SETB DQ ;然后拉高数据线
- NOP
- NOP
- MOV R0,#36
- TSR2: JNB DQ,TSR3 ;等待DS18B20的回应
- DJNZ R0,TSR2
- LJMP TSR4; 延时
- TSR3: SETB FLAG1; 置标志位,表示DS1820存在
- LJMP TSR5
- TSR4: CLR FLAG1; 清标志位,表示DS1820不存在
- LJMP TSR7
- TSR5: MOV R0,#06BH; 200us
- TSR6: DJNZ R0,TSR6; 复位成功!时序要求延时一段时间
- TSR7: SETB DQ
- RET
- ;//定时器初始化
- INT_TO: MOV COUNT_MIN,#20
- MOV TMOD,#01H
- MOV TH0,#0FFH ;延时50MS,常数3CB0H
- MOV TL0,#0B0H
- SETB EA
- SETB ET0
- SETB TR0
- RET
- ;//================================时钟中断程序
- ORG 0200H
- TIMER_T0:PUSH ACC
- PUSH PSW
- MOV TH0,#0FFH
- MOV TL0,#0B0H
- DJNZ COUNT_MIN,TINEXT
- MOV COUNT_MIN,#20
- MOV A,MINUTE ;分处理
- ADD A,#01H
- DA A
- MOV MINUTE, A
- CJNE A, #60H,TINEXT;分处理结束
- MOV MINUTE,#00 ;分清零
- MOV A,HOUR ;时处理
- ADD A,#01H
- DA A
- MOV HOUR, A
- CJNE A, #24H,TINEXT;时处理结束
- MOV HOUR,#00 ;时清零
- MOV A,DAY ;日处理
- ADD A,#01H
- DA A
- MOV DAY, A
- CJNE A, #31H,TINEXT;日处理结束
- MOV DAY,#01 ;日清零
- MOV A,MONTH ;月处理
- ADD A,#01H
- DA A
- MOV MONTH,A
- CJNE A, #13,TINEXT ;月处理结束
- MOV MONTH,#01 ;月清零
- TINEXT: POP PSW
- POP ACC
- RETI
-
- TEMPER: ACALL RE_CONFIG
- ACALL GET_TEMPER
- CALL TEMPER_COV
- RET
- ;//*****************************************//
- ; 重新写DS18B20暂存存储器设定值
- ;//*****************************************//
- RE_CONFIG: JB FLAG1,RE_CONFIG1; 若DS18B20存在,转RE_CONFIG1
- RET
- RE_CONFIG1:MOV A,#0CCH; 发SKIP ROM命令
- LCALL WRITE_1820
- MOV A,#4EH; 发写暂存存储器命令
- LCALL WRITE_1820
- MOV A,#00H; 不 TH(报警上限)中写入00H
- LCALL WRITE_1820
- MOV A,#00H; TL(报警下限)中写入00H
- LCALL WRITE_1820
- MOV A,#1FH; 选择9位温度分辨率
- LCALL WRITE_1820
- RET
- ;//*****************************************//
- ; 读出转换后的温度值
- ;//*****************************************//
- GET_TEMPER: SETB DQ; 定时入口
- LCALL INIT_1820
- JB FLAG1,TSS2
- RET; 若DS18B20不存在则返回
- TSS2: MOV A,#0CCH; 跳过ROM匹配
- LCALL WRITE_1820
- MOV A,#44H; 发出温度转换命令
- LCALL WRITE_1820
- MOV R0,#50;等待A/D转换结束,12位的话750us
- LCALL DELAY
- LCALL INIT_1820
- MOV A,#0CCH; 跳过ROM匹配
- LCALL WRITE_1820
- MOV A,#0BEH; 发出读温度命令
- LCALL WRITE_1820
- LCALL READ_18200
- MOV TEMPER_NUM,A; 将读出的温度数据保存
- RET
- ;//*****************************************//
- ; 读DS18B20的程序,从DS18B20中读出一个字节的数据
- ;//*****************************************//
- READ_1820: MOV R2,#8
- RE1: CLR C
- SETB DQ
- NOP
- NOP
- CLR DQ
- NOP
- NOP
- NOP
- SETB DQ
- MOV R3,#7
- DJNZ R3,$
- MOV C,DQ
- MOV R3,#23
- DJNZ R3,$
- RRC A
- DJNZ R2,RE1
- RET
- ;//*****************************************//
- ; 写DS18B20的程序
- ;//*****************************************//
- WRITE_1820: MOV R2,#8
- CLR C
- WR1: CLR DQ
- MOV R3,#6
- DJNZ R3,$
- RRC A
- MOV DQ,C
- MOV R3,#23
- DJNZ R3,$
- SETB DQ
- NOP
- DJNZ R2,WR1
- SETB DQ
- RET
- ;//*****************************************//
- ; 读DS18B20的程序,从DS18B20中读出两个字节的温度数据
- ;//*****************************************//
- READ_18200:MOV R4,#2; 将温度高位和低位从DS18B20中读出
- MOV R1,#5BH; 低位存入5BH(TEMPER_L),高位存入5AH(TEMPER_H)
- RE00:MOV R2,#8
- RE01:CLR C
- SETB DQ
- NOP
- NOP
- CLR DQ
- NOP
- NOP
- NOP
- SETB DQ
- MOV R3,#7
- DJNZ R3,$
- MOV C,DQ
- MOV R3,#23
- DJNZ R3,$
- RRC A
- DJNZ R2,RE01
- MOV @R1,A
- DEC R1
- DJNZ R4,RE00
- RET
- ;//*****************************************//
- ; 将从DS18B20中读出的温度数据进行转换
- ;//*****************************************//
- TEMPER_COV: MOV A,#0F0H
- ANL A,TEMPER_L; 舍去温度低位中小数点后的四位温度数值
- SWAP A
- MOV TEMPER_NUM,A
- MOV A,TEMPER_L
- JNB ACC.3,TEMPER_COV1; 四舍五入去温度值
- INC TEMPER_NUM
- TEMPER_COV1: MOV A,TEMPER_H
- ANL A,#07H
- SWAP A
- ORL A,TEMPER_NUM
- MOV TEMPER_NUM,A; 保存变换后的温度数据
- LCALL BIN_BCD
- RET
- ;//*****************************************//
- ; 将16进制的温度数据转换成压缩BCD码
- ;//*****************************************//
- BIN_BCD: MOV DPTR,#TEMP_TAB
- MOV A,TEMPER_NUM
- MOVC A,@A+DPTR
- MOV TEMPER_NUM,A
- RET
- TEMP_TAB: DB 00H,01H,02H,03H,04H,05H,06H,07H
- DB 08H,09H,10H,11H,12H,13H,14H,15H
- DB 16H,17H,18H,19H,20H,21H,22H,23H
- DB 24H,25H,26H,27H,28H,29H,30H,31H
- DB 32H,33H,34H,35H,36H,37H,38H,39H
- DB 40H,41H,42H,43H,44H,45H,46H,47H
- DB 48H,49H,50H,51H,52H,53H,54H,55H
- DB 56H,57H,58H,59H,60H,61H,62H,63H
- DB 64H,65H,66H,67H,68H,69H,70H,71H
- DB 72H,73H,74H,75H,76H,77H,78H,79H
- DB 80H,81H,82H,83H,84H,85H,86H,87H
- DB 88H,89H,90H,91H,92H,93H,94H,95H
- DB 96H,97H,98H,99H
- ;//*****************************************//
- ; 延时子程序
- ;为保证DS18B20的严格I/O时序,需做较精确的延时
- ;在DS18B20操作中,用到的延时有15us、90us、270us、540us、750us
- ;因为这些延时均为15us的倍数,因此可编写一个DELAY15(n)函数
- ;//*****************************************//
- DELAY:
- TEMP_LOOP:MOV R1,#06H
- TEMP_LOOP1:DJNZ R1,TEMP_LOOP1
- DJNZ R0,TEMP_LOOP
- RET
- ;//*****************************************//
- ;500毫秒延时子程序和10毫秒延时子程序
- ;//*****************************************//
- DELAY500:MOV R4,#248
- DA222: MOV R5,#248
- DJNZ R5,$
- DJNZ R4,DA222
- RET
-
- DL10MS: MOV R5,#10
- DL1: MOV R6,#20
- DL: NOP
- NOP
- NOP
- DJNZ R6,DL
- DJNZ R5,DL1
- RET
- ;=================================显示一位子程序
- ;显示子程序
- ;显示缓冲区地址:(R0)
- ;位控(R2)
- DIS: MOV DPTR, #SEG_TAB
- MOV A,@R0
- MOVC A,@A+DPTR
- MOV P0,A ;输出
- NOP
- NOP
- MOV A,R2
- MOV P1,A
- NOP
- NOP
- RET
-
- SEG_TAB: DB 3FH,06H,5BH,4FH
- DB 66H,6DH,7DH,07H
- DB 7FH,6FH,77H,7CH
- DB 39H,5EH,79H,71H
- ;=================================BCD分离子程序
- ; 待转换的数放在(R2)中
- ; 转换结果放在(R0)指出的单元中
- BCDS: MOV A, R2
- ANL A,#00001111B
- MOV @R0,A
- INC R0
- MOV A,R2
- ANL A,#11110000B
- SWAP A
- MOV @R0,A
- RET
- ;================================显示程序
- DISPLY_TEMP:
- MOV R2, TEMPER_NUM; 取温度
- MOV R0, #DIS_TEMP
- CALL BCDS
-
- NOP
- MOV R0,#DIS_C
- MOV R2,#00000101B
- CALL DIS
- CALL DL10MS
- MOV R0,#DIS_TEMP
- MOV R2,#00000100B ;温度个位
- CALL DIS
- CALL DL10MS
- INC R0
- MOV R2,#00000011B ;温度十位
- CALL DIS
- CALL DL10MS
- RET
- DISPLY_CLOCK:
- MOV R2, MINUTE; 取分值
- MOV R0, #DIS_MIN
- CALL BCDS
- MOV R2, HOUR; 取时值
- MOV R0, #DIS_HOUR
- CALL BCDS
-
- NOP
- MOV R0,#DIS_MIN
- MOV R2,#00000101B ;分个位
- CALL DIS
- CALL DL10MS
- INC R0
- MOV R2,#00000100B ;分十位
- CALL DIS
- CALL DL10MS
- INC R0
- MOV R2,#00000010B ;时个位
- CALL DIS
- CALL DL10MS
- INC R0
- MOV R2,#00000001B ;时十位
- CALL DIS
- CALL DL10MS
- RET
- DISPLY_DATE:
- MOV R2, DAY; 取日值
- MOV R0, #DIS_DAY
- CALL BCDS
- MOV R2,MONTH; 取月值
- MOV R0, #DIS_MON
- CALL BCDS
-
- NOP
- MOV R0,#DIS_DAY
- MOV R2,#00000101B ;日个位
- CALL DIS
- CALL DL10MS
- INC R0
- MOV R2,#00000100B ;日十位
- CALL DIS
- CALL DL10MS
- INC R0
- MOV R2,#00000010B ;月个位
- CALL DIS
- CALL DL10MS
- INC R0
- MOV R2,#00000001B ;月十位
- CALL DIS
- CALL DL10MS
- INC R0
- RET
- END
复制代码
|