本帖最后由 51黑黑黑 于 2016-3-3 00:58 編輯
(一) 數字溫度傳感器DSl8B20介紹
以下為 DS1820 的詳細特性 l 獨特的單線接口僅需一個端口引腳進行通訊 l 簡單的多點分布應用 l 無需外部器件 l 可通過數據線供電 l 零待機功耗 l 測溫范圍-55~+125℃,以0.5℃遞增。華氏器件-67~+2570F,以0.90F 遞增 l 溫度以 9 位數字量讀出 l 溫度數字量轉換時間 200ms(典型值) l 用戶可定義的非易失性溫度報警設置 l 報警搜索命令識別并標志超過程序限定溫度(溫度報警條件)的器件 l 應用包括溫度控制、工業系統、消費品、溫度計或任何熱感測系統
由上表可見DS18B20適用電壓為3V~5V,有更寬的電壓適用范圍,DS18B20可以程序設定9~12 位的分辨率,精度為±0.5°C。可選更小的封裝方式。用戶設的分辨率和報警溫度可以存儲在EEPROM 中,掉電后依然保存。DS18B20的性能是新一代產品中最好的。 DS1822與DS18B20 軟件兼容,是DS18B20的簡化版本。省略了存儲用戶定義報警溫度、分辨率參數的EEPROM,精度降低為±2°C,適用于對性能要求不高,成本控制嚴格的應用,是經濟型產品。 每只D51820都可以設置成兩種供電方式即數據總線供電方式和外部供電方式,采取數據總線供電方式可以節省一根導線但完成溫度測量的時間較長。采取外部供電方式則多用一根導線但測量速度較快。 每只DSl8B20包括一個唯一的64位長的序號,該序號值存放在DSl8B20內部的ROM(只讀存貯器)中。開始8位是產品類型編碼,接著的48位是每個器件唯一的序號,最后8位是前面56位的CRC(循環冗余校驗)碼。因為每一個DSl8B20在出廠時已經給定了唯一的序號,因此在同一條單線總線上可以連接多個DSl8B20。 DSl8B20的存儲器由9個字節組成,存儲器結構示于下圖。存儲器有一個暫存SRAM和一個存儲高低報警觸發值TH和TL的非易失性電可擦除EEPROM組成。注意當報警功能不使用時,TH和TL寄存器可以被當作普通寄存器使用。 DSl8B20的引腳如下圖l所示: (二)DSl8B20工作過程及時序
主機控制DS18B20完成溫度轉換必須經過三個步驟:初始化、ROM操作指令、存儲器操作指令。必須先啟動DS18B20開始轉換,再讀出溫度轉換值。 1、初始化
單總線上的所有處理均從初始化開始。
2、ROM操作命令
總線主機檢測到DSl8B20的存在便可以發出ROM操作命令。

3、存儲器操作命令

4、時序
1)復位:對DS18B20操作之前,首先要將它復位。復位時序為:
(1)主機將信號線置為低電平,時間為400~960μS。
(2)主機將信號線置為高電平,時間為15~60μS。
(3)DS18B20發出60~240μS 的低電平作為應答信號。主機收到此信號后,才能對DS18B20作其它操作。

2)寫操作:主機將信號線從高電平拉至低電平,產生寫起始信號。從信號線的下降沿開始,在15~60μS的時間內,DS18B20對信號線檢測,如信號線為高電平,則寫1,如信號線為O,則寫0,從而完成了一個寫周期。在開始另一個寫周期前,必須有1μ S以上的 高電平恢復期。

3)讀操作:主機將信號線從高電平拉低至低電平1μ S以上,再使數據線升為高電平,產生讀起始信號。從主機將信號線從高電平拉低至低電平起15~60μS的時間內,DS18B20將數據放到信號線上,供主機讀取。從而完成了一個讀周期。在開始另一個讀周期前,必須有1μ S以上的高電平恢復期。

(三)溫度與數據關系
DS18B20在出廠時配置為12位溫度數據,讀取溫度時共讀取16位,16位數字擺放是從低位到高位,存儲在18B20的兩個8比特的RAM中,二進制數中的前面5位是符號位,如果測得的溫度大于0,這5位為0,此時把溫度高字節的低3位與溫度低字節的高4位合并成一個字節再轉成十進制數是溫度的整數部分。溫度低字節的低4位乘以0.0625或除以16所測的溫度的小數部分。如果溫度小于0,這5位為1,測到的數值需要取反加1,然后再把溫度高字節的低3位與溫度低字節的高4位合并成一個字節再轉成十進制數就是溫度的整數部分。溫度低字節的低4位乘以0.0625或除以16所測的溫度的小數部分。 (四)DS18B20中的低溫觸發器TL、高溫觸發器TH,用于設置低溫、高溫的報警數值。DS18B20完成一個周期的溫度測量后,將測得的溫度值和TL、TH相比較,如果小于TL,或大于TH,則表示溫度越限,將該器件內的告警標志位置位,并對主機發出的告警搜索命令作出響應。需要修改上、下限溫度值時,只需使用一個功能命令即可對TL、TH寫入,十分方便。 (五)具體操作舉例: 現在我們要做的是讓DS18B20進行一次溫度的轉換,那具體的操作就是: 1、主機先作個復位操作, 2、主機再寫跳過ROM的操作(CCH)命令, 3、然后主機接著寫個轉換溫度的操作命令,后面釋放總線至少一秒,讓DS18B20完成轉換的操作。在這里要注意的是每個命令字節在寫的時候都是低字節先寫,例如CCH的二進制為11001100,在寫到總線上時要從低位開始寫,寫的順序是“零、零、壹、壹、零、零、壹、壹”。整個操作的總線狀態如下圖。 
讀取RAM內的溫度數據。同樣,這個操作也要接照三個步驟。 1、主機發出復位操作并接收DS18B20的應答(存在)脈沖。 2、主機發出跳過對ROM操作的命令(CCH)。 3、主機發出讀取RAM的命令(BEH),隨后主機依次讀取DS18B20發出的從第0一第8,共九個字節的數據。如果只想讀取溫度數據,那在讀完第0和第1個數據后就不再理會后面DS18B20發出的數據即可。同樣讀取數據也是低位在前的。整個操作的總線狀態如下圖: (六)單片機程序代碼 ;采用stc11f04e單片機,晶振3.6864MHZ,通訊速率9600,30H,32H存放溫度值的高字節,31H,33H存放溫度值的低字節
;34H用于保存溫度的小數部分;35H用于保存整數部分;36H用于保存溫度;38H39H用于保存小數部分,20H.1保存正負溫度標志
ORG 0000H
AJMP MAIN;轉入主程序
ORG 0003H ;外部中斷P3.2腳INT0入口地址
RETI
ORG 000BH;中斷陷阱
;LJMP CT
RETI
ORG 0013H;中斷陷阱
RETI
ORG 0023H
;LJMP S
TPH DATA30H ;存放溫度值的高字節
TPL DATA31H ;存放溫度值的低字節
XS EQU 34H;用于保存溫度的小數部分
ZS EQU 35H;用于保存整數部分
P1M0 DATA 92H
P1M1 DATA 91H
DQ EQU P3.5;DS18B20的數據口位
WDT_CONTR EQU 0C1H
AUX EQU 0A2H ;P3.0RXD-P3.1TXD TO P1.6RXD-P1.7TXD
FLAG_1 EQU 20H.1 ;接收到下行串口發來數據標志p1.6
MAIN: MOV SCon,#50h; 方式1,REN=1.SM0,SM1,SM2,REN,TB8,RB8,TI,RI
MOV TMOD,#21H;波特率發生器T1工作在模式2上
MOV TH1,#0FFH;預置初值(按照波特率9600BPS預置初值) 24M=9600=F3 3.6864=FF=9600, 1200=f8
MOV TL1,#0FFH;預置初值(按照波特率9600BPS預置初值) 13.56=9600倍頻=F9
MOV TH0,#88H ;8800=12t,7000=stc1t
MOV TL0, #00H
ORL IE, #92H ;EA=1,ES=1;ET0=1
SETBPS ;串口中斷優先
SETBTR1 ;啟動定時器1
MOVP1M0,#01000000b ; P1M0=0 P1M1=0雙向口 P1M0=1 P1M1=0輸入口 P1M0=0 P1M1=1推挽輸出20ma
MOV P1M1,#10000000b
MOV WDT_CONTR ,#27H;;;;;;看門狗設置使能
CPL P3.2
QL: MOV A,#00H
MOV R2,#58 ;清數據區;;
MOV R0,#20H
QRAM: MOV @R0, A
INC R0
DJNZ R2, QRAM
; MOV WDT_CONTR ,#17H;喂狗
QW: CALL DELAY1
CALL DELAY1
CALL DELAY1
CALL DELAY1
;JNB FLAG_1,QQ
LCALL DS18B20
CALL FZJ
CLR FLAG_1
QQ: CPL P3.2
CALL DELAY1
CALL DELAY1
CALLDELAY1
CALL DELAY1
AJMP QL
DS18B20: ;CLR EA;
CALLDS18B20_Reset ;設備復位
MOVA,#0CCH ;跳過ROM命令
CALL DS18B20_WriteByte ;送出命令
MOVA,#044H ;開始轉換 溫度轉換 44H啟動DS18B20進行溫度轉換
CALL DS18B20_WriteByte ;送出命令
DELAY: ; MOV WDT_CONTR ,#17H;喂狗
JNBDQ,DELAY ;等待轉換完成
CALLDS18B20_Reset ;設備復位
MOVA,#0CCH ;跳過ROM命令
CALL DS18B20_WriteByte ;送出命令
MOVA,#0BEH ;讀暫存存儲器讀暫存器BEH讀暫存器9個字節內容
CALLDS18B20_WriteByte ;送出命令
CALL DS18B20_ReadByte ;讀溫度低字節
MOVTPL,A ;存儲數據
CALL DS18B20_ReadByte ;讀溫度高字節
MOVTPH,A ;存儲數據
MOV A,TPH;30H
RLC A
MOV20H.1,c ;保存正負溫度標志
JNCZH ;最高位是0為零上溫度轉ZH
;最高位是1為零下溫度取反加1
MOVA,TPH;30H ;例如溫度是-54.875度,源碼=11001001 001XXXXX 例如溫度72.75,30h=48h,31h=40h,加在一起是01001000(=30H)010xxxxx=(31H)
CPLA ;00110110=(30H)
MOV32H,A ;高位取反
MOVA,TPL;31H ;低位取反110XXXXX
CPLA ;110XXXXXX=(31H)
MOV33H,A ;保存高2位到(32h)=01H,最后轉換成242H=578d,578*0.125=72.75
MOVA,#01H ;10110111=B7
ADD A,33H
MOV 33H,A
CLR A
ADDCA,32H ;例如溫度是-54.875度=-439*.125,補碼649h,-649h=1110 0100 1001
MOV32H,A ;結果是32h=01,33h=b7,合并成1b7h取反=00110110110,加1=00110110111為正碼1b7h=439,39*.125=54.875
AJMP LS
ZH: MOV A,TPH;30H
MOV32H,A ;保存高2位到(32h)=02H,最后轉換成242H=578d,578*0.125=72.75
MOV A,TPL
MOV33H,A ;保存到33h=01000010=42H
LS: MOV A,TPL
ANL A,#0FH ;存放溫度的低字節的低四位決定小數部分
MOV XS,A ;獲得小數部分34H
MOV A,TPL
ANL A,#0F0H
SWAP A
MOVZS,A ;35H存放溫度的低字節的高四位
MOV A,TPH ;獲取存放溫度的高字節的低三位
ANL A,#07H
SWAPA
ORLA,ZS ;存放溫度的低字節的高四位合并存放溫度的高字節的低三位決定整數部分
MOV ZS,A
MOV B,#100;分離出百位,存放在R3中
DIV AB
MOV R3,A
MOV A,#10 ;余數繼續分離十位和個位
XCH A,B
DIV AB
SWAP A
ORL A,B ;十位和個位拼裝成BCD碼
MOV 36H,A
MOV A,XS
MOV R0,#37H
MOVR2,#4
D0: MOV B,#10
MUL AB
MOV B,#16
DIV AB
MOV @R0,A
INC R0
MOV A,B
DJNZ R2,D0
MOV R0,#37H
MOV A,@R0
INC R0
SWAP A
ORL A,@R0
MOV 37H,A
INC R0
MOV A,@R0
INC R0
SWAP A
ORL A,@R0
MOV 38H,A
MOV 39H,#0AAH
RET ;20H.1保存正負溫度標志
;**************************************
;延時X微秒(STC11f04e@3.6864M)
;不同的工作環境,需要調整此函數
;入口參數:R7
;出口參數:無DS18B20在出廠時以配置為12位,讀取溫度時共讀取16位,所以把溫度高字節的低3位與溫度低字節的高4位合并成一個字節再轉成十進制數是溫度的整數部分。
;溫度低字節的低4位乘以0.0625或除以16所測的溫度的小數部分。
;還需要判斷正負。前5個數字為符號位,當前5位為1時,讀取的溫度為負數;當前5位為0時,讀取的溫度為正數。
;**************************************
DelayXus: ;6 此延時函數是使用1T的指令周期進行計算,與傳統的12T的MCU不同
NOP ;1
DJNZR7,DelayXus ;4
RET ;4
;DelayXus1: MOVR6,#255 ;6 此延時函數是使用1T的指令周期進行計算,與傳統的12T的MCU不同 6.7584=22/3.255
;DelayXus2: CALL DelayXus
; DJNZR6,DelayXus2 ;4
; RET ;4
;**************************************
;復位DS18B20,并檢測設備是否存在
;入口參數:無
;出口參數:無
;**************************************
DS18B20_Reset:MOV WDT_CONTR,#37H;喂狗
CLRDQ ;送出低電平復位信號
MOVR7,#240 ;延時至少480us
CALL DelayXus
MOV R7,#240
CALL DelayXus
SETBDQ ;釋放數據線
MOVR7,#60 ;等待60us
CALL DelayXus
MOV C,DQ ;檢測存在脈沖
MOVR7,#240 ;等待設備釋放數據線
CALL DelayXus
MOV R7,#180
CALL DelayXus
JCDS18B20_Reset ;如果設備不存在,則繼續等待
RET
;**************************************
;從DS18B20讀1字節數據
;入口參數:無
;出口參數:ACC
;**************************************
DS18B20_ReadByte:
CLR A
PUSH 0
MOV0,#8 ;8位計數器
ReadNext:
CLRDQ ;開始時間片
MOVR7,#1 ;延時等待
CALL DelayXus
SETBDQ ;準備接收
MOV R7,#1
CALL DelayXus
MOVC,DQ ;讀取數據
RRC A
MOVR7,#60 ;等待時間片結束
CALL DelayXus
DJNZ 0,ReadNext
POP 0
RET
;**************************************
;向DS18B20寫1字節數據
;入口參數:ACC
;出口參數:無
;**************************************
DS18B20_WriteByte:
PUSH 0
MOV0,#8 ;8位計數器
WriteNext:
CLRDQ ;開始時間片
MOVR7,#1 ;延時等待
CALL DelayXus
RRCA ;輸出數據
MOV DQ,C
MOVR7,#60 ;等待時間片結束
CALL DelayXus
SETBDQ ;準備送出下一位數據
MOV R7,#1
CALL DelayXus
DJNZ 0,WriteNext
POP 0
RET
FZJ: MOVR0,#30H ;向主機發送35h單元開始的8個定時器時鐘數據子程序 1B60000000600000
FZJ0: MOV R2,#0AH
FZJ1: CLR EA
ANLAUX,#07FH ;p3.0p3.1當串口
FZL1: MOV A, @R0
MOV SBUF, A
JNB TI, $
CLR TI
INC R0
DJNZ R2,FZL1
SETB EA
RET
DELAY2: MOV R5, #0FFH
DEL: MOV WDT_CONTR ,#17H;喂狗
DJNZ R5, DEL
RET
DELAY1: MOV R6, #0FFH
DELA: ACALL DELAY2
DJNZ R6, DELA
RET
END
帶溫度顯示的LED電子表
下面的例子是利用18B20制作一個簡單的帶溫度顯示的LED電子表,電路原理圖和顯示結果如下圖所示,晶體振蕩器采用7.3128Mhz,如果用其它頻率的晶體,需要改變延遲子程序DelayXus,其它程序結構不變,利用單片機的定時器0定時功能構成電子表,每天有9秒的誤差,可以通過調整達到每月誤差不到1秒,因為本機非常省電,可以長期帶電運行,如遇停電,需要重新調整時鐘,有2個按鍵分別調整時和分,調整比較方便,所以就不加時鐘模塊了,實驗證明與魚缸溫度計比較18B20數字溫度計還是比較準確的。下面給出了源程序代碼,因為注釋的比較詳細,很容易看的懂。程序主要由初始化模塊、定時器模塊、溫度采集模塊組成。內存使用情況是2FH,2EH溫度整數位顯示區,2DH,2CH是溫度小數位顯示區,36H,35H是小時顯示區,34H,33H分鐘顯示區,每隔5秒鐘左右交替顯示時鐘和溫度。25H單元是10毫秒存儲區,夠100毫秒30H加1,31H是秒個位存儲,32H是秒十位存儲。P1.4是米字型數碼管控制端,當p1.4=0為低電平(反相后為高)時,p1.6=1,(反相后為低)中間橫條顯示,P1.6 是米字型數碼管共陰極com選通控制端,P1.7數碼管小數點選通控制。


;程序源代碼如下:
ORG0000H
AJMP L00 ;電子表程序20151215通過 ORG 000BH ; AJMP CT RETI
ORG 001BH
RETI
ORG 0023H
TPH DATA28H ;存放溫度值的高字節
TPL DATA29H ;存放溫度值的低字節
XS EQU26H ;用于保存溫度的小數部分
ZS EQU27H ;用于保存整數部分
XT EQUP3.6 ;MC14513選通
DQ EQUP3.7 ;DS18B20的數據口位
FLAG1 EQU 20H.0
ORG 0030H;初始化子程序
L00: MOV SP,#68H ;設堆棧指針
MOV SCon,#50h; 方式1,REN=1.SM0,SM1,SM2,REN,TB8,RB8,TI,RI
MOV TMOD,#21H;波特率發生器T1工作在模式2上
MOV TH1,#0FFH;預置初值(按照波特率9600BPS預置初值)
MOV TL1,#0FFH;預置初值(按照波特率9600BPS預置初值)
MOV TH0,#0E6H ;7.3128= 11F4H ,方式1,16位定時
MOV TL0, #3EH
ORL IE, #92H ;EA=1,ES=1;ET0=1
SETBPS ;串口中斷優先
QL0: MOV A,#00H
MOV R0,#10H
MOV R2,#60H ;10-ABH清零
CLEAR: MOV @R0,A
INC R0
DJNZ R2,CLEAR
MOV 36H,#01H
MOV 35H,#02H
MOV 34H,#03H
MOV 33H,#00H
CLR FLAG1
;顯示子程序和時鐘調整子程序
DIS:SETB EA ;開AT89C51中斷
SETB ET0 ;允許AT89C51的TIME0中斷
SETB TR0 ;T0開始計數
MOVA,31H ;31H十秒加1?30h是每秒加1
XRL A,#09h
JNZ DIS0
CALL DS18B20;
DIS0: JNB P3.5,DIS4 ;為低再看秒十位單元是否為0
CLR TR0 ;校驗表程序,調整分
MOVA,30H ;31H十秒加1?30h是每秒加1
JNZDIS6 ;秒位=0,自動小時加1
JB FLAG1,DIS6
DIS5: MOV R0,#35H ;校驗表程序,調整小時
SETB FLAG1
ACALL GIA2
MOV R0, #36H
MOV A, @R0
DEC R0
SWAP A
ADD A, @R0
MOV 2DH, A
CJNE A, #24H, DIS6
CLR A
MOV 35H, A
MOV 36H, A
AJMP DIS6
DIS4: JNBP3.1 ,DIS6
CLR TR0 ;校驗表程序調整分
MOVA,30H ;31H十秒加1?30h是每秒加1
JNZDIS6 ;秒位=0,自動小時加1
MOV 31H, #00H
MOV 32H, #00H
DIS7: MOV R0, #33H
JBFLAG1,DIS6 ;
SETB FLAG1
ACALL GIA2
MOV R0, #34H
MOV A, @R0
DEC R0
SWAP A
ADD A, @R0
MOV 2DH, A
CJNE A, #60H, DIS6
CLR A
MOV 33H, A
MOV 34H, A
DIS6: MOV R2,#01H ;R2是位選信號01-04移位 顯示子程序顯示33h-36h單元數值
MOV A,31H
SUBBA,#05H ;6789秒顯示時間,012345秒顯示溫度
JC DIS9
MOV R1,#33H ;顯示時間的起始地址33h-36h
AJMP DIS8
DIS9: MOV R1,#2CH ;顯示溫度的起始地址2ch-2fh
DIS8: SETB TR0
DIS1: MOVA,@R1
MOVP0,A ;送數據
SETB XT ;控制MC14513LE ,當BI,LT為1 ,LE上升沿鎖存輸出,高電平時不變
MOVA,R2 ;
MOV P1,A ;P0.0-P0.3控制4段數碼管共陰極導通,為1反相后為0,數碼管導通
INC R1
MOV A,R2
RL A
MOV R2,A
MOV A,R2 ;第2位小數點閃動
JNB 0E3H,DIS3 ;第2位小數點閃動E3
MOV A,30H
JNZ DIS3
CPLP1.7 ;每秒小數點閃動一次,(CPLP1.7)
DIS10: MOV C,20H.7
SETBp1.6 ;SETBP1.6;經2003反相后變成低電平,米字型數碼管選通
JC DIS2
SETBP1.4 ;十字不亮
AJMP DIS3
DIS2: CLRp1.4 ;豎線不亮,其它一秒一閃
DIS3: LCALLDELAY ;位掃描
CLRXT ;
JB 0E4H, J6
AJMP DIS1
J6: AJMP DIS
;定時器中斷子程序
CT: MOV TH0,#0E8H ;7.3128= 11F4H ,方式1,16位定時E832=10MS E63E)
MOV TL0,#08H ;0FFC慢,1000快E810快 E7F0慢 E807慢
PUSH 0D0H
PUSH 0E0H
PUSH 82H
PUSH 83H
MOV A,25H ;
INC A
MOV 25H, A
CJNE A, #0AH,DONE ;0fff=0a,e63e=64
MOV 25H, #00H
MOV A,30H ;
INC A
MOV 30H, A
CJNE A, #0AH,DONE ;
MOV 30H, #00H
MOV A, 31H;5H
INC A ;秒個位加1
CLRFLAG1 ;31H十秒加1?30h是每秒加1
MOV 31H,A ;5
CJNE A, #0AH, DONE
; CPLFLAG2 ;31H十秒加1?30h是每秒加1
MOV 31H, #00H ;5
MOV A, 32H;4H
INC A ;秒十位加1
MOV 32H,A ;4
CJNE A, #06H,DONE
MOV 32H, #00H ;4
MOV A, 33H
INC A ;分位加1
MOV 33H, A
CJNE A, #0AH,DONE
MOV 33H, #00H
MOV A, 34H;2H
INC A ;分十位加1
MOV 34H, A ;4
CJNE A, #06H,DONE
MOV 34H, #00H ;4
MOV R0,#35H ;1
ACALL GIA1
MOV R0, #36H
MOV A, @R0
DEC R0
SWAP A
ADD A, @R0
MOV 2DH, A
CJNE A, #24H, DONE
CLR A
MOV 35H, A
MOV 36H, A
MOVA,30H ; 1/10秒單元加7,補償慢9秒
ADD A,#07H
MOV 30H,A
MOVA,31H ;秒單元加9,補償慢9秒
ADD A,#09H
MOV 31H,A
; AJMP X
DONE: NOP
POP 83H
POP 82H
POP 0E0H
POP 0D0H
RETI
GIA1: MOV R1, #04H
GIA2: MOV A, @R0
GIA: INC A
MOV @R0, A
CJNE A, #0AH, GIA3
CLR A
MOV @R0, A
INC R0
DJNZ R1, GIA2
GIA3: RET
ORG 0712H
DELAY: MOV R5, #66H;88H
DEL: NOP
DJNZ R5, DEL
RET
;溫度采集子程序
DS18B20: ;CLR EA;
CALLDS18B20_Reset ;設備復位
MOVA,#0CCH ;跳過ROM命令
CALL DS18B20_WriteByte ;送出命令
MOVA,#044H ;開始轉換 溫度轉換 44H 啟動DS18B20進行溫度轉換
CALL DS18B20_WriteByte ;送出命令
JNBDQ,DELAY ;等待轉換完成
CALLDS18B20_Reset ;設備復位
MOVA,#0CCH ;跳過ROM命令
CALL DS18B20_WriteByte ;送出命令
MOVA,#0BEH ;讀暫存存儲器讀暫存器 BEH 讀暫存器9個字節內容
CALL DS18B20_WriteByte ;送出命令
CALL DS18B20_ReadByte ;讀溫度低字節
MOVTPL,A ;存儲數據
CALL DS18B20_ReadByte ;讀溫度高字節
MOVTPH,A ;存儲數據
MOV A,TPH;30H
RLC A
MOV20H.7,c ;保存正負溫度標志
JNCZH ;最高位是0為零上溫度轉ZH
;最高位是1為零下溫度取反加1
MOVA,TPH;28H ;例如溫度是-54.875度,源碼=1100 1001 001XXXXX 例如溫度72.75,30h=48h,31h=40h,加在一起是01001000(=30H) 010xxxxx=(31H)
CPLA ;00110110=(30H)
MOV2AH,A ;高位取反
MOVA,TPL;29H ;低位取反110XXXXX
CPLA ;110XXXXXX=(31H)
MOV2BH,A ;保存高2位到(32h)=01H ,最后轉換成242H=578d,578*0.125=72.75
MOVA,#01H ;10110111=B7
ADD A,2BH
MOV 2BH,A
CLR A
ADDCA,2AH ;例如溫度是-54.875度=-439*.125,補碼649h,-649h=1 110 0100 1001
MOV2AH,A ;結果是32h=01,33h=b7,合并成1b7h 取反=00110110110,加1=00110110111為正碼1b7h=439,39*.125=54.875
AJMP LS
ZH: MOV A,TPH;30H
MOV2AH,A ;保存高2位到(32h)=02H ,最后轉換成242H=578d,578*0.125=72.75
MOV A,TPL
MOV2BH,A ;保存到33h=01000010=42H
LS: MOV A,2BH;TPL
ANL A,#0FH ;存放溫度的低字節的低四位決定小數部分
MOV XS,A ;獲得小數部分34H
MOV A,2BH;TPL
ANL A,#0F0H
SWAP A
MOVZS,A ;35H存放溫度的低字節的高四位
MOV A,2AH;TPH ;獲取存放溫度的高字節的低三位
ANL A,#07H
SWAPA
ORLA,ZS ;存放溫度的低字節的高四位合并存放溫度的高字節的低三位決定整數部分
MOV ZS,A
MOV B,#100;分離出百位,存放在R3中
DIV AB
MOV R3,A
MOVA,#10 ;余數繼續分離十位和個位
XCH A,B
DIV AB
; SWAP A
; ORL A,B ;十位和個位拼裝成BCD碼
MOV 2FH,A
MOV A,B
MOV 2EH,A
MOV A,XS
MOV R0,#37H
MOV R2,#4
D0: MOV B,#10
MUL AB
MOV B,#16
DIV AB
MOV @R0,A
INC R0
MOV A,B
DJNZ R2,D0
MOV 2DH,37H
MOV 2CH,38H
RET ;20H.7保存正負溫度標志
DelayXus: NOP ;6微秒
DJNZR7,DelayXus ;
RET ;
;**************************************
;復位DS18B20,并檢測設備是否存在
;入口參數:無
;出口參數:無
;**************************************
DS18B20_Reset:;MOV WDT_CONTR ,#37H;喂狗
CLRDQ ;送出低電平復位信號
MOVR7,#40;240 ;延時至少480us
CALL DelayXus
MOV R7,#40;240
CALL DelayXus
SETB DQ ;釋放數據線
MOVR7,#10;60 ;等待60us
CALL DelayXus
MOVC,DQ ;檢測存在脈沖
MOVR7,#40;240 ;等待設備釋放數據線
CALL DelayXus
MOVR7,#30;180
CALL DelayXus
JCDS18B20_Reset ;如果設備不存在,則繼續等待
RET
;**************************************
;從DS18B20讀1字節數據
;入口參數:無
;出口參數:ACC
;**************************************
DS18B20_ReadByte:
CLR A
PUSH 0
MOV0,#8 ;8位計數器
ReadNext:
CLRDQ ;開始時間片
MOVR7,#1 ;延時等待
NOP;CALL DelayXus
SETBDQ ;準備接收
MOV R7,#1
NOP; CALL DelayXus
MOVC,DQ ;讀取數據
RRC A
MOVR7,#10;60 ;等待時間片結束
CALL DelayXus
DJNZ0,ReadNext
POP 0
RET
;**************************************
;向DS18B20寫1字節數據
;入口參數:ACC
;出口參數:無
;**************************************
DS18B20_WriteByte:
PUSH 0
MOV 0,#8 ;8位計數器
WriteNext:
CLRDQ ;開始時間片
MOVR7,#1 ;延時等待
NOP;CALL DelayXus
RRCA ;輸出數據
MOV DQ,C
MOVR7,#10;60 ;等待時間片結束
CALL DelayXus
SETBDQ ;準備送出下一位數據
MOV R7,#1
NOP; CALL DelayXus
DJNZ 0,WriteNext
POP 0
RET
END
|