這時一個由匯編語言編寫的ds18b20測溫程序。
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
單片機源程序如下:
- TEMP_ZH EQU 24H ;實時溫度值存放單元,用來和報警值進行比較
- TEMPL EQU 25H ;低溫度值存放單元
- TEMPH EQU 26H ;高溫度值存放單元
- TEMP_TH EQU 27H ;高溫報警值存放單元
- TEMP_TL EQU 28H ;低溫報警值存放單元
- FLAG BIT 20H.0 ;DS18B20是否存在標記
- DQ BIT P1.7 ;DS18B20數據腳定義
- TEMPHC EQU 32H ;溫度轉換低8位緩沖區
- TEMPLC EQU 33H ;溫度轉換高8位緩沖區
- DISP_BUF EQU 34H ; DISP_BUF為顯示緩沖區小數位,DISP_BUF+1為顯示緩沖區個數位
- ;DISP_BUF+2為顯示緩沖區十位,DISP_BUF +3為顯示緩沖區百位
- DOT BIT P0.7 ;小數點控制
- ORG 0000H ;主程序入口地址
- AJMP MAIN ;轉主程序MAIN
- ORG 0030H ;主程序從0030H開始
- ;以下是主程序
- MAIN: MOV SP, #50H ;堆棧初始化
- MOV P0, #0FFH ;P0口置1
- START: LCALL GET_TEMP ;調用讀溫度子程序
- LCALL TEMP_PROC ;調溫度BCD處理子程序
- LCALL BCD_REFUR ;調BCD碼溫度值刷新子程序
- LCALL DISPLAY ;調用數碼管顯示子程序
- AJMP START ;跳轉到START
- ;以下是讀出轉換后的溫度值
- GET_TEMP: SETB DQ ;拉高數據線
- LCALL RESET_1820 ;先復位DS18B20(在驅動程序軟件包中)
- JB FLAG, GET_NEXT ;若FLAG=1說明DS18B20存在,跳轉到GET_NEXT
- AJMP GET_RET ;若FLAG=0,說明DS18B20不存在,跳轉到GET_RET返回
- GET_NEXT: MOV A,#0CCH ;跳過ROM匹配
- LCALL WRITE_1820 ;調寫DS18B20子程序(在驅動程序軟件包中)
- MOV A,#44H ;發出溫度轉換命令
- LCALL WRITE_1820 ;調寫DS18B20子程序(在驅動程序軟件包中)
- LCALL DISPLAY ;調用顯示子程序延時,等待A/D轉換結束,分辨率為12位時需延時750ms
- ;此語句也可以不加
- LCALL RESET_1820 ;準備讀溫度前先復位(在驅動程序軟件包中)
- MOV A,#0CCH ;跳過ROM匹配
- LCALL WRITE_1820 ;調寫DS18B20子程序(在驅動程序軟件包中)
- MOV A,#0BEH ;發出讀溫度命令
- LCALL WRITE_1820 ;調寫DS18B20子程序(在驅動程序軟件包中)
- LCALL READ_1820 ;調讀DS18B20子程序(在驅動程序軟件包中)
- GET_RET: RET
- ;以下是溫度BCD碼處理子程序
- ;以下是溫度BCD碼處理子程序
- TEMP_PROC: MOV A,TEMPH ;判溫度是否零下
- ANL A,#80H ;取出最高位
- JZ TC1 ;若A為0,說明溫度為零上,轉TC1
- CLR C ;若A為1,說明溫度為零下,C清0
- MOV A,TEMPL ;溫度值低位TEMPL送A
- CPL A ; TEMPL取反
- ADD A,#01H ; TEMPL取反加1
- MOV TEMPL,A ;取反加1后再送回TEMPL
- MOV A,TEMPH ; TEMPH送A
- CPL A ; TEMPH取反
- ADDC A,#00H ; TEMPH加上進位位
- MOV TEMPH,A ;A的值送回TEMPH
- SJMP TC2 ;跳轉到TC2
- TC1: MOV TEMPHC,#0AH ;將0AH送TEMPHC
- TC2: MOV A,TEMPHC ; TEMPHC送A
- SWAP A ;A高低半字節交換
- MOV TEMPHC,A ;交換后送TEMPHC
- MOV A,TEMPL ;溫度值低字節TEMPL送A
- ANL A,#0FH ;取出低4位的小數
- MOV DPTR,#DOTTAB ;小數表DOTTAB地址送DPTR
- MOVC A,@A+DPTR ;查出小數
- MOV TEMPLC,A ;小數部分送TEMPLC
- MOV A,TEMPL ; 溫度值低字節TEMPL送A
- ANL A,#0F0H ;取出高四位整位部分
- SWAP A ;高低半字節交換
- MOV TEMPL,A ;交換后送TEMPL
- MOV A,TEMPH ;溫度值高字節TEMPH送A
- ANL A,#0FH ;取出TEMPH低4位
- SWAP A ;高低半字節交換
- ORL A,TEMPL ;將TEMPH低4位與TEMPL高4位整數部分重新組合
- MOV TEMP_ZH,A ;將組合后的值送TEMP_ZH(實際溫度)
- LCALL HEX_BCD ;調十六進制轉BCD碼子程序
- MOV TEMPL,A ;轉換后A送TEMPL
- ANL A,#0F0H ;取高4位
- SWAP A ;高低4位交換
- ORL A,TEMPHC ;與TEMPHC進行或運算
- MOV TEMPHC,A ;送回TEMPHC
- MOV A,TEMPL ; TEMPL送A
- ANL A,#0FH ;取出低4位
- SWAP A ;高低4位交換
- ORL A,TEMPLC ;與TEMPLC進行或運算
- MOV TEMPLC,A ;送回TEMPLC
- MOV A,R4 ;R4送A
- JZ TC3 ;若A為0,退出
- ANL A,#0FH ;若不為0,取出低4位
- SWAP A ;高低4位交換
- MOV R4,A ;送R4
- MOV A,TEMPHC ;TEMPHC送A
- ANL A,#0FH ;取出低4位
- ORL A,R4 ;與R4進行或運算
- MOV TEMPHC,A ;送回TEMPHC
- TC3: RET
- ;以下是單字節十六進制轉BCD子程序
- HEX_BCD: MOV B,#100 ;B為100
- DIV AB ; A除以B
- MOV R7,A ; 百位數送R7
- MOV A,#10 ;A為10
- XCH A,B ;A、B值交換
- DIV AB ; A除以B
- SWAP A ;高低半字節交換
- ORL A,B ;或運算
- RET
- ;以下是小數部分碼表
- DOTTAB: DB 00H,00H,01H,01H,02H,03H,03H,04H
- DB 05H,05H,06H,06H,07H,08H,08H,09H
- ;以下是BCD 碼溫度值刷新子程序
- BCD_REFUR: MOV A,TEMPLC ;取低8位溫度值
- ANL A,#0FH ;取出低4位(小數部分)
- MOV DISP_BUF,A ;小數部分送顯示緩沖DISP_BUF
- MOV A,TEMPLC ;取低8位溫度值
- SWAP A ;高低4位交換
- ANL A,#0FH ;取A低4位,即取出TEMPLC的高4位(個位部分)
- MOV DISP_BUF+1,A ;個位部分送DISP_BUF+1
- MOV A,TEMPHC ;取高8位溫度值
- ANL A,#0FH ;取低4位(十位部分)
- MOV DISP_BUF+2,A ;十位部分送DISP_BUF+2
- MOV A,TEMPHC ;取高8位溫度值
- SWAP A ;送A
- ANL A,#0FH ;取出低4位,相當于取出TEMPHC的高4位(百位)
- MOV DISP_BUF+3,A ;百位送DISP_BUF+3
- MOV A,TEMPHC ; TEMPHC送A
- ANL A,#0F0H ;取出高4位
- CJNE A,#10H,BCD0 ;百位數是0?
- SJMP BCD_RET ;退出
- BCD0: MOV A, TEMPHC ; TEMPHC送A
- ANL A, #0FH ;取出低4位
- JNZ BCD_RET ; 十位數是0?
- MOV A,TEMPHC ; TEMPHC送A
- SWAP A ;高低4位交換
- ANL A,#0FH ;取出低4位
- MOV DISP_BUF+3,0AH ; 符號位不顯示
- MOV DISP_BUF+2,A ;十位數顯示符號
- BCD_RET: RET
-
- ;以下是顯示子程序
- DISPLAY: MOV DPTR,#TAB ; 指定查表啟始地址
- MOV R1,#250 ; 顯示250次
- DPLP: SETB DOT ;小數點位為高,不顯示小數點
- ;-----------------------------------------------------------------------------
- MOV A,DISP_BUF ; 取小位數
- MOVC A,@A+DPTR ; 查小位數的7段代碼
- MOV P0,A ; 送出小位的段碼
- SETB P2.3;CLR P2.3 ; 開小位顯示
- ACALL DELAY_1ms ; 顯示1ms,延時時間不可過長,否則會出現閃爍現象
- CLR P2.3 ;SETB P2.3 ;關小數位
- ;------------------------------------------------------------------------------
- MOV A,DISP_BUF+1 ;取個位數
- MOVC A,@A+DPTR ; 查個位數的7段代碼
- MOV P0,A ; 送出個位的段碼
- CLR DOT ;顯示小數點
- SETB P2.2;CLR P2.2 ;開個位顯示
- ACALL DELAY_1ms ; 顯示1ms
- CLR P2.2;SETB P2.2 ;關個位
- SETB DOT ;關小數點
- ;--------------------------------------------------------------------------
- MOV A,DISP_BUF+2 ;取十位數
- MOVC A,@A+DPTR ;查十位數的段碼
- MOV P0,A ; 送出十位的段碼
- SETB P2.1;CLR P2.1 ; 開十位顯示
- ACALL DELAY_1ms ; 顯示1ms
- CLR P2.1 ;SETB P2.1 ;關十位
- SETB DOT ;關小數點
- ;-------------------------------------------------------------------------------;
- MOV A,DISP_BUF+3 ; 取百位數
- MOVC A,@A+DPTR ; 查百位數的段碼
- MOV P0,A ; 送出百位的段碼
- SETB P2.0;CLR P2.0 ; 開百位顯示
- ACALL DELAY_1ms ; 顯示1ms
- CLR P2.0;SETB P2.0 ;關百位
- DJNZ R1,DPLP ; 250次沒完循環
- RET
- ;-------------------------------------------------------------------------------------
- ;以下是1ms延時子程序
- DELAY_1ms: MOV R7,#5
- LOOP2: MOV R6,#100
- LOOP1: DJNZ R6,LOOP1
- DJNZ R7,LOOP2
- RET
- ;以下是數碼管顯示代碼
- TAB: DB 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H ;0-9顯示碼
- DB 0FFH,0BFH ;"熄滅"、 "-"顯示碼
- ;以下是 DS18B20復位初始化子程序
- RESET_1820: SETB DQ
- NOP
- CLR DQ
- MOV R1,#3 ;主機發出延時500us的復位低脈沖
- DLY: MOV R0,#107
- DJNZ R0,$
- DJNZ R1,DLY
- SETB DQ ;拉高數據線
- NOP
- NOP
- NOP
- MOV R0,#25H
- RST2: JNB DQ , RST3 ;等待DS18B20回應
- DJNZ R0, RST2
- JMP RST4
- RST3: SETB FLAG ;置標志位,表示DS18B20存在
- JMP RST5
- RST4: CLR FLAG ;清標志位,表示DS18B20不存在
- JMP RST7
- RST5: MOV R0,#117
- RST6: DJNZ R0, RST6 ;時序要求延時一段時間
- RST7: SETB DQ
- RET
- ;以下是寫DS18B20子程序
- WRITE_1820: MOV R2,#8 ;共8位數據
- CLR C
- WR1: CLR DQ ;總線低位,開始寫入
- MOV R3,#6
- DJNZ R3,$ ;保持16微秒以上
- RRC A ;把字節DATA分成8個BIT環移給C
- MOV DQ, C ;寫入一個BIT
- MOV R3,#23
- DJNZ R3,$ ;等待
- SETB DQ ;重新釋放總線
- NOP
- DJNZ R2,WR1 ;寫入下一個BIT
- SETB DQ
- RET ;寫入子程序
- ;以下是讀DS18B20子程序(將溫度低位、高位、報警高位TH、報警低位TL從DS18B20中讀出)
- READ_1820: MOV R4,#4 ;讀取4字節
- MOV R1,#TEMPL ;存入TEMPL (25H)、TEMPLH(26H)、TEMP_TH (27H)、TEMP_TL(28H)
- READ0: MOV R2,#8 ;數據一共有8位
- READ1: CLR C
- SETB DQ
- NOP
- NOP
- CLR DQ ;讀前總線保持為低
- NOP
- NOP
- NOP
- SETB DQ ;開始讀總線釋放
- MOV R3,#9
- DJNZ R3,$ ;延時18微妙
- MOV C, DQ ;從總線讀到一個BIT
- MOV R3,#23 ;
- DJNZ R3,$ ;等待50us
- RRC A ;把讀得的位價值環移給A
- DJNZ R2,READ1 ;讀下一個BIT
- MOV @R1,A
- INC R1 ; R1內數據遞增
- DJNZ R4,READ0
- RET
- END
復制代碼
所有資料51hei提供下載:
18b20單支.rar
(41.51 KB, 下載次數: 31)
2018-10-16 11:04 上傳
點擊文件名下載附件
|