匯編源程序如下:
ORG 0000H
TEMPER_L EQU 41H ;用于保存讀出溫度的低8位
TEMPER_H EQU 40H ;用于保存讀出溫度的高8位
FLAG1 EQU 38H ;是否檢測到DS18B20標志位
A_BIT1 EQU 31H ;數碼管個位數存放內存位置
B_BIT1 EQU 32H ;數碼管十位數存放內存位置
D_BIT1 EQU 35H ;數碼管百位數存放內存位置
DQ EQU P3.7 ;30H,31H,32H,33H: X 個位 十位 X
MOD7: MOV SP,#60H
LCALL GET_TEMPER ;調用讀溫度子程序
LCALL TEMPCOV
LCALL DISPLAY ;調用數碼管顯示子程序
AJMP MOD7
TEMP0: INC A
AJMP TEMP1
TEMPCOV: MOV A,TEMPER_L ;數據處理子程序TEMPCOV
MOV B,#16
DIV AB
JB B.3,TEMP0
TEMP1: MOV 34H,A ;將TEMPER_L的高四位右移四位,存入34H中(溫度值)
MOV A,B ;將TEMPER_L的低四位X10/16得小數后一位數.
MOV B,#10
MUL AB
MOV B,#16
DIV AB
MOV 30H,A ;將小數后一位數.存入30H中
MOV A,TEMPER_H ;TEMPER_H中存放高8位數,權重16
MOV B,#16
MUL AB
ADD A,34H ;34H中存入溫度值的整數部分
MOV B,#10
DIV AB
MOV 31H,B ;個位存入31H中
MOV B,#10 ;
DIV AB ;
MOV 32H,B ;十位存入32H中
MOV B,#10 ;
DIV AB ;
MOV 35H,B ;百位存入33H中
MOV A,TEMPER_H
MOV 33H,#10H ;
JB ACC.7,EXIT7
MOV 33H,#00H
EXIT7: RET
INIT_1820: ;這是DS18B20復位初始化子程序
SETB DQ
NOP
CLR DQ ;主機發出延時537微秒的復位低脈沖
MOV R1,#3
TSR1: MOV R0,#107
DJNZ R0,$
DJNZ R1,TSR1
SETB DQ ;然后拉高數據線
NOP
NOP
NOP
MOV R0,#25H
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,#117
TSR6: DJNZ R0,TSR6 ;時序要求延時一段時間
TSR7: SETB DQ
RET
GET_TEMPER: ;讀出轉換后的溫度值
SETB DQ
LCALL INIT_1820 ;先復位DS18B20
JB FLAG1,TSS2
RET ;判斷DS1820是否存在?若DS18B20不存在則返回
TSS2: MOV A,#0CCH ;跳過ROM匹配
LCALL WRITE_1820
MOV A,#44H ;發出溫度轉換命令
LCALL WRITE_1820
LCALL DISPLAY ;等待AD轉換結束,12位的話750微秒
LCALL INIT_1820 ;準備讀溫度前先復位
MOV A,#0CCH ;跳過ROM匹配
LCALL WRITE_1820
MOV A,#0BEH ;發出讀溫度命令
LCALL WRITE_1820
LCALL READ_18200 ;將讀出的溫度數據保存到35H/36H
RET
;寫DS18B20的子程序(有具體的時序要求)
WRITE_1820: MOV R2,#8 ;一共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,#TEMPER_L ;低位存入TEMPER_L(TEMPER_L),高位存入(TEMPER_H)
RE00: MOV R2,#8 ;數據一共有8位
RE01: CLR C
SETB DQ
NOP
NOP
CLR DQ
NOP
NOP
NOP
SETB DQ
MOV R3,#9
RE10: DJNZ R3,RE10
MOV C,DQ
MOV R3,#23
RE20: DJNZ R3,RE20
RRC A
DJNZ R2,RE01
MOV @R1,A
DEC R1
DJNZ R4,RE00
RET
;顯示子程序
DISPLAY: MOV DPTR,#TABLE ;指定查表啟始地址
MOV R0,#4
DPL1: MOV R1,#250 ;顯示1000次
DPLOP: MOV A,A_BIT1 ;取個位數
MOVC A,@A+DPTR ;查個位數的7段代碼
MOV P0,A ;送出個位的7段代碼
CLR P2.0 ;開個位顯示
ACALL D1MS ;顯示1MS
SETB P2.0
MOV A,B_BIT1 ;取十位數
MOVC A,@A+DPTR ;查十位數的7段代碼
MOV P0,A ;送出十位的7段代碼
CLR P2.1 ;開十位顯示
ACALL D1MS ;顯示1MS
SETB P2.1
MOV A,D_BIT1 ;取百位數
MOVC A,@A+DPTR ;查百位數的7段代碼
MOV P0,A ;送出百位的7段代碼
CLR P2.2;開百位顯示
ACALL D1MS ;顯示1MS
SETB P2.2
MOV P0,#00H
DJNZ R1,DPLOP ;100次沒完循環
DJNZ R0,DPL1 ;4個100次沒完循環
RET
;1MS延時(按12MHZ算)
D1MS: MOV R7,#0FFH
DJNZ R7,$
RET
;7段數碼管0~9數字的共陽顯示代碼
TABLE:DB 0C0H,0F9H,0A4H,0B0H,99H
DB 92H,82H,0F8H,80H,90H
END
注:晶振12MHZ。
本程序已通過實踐驗證!!!