?? ds18b20應用于2051源程序.txt
字號:
;應用于AT89C2051試驗基本正常
;0--125度
DOT EQU 30H
ZHENGSHU EQU 31H
FLAG1 EQU 38H ;是否檢測到DS18B20的標志位
;定義溫度數據
DIS_1 EQU 32H ;符號
DIS_2 EQU 33H ;十位
DIS_3 EQU 34H ;個位
DIS_4 EQU 35H ;小數點后第一位
DIS_5 EQU 36H ;小數點后第二位
WDDATA BIT P1.7 ;;;;;;;;;(連接DS18B20 IO口引腳)
ORG 0000H
MOV ZHENGSHU,#0
MOV DOT,#0
MAIN:
LCALL INIT_1820 ;調用復位DS18B20子程序
MAIN1:
LCALL GET_TEMPER;調用讀溫度子程序
LCALL FORMULA ;通過公式計算,小數點后顯示兩位
LCALL DISPLAY
AJMP MAIN1
; DS18B20復位初始化程序
INIT_1820:
SETB WDDATA
NOP
CLR WDDATA
;主機發出延時540微秒的復位低脈沖
MOV R0,#36
LCALL DELAY
SETB WDDATA;然后拉高數據線
NOP
NOP
MOV R0,#36
TSR2:
JNB WDDATA,TSR3;等待DS18B20回應
DJNZ R0,TSR2
LJMP TSR4 ; 延時
TSR3:
SETB FLAG1 ; 置標志位,表示DS1820存在
LJMP TSR5
TSR4:
CLR FLAG1 ; 清標志位,表示DS1820不存在
LJMP TSR7
TSR5:
MOV R0,#06BH
TSR6:
DJNZ R0,TSR6 ;復位成功!時序要求延時一段時間
TSR7:
SETB WDDATA
RET
; 讀出轉換后的溫度值
GET_TEMPER:
SETB WDDATA ; 定時入口
LCALL INIT_1820 ;先復位DS18B20
JB FLAG1,TSS2
RET ; 判斷DS1820是否存在?若DS18B20不存在則返回
TSS2:
MOV A,#0CCH ; 跳過ROM匹配
LCALL WRITE_1820
MOV A,#44H ; 發出溫度轉換命令
LCALL WRITE_1820
MOV R0,#50 ;等待AD轉換結束,12位的話750微秒.
;LCALL DISPLAY
LCALL INIT_1820 ;準備讀溫度前先復位
MOV A,#0CCH ; 跳過ROM匹配
LCALL WRITE_1820
MOV A,#0BEH ; 發出讀溫度命令
LCALL WRITE_1820
LCALL READ_18200; 將讀出的九個字節數據保存到60H-68H
RET
;寫DS18B20的子程序(有具體的時序要求)
WRITE_1820:
MOV R2,#8 ;一共8位數據
CLR C
WR1:
CLR WDDATA
MOV R3,#6
DJNZ R3,$
RRC A
MOV WDDATA,C
MOV R3,#24
DJNZ R3,$
SETB WDDATA
NOP
DJNZ R2,WR1
SETB WDDATA
RET
; 讀DS18B20的程序,從DS18B20中讀出九個字節的數據
READ_18200:
MOV R4,#9
MOV R1,#60H ; 存入60H開始的九個單元
RE00:
MOV R2,#8
RE01:
CLR C
SETB WDDATA
NOP
NOP
CLR WDDATA
NOP
NOP
NOP
SETB WDDATA
MOV R3,#09
RE10:
DJNZ R3,RE10
MOV C,WDDATA
MOV R3,#23
RE20:
DJNZ R3,RE20
RRC A
DJNZ R2,RE01
MOV @R1,A
INC R1
DJNZ R4,RE00
RET
;溫度計算子程序
FORMULA: ; 按公式:T實際=(T整數-0.25)+( M每度-M剩余)/ M每度
;計算出實際溫度,整數部分和小數部分分別存于ZHENGSHU單元和DOT單元
;將61H中的低4位移入60H中的高4位,得到溫度的整數部分,并存于ZHENGSHU單元
MOV 29H,61H
MOV A,60H
MOV C,48H
RRC A
MOV C,49H
RRC A
MOV C,4AH
RRC A
MOV C,4BH
RRC A
MOV ZHENGSHU,A
; ( M每度-M剩余)/ M每度,小數值存于A中
MOV A,67h
SUBB A,66h
MOV B,#64H
MUL AB
MOV R4,B
MOV R5,A
MOV R7,67H
LCALL DIV457
MOV A,R3
;再減去0.25,實際應用中減去25
CJNE A,#19H,LL2
LL2: JC LL3
AJMP LL4
LL3:
ADD A,#64H
DEC ZHENGSHU
LL4: SUBB A,#19H
MOV DOT,A ;小數部分存于DOT中
MOV A,ZHENGSHU
SUBB A,#00H ;整數部分減去來自小數部分的借位
MOV ZHENGSHU,A
MOV C,4BH
JNC ZHENG ;是否為負數
CPL A
INC A
MOV DIS_1,#2DH ; 零度以下時,第一位顯示"-"號
MOV ZHENGSHU,A
ZHENG:
MOV DIS_1,#2BH ; 零度以上時,第一位顯示"+"號
RET
;雙字節除以單字節子程序
DIV457: CLR C
MOV A,R4
SUBB A,R7
JC DV50
SETB OV ;商溢出
RET
DV50: MOV R6,#8 ;求平均值(R4R5/R7-→R3)
DV51: MOV A,R5
RLC A
MOV R5,A
MOV A,R4
RLC A
MOV R4,A
MOV F0,C
CLR C
SUBB A,R7
ANL C,/F0
JC DV52
MOV R4,A
DV52: CPL C
MOV A,R3
RLC A
MOV R3,A
DJNZ R6,DV51
MOV A,R4 ;四舍五入
ADD A,R4
JC DV53
SUBB A,R7
JC DV54
DV53: INC R3
DV54: CLR OV
RET
display:
mov a,ZHENGSHU;將29H中的十六進制數轉換成10進制
mov b,#10 ;10進制/10=10進制
div ab
mov DIS_2,a ;十位在a
mov DIS_3,b ;個位在b
mov a,DOT;將29H中的十六進制數轉換成10進制
mov b,#10 ;10進制/10=10進制
div ab
mov DIS_4,a ;十位在a
mov DIS_5,b ;個位在b
mov dptr,#numtab ;指定查表啟始地址
mov r0,#1
dpl1: mov r1,#300 ;顯示1200次
dplop: mov a,DIS_2 ;取十位數
MOVC A,@A+DPTR ;查十位數的7段代碼
mov p1,a ;送出十位的7段代碼
clr p3.3 ;開十位顯示;;;;;;;;;;數碼管十位
acall d1ms ;顯示1ms
setb p3.3
mov a,DIS_3 ;取個位數
MOVC A,@A+DPTR ;查個位數的7段代碼
ANL A,#7FH
mov p1,a ;送出個位的7段代碼
clr p3.4 ;開個位顯示;;;;;;;;;數碼管個位
acall d1ms ;顯示1ms
setb p3.4
mov a,DIS_4 ;取十位數
MOVC A,@A+DPTR ;查十位數的7段代碼
mov p1,a ;送出十位的7段代碼
clr p3.7;開十位顯示;;;;;;;;;數碼管小數點十位
acall d1ms ;顯示1ms
setb p3.7
mov a,DIS_5;取個位數
MOVC A,@A+DPTR ;查個位數的7段代碼
mov p1,a ;送出個位的7段代碼
clr p3.5;開個位顯示;;;;;;;;;數碼管小數點個位
acall d1ms ;顯示1ms
setb p3.5
djnz r1,dplop ;100次沒完循環
djnz r0,dpl1 ;4個100次沒完循環
ret
NUMTAB:DB 0C0H,0F9H,0A4H,0B0H,99H
DB 92H,82H,0F8H,80H,90H,0FFH,0BFH;;;;數碼管(0-9,暗、-)段碼
;1MS延時(按12MHZ算)
D1MS: MOV R7,#50
DJNZ R7,$
RET
;延時子程序
;為保證DS18B20的嚴格I/O時序,需要做較精確的延時
;在DS18B20操作中,用到的延時有15 μs,90 μs,270 μs,540 μs
;因這些延時均為15 μs的整數倍,因此可編寫一個DELAY15(n)函數
DELAY: ;11.05962M晶振 ;12MHZ晶振
LOOP: MOV R1,#06H
LOOP1: DJNZ R1,LOOP1
DJNZ R0,LOOP
RET
END
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -