?? temperature.asm
字號:
;----------------------------------
; 溫度檢測實例
;功能:從溫度傳感器DS18B20讀寫,然后將接收到的數據
; 直接顯示到兩個數碼管上
;-----------------------------------
; 這是關于DS18B20的讀寫程序,數據腳P2.2,晶振11.0592mhz
; 溫度傳感器18B20匯編程序,采用器件默認的12位轉化,最大轉化時間750微秒
; 可以將檢測到的溫度直接顯示到兩個數碼管上
; 顯示溫度00到99度
ORG 0000H
;----------------------------------
;單片機內存分配申明
;----------------------------------
TEMPER_L EQU 29H ; 用于保存讀出溫度的低8位
TEMPER_H EQU 28H ; 用于保存讀出溫度的高8位
FLAG1 EQU 38H ; 是否檢測到DS18B20標志位
A_BIT EQU 20h ; 數碼管個位數存放內存位置
B_BIT EQU 21h ; 數碼管十位數存放內存位置
;----------------------------------
;主循環,用來反復讀溫度和顯示溫度
;----------------------------------
MAIN:
LCALL GET_TEMPER ; 調用讀溫度子程序
; 進行溫度顯示,這里考慮用兩位數碼管來顯示溫度
; 顯示范圍00到99度,顯示精度為1度
; 因為12位轉化時每一位的精度為0.0625度,不要求顯示小數所以可以拋棄29H的低4位
; 將28H中的低4位移入29H中的高4位,這樣獲得一個新字節,這個字節就是實際測量獲得的溫度
MOV A,29H
MOV C,40H ; 將28H中的最低位移入C
RRC A
MOV C,41H
RRC A
MOV C,42H
RRC A
MOV C,43H
RRC A
MOV 29H,A
LCALL DISPLAY ; 調用數碼管顯示子程序
CPL P1.0
AJMP MAIN
;----------------------------------
; 這是DS18B20復位初始化子程序
;----------------------------------
INIT_1820:
SETB P2.2 ; 拉高2.2管腳的電平
NOP
CLR P2.2 ; 拉低2.2管腳的電平
; 主機發出延時537微秒的復位低脈沖
MOV R1,#3
TSR1:
MOV R0,#107
DJNZ R0,$ ; 當R0不等于0時,原地等待
DJNZ R1,TSR1 ; 當R1不等于0時,返回TSR1,用于延時
SETB P2.2 ; 然后拉高數據線,將18B20中的數據清零
NOP
NOP
NOP
MOV R0,#25H
TSR2:
JNB P2.2,TSR3 ; 等待DS18B20回應,有回應則跳到TSR3
DJNZ R0,TSR2 ; 如果等沒到37次,則繼續等待回應
LJMP TSR4 ; 跳轉到TSR4
TSR3:
SETB FLAG1 ; 置標志位,表示DS1820存在
LJMP TSR5 ; 跳轉到TSR5
TSR4:
CLR FLAG1 ; 清標志位,表示DS1820不存在
LJMP TSR7 ; 跳轉到TSR5
TSR5:
MOV R0,#117
TSR6:
DJNZ R0,TSR6 ; 時序要求延時一段時間
TSR7:
SETB P2.2 ; 拉高數據線
RET
;----------------------------------
; 讀出轉換后的溫度值
;----------------------------------
GET_TEMPER:
SETB P2.2 ; 拉高數據線
LCALL INIT_1820 ; 先復位DS18B20
JB FLAG1,TSS2 ; 如果檢測到18B20,則跳轉到TSS2
CLR P2.2
RET ; 判斷DS1820是否存在?若DS18B20不存在則返回
TSS2:
MOV A,#0CCH ; 跳過ROM匹配
LCALL WRITE_1820 ; 調用寫18B20指令,將累加器中的命令寫進18B20中
MOV A,#44H ; 發出溫度轉換命令
LCALL WRITE_1820 ; 調用寫18B20指令,將累加器中的命令寫進18B20中
; 這里通過調用顯示子程序實現延時一段時間,等待AD轉換結束,12位的話750微秒
LCALL DISPLAY
LCALL INIT_1820 ; 準備讀溫度前先復位
MOV A,#0CCH ; 跳過ROM匹配
LCALL WRITE_1820
MOV A,#0BEH ; 發出讀溫度命令
LCALL WRITE_1820
LCALL READ_18200 ; 將讀出的溫度數據保存到35H/36H
CLR P1.4
RET
;----------------------------------
;寫DS18B20的子程序(有具體的時序要求)
;----------------------------------
WRITE_1820:
MOV R2,#8 ; 一共8位數據
CLR C ; 清除進位標志位
WR1:
CLR P2.2 ; 拉低數據線60微秒以上后,將數據移位寫入18B20
MOV R3,#5
DJNZ R3,$ ; 等待60微秒以上,完成寫初始化,然后寫入數據,
RRC A ; 將累加器中的數據帶進位右移
MOV P2.2,C ; 將進位位寫進18B20后,等待15微秒以上
MOV R3,#21
DJNZ R3,$ ; 等待15微秒以上,完成一比特的寫操作
SETB P2.2 ; 拉高數據線,初始化寫
NOP
DJNZ R2,WR1 ; 如果一個字節沒寫完,繼續寫
SETB P2.2 ; 拉高數據線
RET
;----------------------------------
;讀DS18B20的子程序(有具體的時序要求)
;----------------------------------
READ_18200:
; 讀DS18B20的程序,從DS18B20中讀出兩個字節的溫度數據
MOV R4,#2 ; 將溫度高位和低位從DS18B20中讀出
MOV R1,#29H ; 低位存入29H(TEMPER_L),高位存入28H(TEMPER_H)
RE00:
MOV R2,#8 ; 數據一共有8位
RE01:
CLR C ; 清除進位標志位
SETB P2.2 ; 拉高數據線后,等待1微秒初始化讀
NOP
NOP
CLR P2.2 ; 拉低數據線后,保持1微秒以上使讀初始化有效
NOP
NOP
NOP
SETB P2.2 ; 拉高數據線后,開始讀操作
MOV R3,#8
DJNZ R3,RE10 ; 等待15微秒后,寫入數據正確
MOV C,P2.2 ; 將數據讀入累加器
MOV R3,#21
RE20:
DJNZ R3,RE20 ; 等待60微秒以上后,進行下一次讀操作
RRC A ; 將累加器帶進位右移
DJNZ R2,RE01 ; 如果沒讀滿一個字節,繼續讀取數據
MOV @R1,A ; 將累加器中的數據存儲進地址29H中
DEC R1
DJNZ R4,RE00 ; 繼續讀取高位
RET
;----------------------------------
;顯示子程序
;----------------------------------
DISPLAY:
MOV A,29H ; 將29H中的十六進制數轉換成10進制
MOV B,#10 ; 10進制/10=10進制
DIV AB
MOV B_BIT,A ; 十位在A
MOV A_BIT,B ; 個位在B
MOV DPTR,#NUMTAB ; 指定查表啟始地址
MOV R0,#4
DPL1:
MOV R1,#250 ; 顯示1000次
DPLOP:
MOV A,A_BIT ; 取個位數
MOVC A,@A+DPTR ; 查個位數的7段代碼
MOV P0,A ; 送出個位的7段代碼
CLR P2.7 ; 開個位顯示
ACALL D1MS ; 顯示1ms
SETB P2.7
MOV A,B_BIT ; 取十位數
MOVC A,@A+DPTR ; 查十位數的7段代碼
MOV P0,A ; 送出十位的7段代碼
CLR P2.6 ; 開十位顯示
ACALL D1MS ; 顯示1ms
SETB P2.6
DJNZ R1,DPLOP ; 未到100次循環,則繼續
DJNZ R0,DPL1 ; 未到4個100次循環,則繼續
RET
; 1MS延時
D1MS:
MOV R7,#80
DJNZ R7,$
RET
; 實驗板上的7段數碼管0~9數字的共陰顯示代碼
NUMTAB: DB 03FH,06H,5BH,4FH,66H,06DH,07DH,07H,07FH,06FH
END
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -