|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有账号?注册
x
我用DS18B20和AT89S51做了一个数字式温度计,电路板是我自己用导线连接的。
测得我家室内的温度是22.9度,可是水银温度计测得只有20度,水银温度计应该是准确的(我家有两个水银温度计),那是什么原因呢?我把我做的板子和水银温度计一起放到冰箱的冷冻室里,DS18B20测得的温度稍高0.5--1度左右。
请问大家,究竟是什么原因呢?难道是软件设计的原因吗?
附上我写的程序
FIRST BIT P2.1 ;数码管位选通
SECOND BIT P2.0 ;数码管位选通
THIRD BIT P1.4 ;数码管位选通
FOURTH BIT P1.5 ;数码管位选通
TEMPDIN BIT P1.7 ;DS18B20单线接口
Counter EQU 25H ;选通数码管用计数器
BITST DATA 20H
TIME1SOK BIT BITST.1 ;显示温度用,1秒到标志位
TEMPONEOK BIT BITST.2 ;是否初次上电标志位
TEMPHEAD DATA 30H ;30H-38H为单片机ROM中保存温度传感器中“高速暂存器”数据的空间
TEMPL DATA 3AH ;温度值低位暂存区
TEMPH DATA 3BH ;温度值高位暂存区
TEMPLC DATA 3CH ;温度值BCD码低位暂存区
TEMPHC DATA 3DH ;温度值BCD码高位暂存区
DISPBUF EQU 56H ;显示缓冲区首地址
TMRVAR EQU 45536 ;定时20ms
ORG 0000H
JMP START
ORG 000BH
JMP INT_T0
ORG 0030H
START: MOV SP,#5FH
CLSMEM: MOV R0,#20H
MOV R1,#60H
CLSMEM1: MOV @R0,#00H
INC R0
DJNZ R1,CLSMEM1
MOV TMOD,#01H
MOV TH0,#HIGH(TMRVAR)
MOV TL0,#LOW(TMRVAR)
JMP INIT
;
ERROR: NOP
JMP START
;
NOP
INIT: NOP
SETB ET0
SETB EA
SETB TR0
MOV PSW,#00H
CLR TEMPONEOK
JMP MAIN
INT_T0: PUSH PSW
MOV PSW,#10H
MOV TH0,#HIGH(TMRVAR)
MOV TL0,#LOW(TMRVAR)
INC R7
CJNE R7,#50,INT_T01
MOV R7,#00H
SETB TIME1SOK
INT_T01: POP PSW
RETI
;
;
MAIN: CALL DISP
JNB TIME1SOK,MAIN ;每秒测温一次,不到一秒,继续循环
CLR TIME1SOK ;到一秒,清标志位
JNB TEMPONEOK,MAIN1 ;第一次上电先温度转换一次
CALL READTEMP1 ;读出温度值
CALL CONVTEMP ;温度BCD码计算处理
CALL DISPBCD ;显示区温度值时间值BCD码刷新
CALL DISP ;消闪烁,显示一次
MAIN1: CALL READTEMP ;温度转换开始
SETB TEMPONEOK
JMP MAIN
;
;
;子程序区
;***************
;RESET DS18B20
;***************
INITDS1820: SETB TEMPDIN
NOP
NOP
CLR TEMPDIN
MOV R6,#0A0H ;DELAY 480us
DJNZ R6,$
MOV R6,#0A0H
DJNZ R6,$
SETB TEMPDIN
MOV R6,#32H ;DELAY 70us
DJNZ R6,$
MOV R6,#3CH
LOOP1820: MOV C,TEMPDIN
JC INITDS1820OUT
DJNZ R6,LOOP1820
MOV R6,#64H ;DELAY 200us
DJNZ R6,$
JMP INITDS1820
RET
INITDS1820OUT: SETB TEMPDIN
RET
;
;***********************************************
;读DS18B20子程序,从DS18B20中读出一个字节的数据
;***********************************************
READDS1820: MOV R7,#08H
SETB TEMPDIN
NOP
NOP
READDS1820LOOP: CLR TEMPDIN
NOP
NOP
NOP
SETB TEMPDIN
MOV R6,#07H ;DELAY 15ms
DJNZ R6,$
MOV C,TEMPDIN
MOV R6,#3CH ;DELAY 120us
DJNZ R6,$
RRC A
SETB TEMPDIN
DJNZ R7,READDS1820LOOP
MOV R6,#3CH ;DELAY 120us
DJNZ R6,$
RET
;
;************************************************
;写DS18B20的程序,向DS18B20中写一个字节的数据
;************************************************
WRITEDS1820: MOV R7,#08H
SETB TEMPDIN
NOP
NOP
WRITEDS1820LOP:CLR TEMPDIN
MOV R6,#07H ;DELAY 15us
DJNZ R6,$
RRC A
MOV TEMPDIN,C
MOV R6,#34H ;DELAY 104us
DJNZ R6,$
SETB TEMPDIN
DJNZ R7,WRITEDS1820LOP
RET
;**********************************************
;温度转换,从DS18B20的暂存器中读出温度子程序
;**********************************************
READTEMP: CALL INITDS1820 ;RESET DS18B20
MOV A,#0CCH
CALL WRITEDS1820 ;SKIP ROM
MOV R6,#34H ;DELAY 104us
DJNZ R6,$
MOV A,#44H ;启动一次温度转换命令
CALL WRITEDS1820 ;START CONVERSION
MOV R6,#34H ;DELAY 104us
DJNZ R6,$
RET
;
READTEMP1: CALL INITDS1820 ;RESET DS18B20
MOV A,#0CCH
CALL WRITEDS1820 ;SKIP ROM
MOV R6,#34H ;DELAY 104us
DJNZ R6,$
MOV A,#0BEH
CALL WRITEDS1820
MOV R6,#34H
DJNZ R6,$
MOV R5,#09H ;暂存器有9个字节
MOV R0,#TEMPHEAD ;
MOV B,#00H
READTEMP2: CALL READDS1820 ;读出一个字节的数据
MOV @R0,A ;将读出的数据保存在单片机的以#TEMPHEAD为首地址的单元中
INC R0
READTEMP21: CALL CRC8CAL ;CRC校验
DJNZ R5,READTEMP2
MOV A,B
JNZ READTEMPOUT ;若B=0,校验结果正确,B不等于0,退出
MOV A,TEMPHEAD+0
MOV TEMPL,A ;将温度值的低位保存在单片机的TEMPL单元中
MOV A,TEMPHEAD+1
MOV TEMPH,A ;保存高位
READTEMPOUT: RET
;
;****************************************************************************
;处理温度BCD码子程序
;****************************************************************************
CONVTEMP: MOV A,TEMPH
ANL A,#80H ;取符号位
JZ TEMPC1 ;如果符号位为0,则为正值,转
CLR C
MOV A,TEMPL ;负值,温度值为补码形式
CPL A
ADD A,#01H ;将补码转换为原码
MOV TEMPL,A ;将原码送回
MOV A,TEMPH
CPL A
ADDC A,#00H ;将高位转换为原码,带进位加是为了加上低位的进位
MOV TEMPH,A ;将原码送回
MOV TEMPHC,#11 ;“—”号字型码顺序号
JMP TEMPC11
;
TEMPC1: MOV TEMPHC,#10 ;正数消隐符号位
TEMPC11: MOV A,TEMPHC
SWAP A ;将符号调整到高半字节
MOV TEMPHC,A ;TEMPHC高半字节=符号
MOV A,TEMPL
ANL A,#0FH ;取出底半字节的小数部分
MOV DPTR,#TEMPDOTTAB
MOVC A,@A+DPTR ;小数部分以0.0625为步进,通过查表来实现乘0.0625
MOV TEMPLC,A ;TEMPLC低半字节=小数部分BCD
;
MOV A,TEMPL
ANL A,#0F0H ;取TEMPL的整数部分
SWAP A
MOV TEMPL,A
MOV A,TEMPH
ANL A,#0FH ;取TEMPH的整数部分
SWAP A
ORL A,TEMPL ;A中存放完整的整数部分
CALL HEX2BCD1 ;将单字节十六进制整数部分转BCD
MOV TEMPL,A
ANL A,#0F0H ;取“十”位的BCD码
SWAP A ;低位存放
ORL A,TEMPHC ;TEMPHC高半字节为符号
MOV TEMPHC,A ;“符号”位与“十”位置入TEMPHC***********************
MOV A,TEMPL
ANL A,#0FH ;取“个”位的BCD码
SWAP A ;高位存放
ORL A,TEMPLC ;TEMPLC低半字节为小数部分BCD
MOV TEMPLC,A ;“个”位与“小数”位置入TEMPLC***********************
MOV A,R7 ;R7中存放“百”位BCD
JZ TEMPC12 ;“百”位为0,退出
ANL A,#0FH ;取“百”位(“百”位不是0,需将TEMPHC中内容重新调整
;高半字节存“百”位,低半字节存“十”位,不显示符号 )
SWAP A
MOV R7,A
MOV A,TEMPHC
ANL A,#0FH ;取“十”位的BCD码
ORL A,R7
MOV TEMPHC,A ;“百”位与“十”位置入TEMPHC*************************
TEMPC12: RET
;
;**************************************************
; 小数部分码表
;**************************************************
TEMPDOTTAB: DB 00H,01H,01H,02H,03H,03H,04H,04H,05H,06H,06H,07H,08H,08H,09H,09H
;
;**************************************************
; 单字节十六进制转BCD码
;**************************************************
HEX2BCD1: MOV B,#100
DIV AB
MOV R7,A
MOV A,#10
XCH A,B
DIV AB
SWAP A
ORL A,B
RET
;
;
DISPBCD: MOV A,TEMPLC
ANL A,#0FH
MOV DISPBUF+3,A ;温度值小数位送显示缓冲区
MOV A,TEMPLC
SWAP A
ANL A,#0FH
MOV DISPBUF+2,A ;温度值个位送显示缓冲区
MOV A,TEMPHC
ANL A,#0FH
MOV DISPBUF+1,A ;温度值十位送显示缓冲区
MOV A,TEMPHC
SWAP A
ANL A,#0FH
MOV DISPBUF+0,A ;温度值百位送显示缓冲区
RET
;**************************************************
; CRC校验
;**************************************************
CRC8CAL: PUSH ACC
MOV R7,#08H
CRC8LOOP1: XRL A,B
RRC A
MOV A,B
JNC CRC8LOOP2
XRL A,#18H
CRC8LOOP2: RRC A
MOV B,A
POP ACC
RR A
PUSH ACC
DJNZ R7,CRC8LOOP1
POP ACC
RET
;
;*************************************
;显示子程序
;*************************************
DISP: PUSH ACC
PUSH PSW
MOV A,DISPBUF
MOV DPTR,#DISPTAB
MOVC A,@A+DPTR
MOV P0,A
CLR FIRST
LCALL DELAY
SETB FIRST
MOV A,DISPBUF+1
MOVC A,@A+DPTR
MOV P0,A
CLR SECOND
CALL DELAY
SETB SECOND
MOV A,DISPBUF+2
MOVC A,@A+DPTR
MOV P0,A
CLR THIRD
CALL DELAY
SETB THIRD
MOV A,DISPBUF+3
MOVC A,@A+DPTR
MOV P0,A
CLR FOURTH
CALL DELAY
SETB FOURTH
POP PSW
POP ACC
RET
;
;
;显示延时子程序,延时1mS
DELAY: MOV R7,#14H
D1: MOV R6,#19H
DJNZ R6,$
DJNZ R7,D1
RET
;
DISPTAB: DB 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H,0FFH,0BFH
; 0 1 2 3 4 5 6 7 8 9 消隐“—”
END
|
|