|
;這是關(guān)于DS18B20的讀寫程序,數(shù)據(jù)腳P3.4,晶振12MHZ ;溫度傳感器18B20匯編程序,采用器件默認(rèn)的12位轉(zhuǎn)化,最大轉(zhuǎn)化時(shí)間750微秒 ;可以將檢測到的溫度直接顯示到連接到AT89C2051的兩個(gè)數(shù)碼管上 ;顯示溫度00到99度,很準(zhǔn)確哦~~無需校正!
ORG 0000H
;單片機(jī)內(nèi)存分配申明! TEMPER_L EQU 29H ;用于保存讀出溫度的低8位 TEMPER_H EQU 28H ;用于保存讀出溫度的高8位 FLAG1 EQU 38H ;是否檢測到DS18B20標(biāo)志位 A_BIT EQU 20H ;數(shù)碼管個(gè)位數(shù)存放內(nèi)存位置 B_BIT EQU 21H ;數(shù)碼管十位數(shù)存放內(nèi)存位置
MAIN: LCALL GET_TEMPER ;調(diào)用讀溫度子程序
;顯示范圍00到99度,顯示精度為1度 ;因?yàn)?2位轉(zhuǎn)化時(shí)每一位的精度為0.0625度,我們不要求顯示小數(shù)所以可以拋棄29H的低4位 ;將28H中的低4位移入29H中的高4位,這樣獲得一個(gè)新字節(jié),這個(gè)字節(jié)就是實(shí)際測量獲得的溫度 ;這個(gè)轉(zhuǎn)化溫度的方法非常簡潔,無需乘于0.0625系數(shù)
MOV A,29H MOV C,40 ;將28H中的最低位移入C RRC A MOV C,41H RRC A MOV C,42H RRC A MOV C,43H RRC A MOV 29H,A
LCALL DISPLAY ;調(diào)用數(shù)碼管顯示子程序
AJMP MAIN
;這是DS18B20復(fù)位初始化子程序 INIT_1820: SETB P3.4 NOP CLR P3.4 ;主機(jī)發(fā)出延時(shí)537微秒的復(fù)位低脈沖 MOV R1,#3 TSR1: MOV R0,#107 DJNZ R0,$ DJNZ R1,TSR1 SETB P3.4 ;然后拉高數(shù)據(jù)線 NOP NOP NOP MOV R0,#25H TSR2: JNB P3.4,TSR3 ;等待DS18B20回應(yīng) DJNZ R0,TSR2 ;延時(shí) LJMP TSR4 TSR3: SETB FLAG1 ;置標(biāo)志位,表示DS1820存在 LJMP TSR5 TSR4: CLR FLAG1 ;清標(biāo)志位,表示DS1820不存在 LJMP TSR7
TSR5: MOV R0,#117 TSR6: DJNZ R0,TSR6 ;時(shí)序要求延時(shí)一段時(shí)間 TSR7: SETB P3.4 RET
;讀出轉(zhuǎn)換后的溫度值
GET_TEMPER: SETB P3.4 LCALL INIT_1820 ;先復(fù)位DS18B20 JB FLAG1,TSS2 RET ;判斷DS1820是否存在?若DS18B20不存在則返回 TSS2: MOV A,#0CCH ;跳過ROM匹配 LCALL WRITE_1820 MOV A,#44H ;發(fā)出溫度轉(zhuǎn)換命令 LCALL WRITE_1820
;這里通過調(diào)用顯示子程序?qū)崿F(xiàn)延時(shí)一段時(shí)間,等待AD轉(zhuǎn)換結(jié)束,12位的話750微秒
LCALL DISPLAY
LCALL INIT_1820 ;準(zhǔn)備讀溫度前先復(fù)位
MOV A,#0CCH ;跳過ROM匹配 LCALL WRITE_1820
MOV A,#0BEH ;發(fā)出讀溫度命令 LCALL WRITE_1820
LCALL READ_18200 ;將讀出的溫度數(shù)據(jù)保存到35H/36H
RET
;寫DS18B20的子程序(有具體的時(shí)序要求) WRITE_1820: MOV R2,#8 ;一共8位數(shù)據(jù) CLR C WR1: CLR P3.4 MOV R3,#6 DJNZ R3,$ RRC A MOV P3.4,C MOV R3,#23 DJNZ R3,$ SETB P3.4 NOP DJNZ R2,WR1 SETB P3.4 RET
;讀DS18B20的程序,從DS18B20中讀出兩個(gè)字節(jié)的溫度數(shù)據(jù) READ_18200: MOV R4,#2 ;將溫度高位和低位從DS18B20中讀出 MOV R1,#29H ;低位存入29H(TEMPER_L),高位存入28H(TEMPER_H) RE00: MOV R2,#8 ;數(shù)據(jù)一共有8位 RE01: CLR C SETB P3.4 NOP NOP CLR P3.4 NOP NOP NOP SETB P3.4
MOV R3,#9 RE10: DJNZ R3,RE10
MOV C,P3.4
MOV R3,#23 RE20: DJNZ R3,RE20
RRC A DJNZ R2,RE01 MOV @R1,A DEC R1 DJNZ R4,RE00 RET
;顯示子程序
DISPLAY: MOV A,29H ;將29H中的十六進(jìn)制數(shù)轉(zhuǎn)換成10進(jìn)制 MOV B,#10 ;10進(jìn)制/10=10進(jìn)制 DIV AB MOV B_BIT,A ;十位在a MOV A_BIT,B ;個(gè)位在b MOV DPTR,#NUMTAB ;指定查表啟始地址 MOV R0,#4 DPL1: MOV R1,#250 ;顯示1000次 DPLOP: MOV A,A_BIT ;取個(gè)位數(shù) MOVC A,@A+DPTR ;查個(gè)位數(shù)的7段代碼 MOV P1,A ;送出個(gè)位的7段代碼 CLR P3.7 ;開個(gè)位顯示 ACALL D1MS ;顯示1ms SETB P3.7 MOV A,B_BIT ;取十位數(shù) MOVC A,@A+DPTR ;查十位數(shù)的7段代碼 MOV P1,A ;送出十位的7段代碼 CLR P3.5 ;開十位顯示 ACALL D1MS ;顯示1ms SETB P3.5 DJNZ R1,DPLOP ;250次沒完循環(huán) DJNZ R0,DPL1 ;4個(gè)250次沒完循環(huán) RET
;1MS延時(shí)(按12MHZ算)
D1MS: MOV R7,#80 DJNZ R7,$ RET
;7段數(shù)碼管0~9數(shù)字的共陽顯示代碼
NUMTAB: DB 081H,0CFH,092H,086H,0CCH,0A4H,0A0H,08FH,080H,084H
END
|