1、DS18B20封裝
單總線DQ,內部9個字節的寄存器和64 bit的ROM(包含唯一標識ID),暫存寄存器包含了轉換溫度、報警溫度上下限。
空閑狀態下,總線以上拉形式保持高電平。
數據傳輸從低位(LSB)開始。
2、18B20復位時序
(1)復位:控制器(單片機)拉低總線480-950μs,然后釋放總線(拉高)。此時,單片機引腳需設置為輸出。
(2)控制器釋放總線后60-240μs,18B20拉低總線,表示應答。然后拉高釋放總線。
(3)在第二步18B20拉低總線時,控制器檢測總線狀態,如果是低電平,則可判定復位成功。此時,單片機引腳需設置為輸入。這里可以加一個超時檢測,以防超過240μs后,仍未收到復位應答。
(4)檢測到復位應答信號后,設置單片機引腳為輸出,拉高總線至少1μs,釋放總線。
3、向18B20寫一個字節的數據
(1)單片機引腳設置為輸出,拉低總線12μs。
(2)從最低位開始發送,根據最低位的值,設置引腳為低或高,延時40μs。
(3)單片機拉高總線,保持2μs左右。
(4)對發送字節數據進行邏輯右移一位,回到第(1)步,直到8位數據都發送完成。
4、從18B20讀取一個字節的數據
(1)每次讀取新的位時,先將讀取數據的變量邏輯右移一位。
(2)單片機引腳設置為輸出,拉低總線,保持12μs左右,再拉高總線,釋放,加幾個NOP指令延時即可。
(3)單片機引腳設置為輸入,加幾個NOP指令延時。
(4)檢測引腳狀態,收到第一位數據(第一次為最低位)。
(5)讀取一位數據后,延時40μs,將單片機引腳設置為輸出,拉高總線,延遲2μs以上。
(6)回到第(1)步,讀取下一位數據,直到8位數據讀取完成。
5、一個完整的溫度轉換流程
(1)復位(初始化)
(2)發送ROM命令
(3)發送寄存器命令
(4)數據傳輸
單個18B20連接時,可以在復位后,發送0xCC,調過ROM命令。???
寄存器命令0x44為溫度轉換命令,發送后,等待750ms以上(12位精度),才可進行數據讀取。
寄存器命令0xBE為讀取寄存器數據的命令(9個寄存器),大部分情況下,只需要讀取開始的兩個字節數據(溫度轉換結果),當讀取兩個字節后,可以再次復位18B20,以結束后續無關數據的讀取。
實際代碼時序:? 復位,發送0xCC,發送0x44,延時800ms; 復位,發送0xCC,發送0xBE,調用讀字節函數,保存低字節數據,調用讀字節函數,保存高字節數據。
6、關于溫度轉換數據的處理
(1)數據一共16bit,高5個bit為符號位,如果溫度值為正數,則高5位全0,溫度值為負數,則高5位全1。
(2)最低4個bit為溫度值的小數部分,中間的7個bit為溫度值的整數部分。
(3)小數位和溫度值的轉換過程:將低4位乘以0.0625即為溫度的小數位。 如低4位為0011,則小數部分為 3x0.0625=0.1875。程序中可以預先將小數位的值算出來,取合適的精度,用查表(00-FF,16個數值)的方式來得到小數位。
7、代碼參考,溫度讀取后的數據處理是為了在數碼管上顯示,分離出符號位、整數位和小數位(小數點后兩位精度):
INCLUDE 'derivative.inc' ; 這一句必須加,否則會報 value is truncated to one byte錯誤
? ? ? ? ; PJ1->DQ(18B20)
? ? ? ? XDEF? ? init_18b20,convert_18b20
? ? ? ? XREF? ? DS18B20_RST,r_data_H,r_data_L,r_buff,shuma_data,shuma_table,shuma_point_table,float_table
init_18b20:
? ? ? ? ? ? ? PSHB? ? ? ? ? ? ? ? ? ? ; 每個函數里面都包含一對入棧和出棧指令,以防破壞外部操作使用 B/X/Y寄存器; A寄存器自動入棧
? ? ? ? ? ? ? PSHX
? ? ? ? ? ? ? PSHY
? ? ? ? ? ? ? BSET? ? DDRJ,mDDRJ_DDRJ1? ? ? ; DJ1? OUTPUT輸出模式
? ? ? ? ? ? ? BCLR? ? PTJ,mPTJ_PTJ1? ? ? ? ; DJ1 -> 0
? ? ? ? ? ? ? LDAA? ? #$C7
? ? ? ? ? ? ? LDX? ? #$77
? ? ? ? ? ? ? CALL? ? delay_n_us? ? ? ? ? ? ; 延時 600μs (實際延時略大于600)
? ? ? ? ? ? ? BSET? ? PTJ,mPTJ_PTJ1? ? ? ? ; DJ1 -> 1
? ? ? ? ? ? ? LDAA? ? #$C7
? ? ? ? ? ? ? LDX? ? #$B
? ? ? ? ? ? ? CALL? ? delay_n_us? ? ? ? ? ? ; 延時60μs
? ? ? ? ? ? ? BCLR? ? DDRJ,mDDRJ_DDRJ1? ? ? ; DJ1? INPUT輸入模式
? ? ? ? ? ? ? LDX? ? #2000? ? ? ? ? ? ? ? ; 設置應答超時,以防進入死循環
? ? ? ? ? ? ? time_out:
? ? ? ? ? ? ? ? ? ? ? ? ? DEX
? ? ? ? ? ? ? ? ? ? ? ? ? CPX? ? #0
? ? ? ? ? ? ? ? ? ? ? ? ? BEQ? ? time_out_err
? ? ? ? ? ? ? ? ? ? ? ? ? BRSET? PTJ,mPTJ_PTJ1,time_out? ? ? ? ? ; 使用PTJ, 勿使用PTIJ
? ? ? ? ? ? ? ? ? ? ? ? ? LDAA? ? #1? ? ? ? ? ? ; 正常檢測到應答信號,返回1,復位成功
? ? ? ? ? ? ? ? ? ? ? ? ? STAA? ? DS18B20_RST
? ? ? ? ? ? ? ? ? ? ? ? ? BSET? ? DDRJ,mDDRJ_DDRJ1? ? ? ; DJ1? OUTPUT輸出模式? ? 檢測到復位應答后,單片機將總線拉高,保持1μs
? ? ? ? ? ? ? ? ? ? ? ? ? BSET? ? PTJ,mPTJ_PTJ1? ? ? ? ; DJ1 -> 0
? ? ? ? ? ? ? ? ? ? ? ? ? NOP
? ? ? ? ? ? ? ? ? ? ? ? ? LDAA? ? #$13
? ? ? ? ? ? ? ? ? ? ? ? ? LDX? ? #$1
? ? ? ? ? ? ? ? ? ? ? ? ? CALL? ? delay_n_us? ? ? ? ? ; 延時1μs
? ? ? ? ? ? ? ? ? ? ? ? ? PULY
? ? ? ? ? ? ? ? ? ? ? ? ? PULX
? ? ? ? ? ? ? ? ? ? ? ? ? PULB
? ? ? ? ? ? ? ? ? ? ? ? ? RTC
? ? ? ? ? ? ? time_out_err:? ? ? ? ? ? ? ;超時返回0
? ? ? ? ? ? ? ? ? ? ? ? ? LDAA? ? #0
? ? ? ? ? ? ? ? ? ? ? ? ? STAA? ? DS18B20_RST
? ? ? ? ? ? ? ? ? ? ? ? ? PULY
? ? ? ? ? ? ? ? ? ? ? ? ? PULX
? ? ? ? ? ? ? ? ? ? ? ? ? PULB
? ? ? ? ? ? ? ? ? ? ? ? ? RTC
convert_18b20:
? ? ? ? ? ? ? PSHB
? ? ? ? ? ? ? PSHX
? ? ? ? ? ? ? PSHY
? ? ? ? ? ? ? CALL? ? init_18b20
? ? ? ? ? ? ? LDAB? ? #$CC
? ? ? ? ? ? ? CALL? ? w_18b20? ? ? ? ? ? ? ? ? ? ? ? ?
? ? ? ? ? ? ? LDAB? ? #$44
? ? ? ? ? ? ? CALL? ? w_18b20
? ? ? ? ? ? ? LDY? ? #2
delay_800ms:? LDAA? ? #$F9
? ? ? ? ? ? ? LDX? ? #$F9FF
? ? ? ? ? ? ? CALL? ? delay_n_us
? ? ? ? ? ? ? DECY
? ? ? ? ? ? ? CPY? ? #0
? ? ? ? ? ? ? BNE? ? delay_800ms
? ? ? ? ? ? ? CALL? ? init_18b20
? ? ? ? ? ? ? LDAB? ? #$CC
? ? ? ? ? ? ? CALL? ? w_18b20
? ? ? ? ? ? ? LDAB? ? #$BE
? ? ? ? ? ? ? CALL? ? w_18b20
? ? ? ? ? ? ? CALL? ? r_18b20
? ? ? ? ? ? ? MOVB? ? r_buff,r_data_L
? ? ? ? ? ? ? CALL? ? r_18b20
? ? ? ? ? ? ? MOVB? ? r_buff,r_data_H
? ? ? ? ? ? ? CALL? ? init_18b20? ? ? ? ; BE命令會連續返回所有9個字節,這里復位18b20可以中斷后面的 數據返回。否則18b20會出錯。
; 處理數據,賦值給數碼管相關變量
data_pro:
? ? ? ? ? ? ? LDY? ? #shuma_data
? ? ? ? ? ? ? LDAA? ? r_data_H
? ? ? ? ? ? ? ANDA? ? #$F0
? ? ? ? ? ? ? CMPA? ? #$F0
? ? ? ? ? ? ? BNE? ? pos_data
? ? ? ? ? ? ? MOVB? ? #$BF,1,Y+? ? ; negative data
pos_data:? ? MOVB? ? #$FF,1,Y+
? ? ? ? ? ? ? LDAA? ? r_data_H
? ? ? ? ? ? ? LDAB? ? r_data_L
? ? ? ? ? ? ? ANDA? ? #$07
? ? ? ? ? ? ? LDX? ? #4? ? ? ? ? ? ? ; 左移 4位, 計算整數位
lsr_4:? ? ? ? LSRD
? ? ? ? ? ? ? DECX
? ? ? ? ? ? ? CPX? ? #0
? ? ? ? ? ? ? BNE? ? lsr_4?
? ? ? ? ? ? ? LDY? ? #$0000? ? ? ? ? ; 計算百位
? ? ? ? ? ? ? LDX? ? #100
? ? ? ? ? ? ? EDIV
? ? ? ? ? ? ? XGDX? ? ? ? ? ? ? ? ? ? ; D 和 X 交換, 保存余數 D到X中
? ? ? ? ? ? ? XGDY? ? ? ? ? ? ? ? ? ? ; 將商保存在D中, 實際用到B
? ? ? ? ? ? ? LDY? ? #shuma_table? ? ; 基址
? ? ? ? ? ? ? ABY? ? ? ? ? ? ? ? ? ? ; 加上B中的 偏移量
? ? ? ? ? ? ? XGDX? ? ? ? ? ? ? ? ? ? ; 回恢復余數到 D
? ? ? ? ? ? ? LDX? ? #shuma_data
? ? ? ? ? ? ? MOVB? ? Y,1,+X
? ? ? ? ? ? ? LDY? ? #$0000? ? ? ? ? ? ; 計算十位
? ? ? ? ? ? ? LDX? ? #10
? ? ? ? ? ? ? EDIV? ?
? ? ? ? ? ? ? XGDX? ? ? ? ? ? ? ? ? ? ; D 和 X 交換, 保存余數 D到X中
? ? ? ? ? ? ? XGDY? ? ? ? ? ? ? ? ? ? ; 將商保存在D中, 實際用到B
? ? ? ? ? ? ? LDY? ? #shuma_table? ? ; 基址
? ? ? ? ? ? ? ABY? ? ? ? ? ? ? ? ? ? ; 加上B中的 偏移量
? ? ? ? ? ? ? XGDX? ? ? ? ? ? ? ? ? ? ; 恢復余數到 D
? ? ? ? ? ? ? LDX? ? #shuma_data
? ? ? ? ? ? ? MOVB? ? Y,2,+X
? ? ? ? ? ? ? LDY? ? #shuma_point_table? ? ;? 表基址? ? 個位
? ? ? ? ? ? ? ABY? ? ? ? ? ? ? ? ? ? ? ? ? ; 加上B中的值 ,偏移量
? ? ? ? ? ? ? LDX? ? #shuma_data
? ? ? ? ? ? ? MOVB? ? Y,3,+X
; 小數位 計算? ? ? ? ? ? ?
? ? ? ? ? ? ? LDAB? ? r_data_L? ? ? ? ? ; 計算小數位? , 先查表出小數位的十進制表示
? ? ? ? ? ? ? ANDB? ? #$0F? ? ? ? ? ? ? ; 屏蔽高4位
? ? ? ? ? ? ? LDY? ? #float_table
? ? ? ? ? ? ? ABY
? ? ? ? ? ? ? MOVB? ? Y,r_data_L
? ? ? ? ? ? ? LDAB? ? r_data_L
? ? ? ? ? ? ? LDY? ? #$0000
? ? ? ? ? ? ? LDX? ? #10
? ? ? ? ? ? ? EDIV
? ? ? ? ? ? ? XGDX? ? ? ? ? ? ? ? ? ? ; D 和 X 交換, 保存余數 D到X中
? ? ? ? ? ? ? XGDY? ? ? ? ? ? ? ? ? ? ; 將商保存在D中, 實際用到B
? ? ? ? ? ? ? LDY? ? #shuma_table? ? ; 基址
? ? ? ? ? ? ? ABY? ? ? ? ? ? ? ? ? ? ; 加上B中的 偏移量
? ? ? ? ? ? ? XGDX? ? ? ? ? ? ? ? ? ? ; 恢復余數到 D
? ? ? ? ? ? ? LDX? ? #shuma_data
? ? ? ? ? ? ? MOVB? ? Y,4,+X
? ? ? ? ? ? ? LDY? ? #shuma_table? ? ;? 表基址? ? 個位
? ? ? ? ? ? ? ABY? ? ? ? ? ? ? ? ? ? ; 加上B中的值 ,偏移量
? ? ? ? ? ? ? LDX? ? #shuma_data
? ? ? ? ? ? ? MOVB? ? Y,5,+X
? ? ? ? ? ? ? PULY
? ? ? ? ? ? ? PULX
? ? ? ? ? ? ? PULB
? ? ? ? ? ? ? RTC? ? ? ? ?
; Write a byte to 18b20 ,入口參數? 需要寫的數據 存放到 B 寄存器
w_18b20:?
? ? ? ? ? ? ? PSHB
? ? ? ? ? ? ? PSHX
? ? ? ? ? ? ? PSHY
? ? ? ? ? ? ? LDY? ? #8
? ? ? ? ? ? ? BSET? ? DDRJ,mDDRJ_DDRJ1
w_start:? ? ? BCLR? ? PTJ,mPTJ_PTJ1? ? ? ? ; 輸出0
? ? ? ? ? ? ? LDAA? ? #$17
? ? ? ? ? ? ? LDX? ? #$13
? ? ? ? ? ? ? CALL? ? delay_n_us? ? ? ? ? ? ; 延時12μs
? ? ? ? ? ? ? TBA
? ? ? ? ? ? ? ANDA? ? #$01
? ? ? ? ? ? ? BEQ? ? w0
w1:? ? ? ? ? BSET? ? PTJ,mPTJ_PTJ1? ? ? ? ; 寫 1
? ? ? ? ? ? ? LDAA? ? #$C7
? ? ? ? ? ? ? LDX? ? #$7
? ? ? ? ? ? ? CALL? ? delay_n_us? ? ? ? ? ? ; 延時40μs
? ? ? ? ? ? ? BSET? ? PTJ,mPTJ_PTJ1
? ? ? ? ? ? ? LSRB?
? ? ? ? ? ? ? LDAA? ? #$13
? ? ? ? ? ? ? LDX? ? #$3
? ? ? ? ? ? ? CALL? ? delay_n_us? ? ? ? ? ; 延時2μs
? ? ? ? ? ? ? DECY
? ? ? ? ? ? ? CPY? ? #0
? ? ? ? ? ? ? BNE? ? w_start
? ? ? ? ? ? ? PULY
? ? ? ? ? ? ? PULX
? ? ? ? ? ? ? PULB
? ? ? ? ? ? ? RTC
? ? ? ? ? ? ? w0:? BCLR? ? PTJ,mPTJ_PTJ1? ; 寫 0
? ? ? ? ? ? ? ? ? ? LDAA? ? #$C7
? ? ? ? ? ? ? ? ? ? LDX? ? #$7
? ? ? ? ? ? ? ? ? ? CALL? ? delay_n_us? ? ? ? ? ? ; 延時40μs
? ? ? ? ? ? ? ? ? ? BSET? ? PTJ,mPTJ_PTJ1
? ? ? ? ? ? ? ? ? ? LSRB
? ? ? ? ? ? ? ? ? ? LDAA? ? #$13
? ? ? ? ? ? ? ? ? ? LDX? ? #$3
? ? ? ? ? ? ? ? ? ? CALL? ? delay_n_us? ? ? ? ? ; 延時2us
? ? ? ? ? ? ? ? ? ? DECY
? ? ? ? ? ? ? ? ? ? CPY? ? #0
? ? ? ? ? ? ? ? ? ? BNE? ? w_start
? ? ? ? ? ? ? ? ? ? PULY
? ? ? ? ? ? ? ? ? ? PULX
? ? ? ? ? ? ? ? ? ? PULB
? ? ? ? ? ? ? ? ? ? RTC
; Read a byte from 18b20? ,返回的數據保存在 r_buff 內,返回數據不要保存在寄存器A/B/X/Y中,因為有出棧操作!
r_18b20:
? ? ? ? ? ? PSHB
? ? ? ? ? ? PSHX
? ? ? ? ? ? PSHY
? ? ? ? ? ? LDAB? ? #$00
? ? ? ? ? ? LDY? ? #8
r_start:? ? LSRB? ?
? ? ? ? ? ? BSET? ? DDRJ,mDDRJ_DDRJ1
? ? ? ? ? ? BCLR? ? PTJ,mPTJ_PTJ1? ? ? ; 輸出0
? ? ? ? ? ? LDAA? ? #$17
? ? ? ? ? ? LDX? ? #$13
? ? ? ? ? ? CALL? ? delay_n_us? ? ? ? ; 延遲12μs
? ? ? ? ? ? BSET? ? PTJ,mPTJ_PTJ1? ? ; 釋放總線
? ? ? ? ? ? NOP
? ? ? ? ? ? NOP
? ? ? ? ? ? BCLR? ? DDRJ,mDDRJ_DDRJ1? ;設置輸入
? ? ? ? ? ? NOP
? ? ? ? ? ? NOP
? ? ? ? ? ? NOP
? ? ? ? ? ? BRCLR? PTJ,mPTJ_PTJ1,r0? ; 不能使用PTIJ寄存器? ? ,在12μs處 采樣
r1:? ? ? ? ORAB? ? #$80
? ? ? ? ? ? LDAA? ? #$C7
? ? ? ? ? ? LDX? ? #$7
? ? ? ? ? ? CALL? ? delay_n_us? ? ? ; 延遲40μs
? ? ? ? ? ? BSET? ? DDRJ,mDDRJ_DDRJ1
? ? ? ? ? ? BSET? ? PTJ,mPTJ_PTJ1
? ? ? ? ? ? LDAA? ? #$0F
? ? ? ? ? ? LDX? ? #$13
? ? ? ? ? ? CALL? ? delay_n_us? ? ? ? ; 延遲8μs
? ? ? ? ? ? DECY
? ? ? ? ? ? CPY? ? #0
? ? ? ? ? ? BNE? ? r_start
? ? ? ? ? ? STAB? ? r_buff
? ? ? ? ? ? PULY
? ? ? ? ? ? PULX
? ? ? ? ? ? PULB
? ? ? ? ? ? RTC
? ? ? ? ? ? r0:? ? ORAB? ? #$00
? ? ? ? ? ? ? ? ? ? LDAA? ? #$C7
? ? ? ? ? ? ? ? ? ? LDX? ? #$7
? ? ? ? ? ? ? ? ? ? CALL? ? delay_n_us? ? ? ; 延遲40μs
? ? ? ? ? ? ? ? ? ? BSET? ? DDRJ,mDDRJ_DDRJ1
? ? ? ? ? ? ? ? ? ? BSET? ? PTJ,mPTJ_PTJ1
? ? ? ? ? ? ? ? ? ? LDAA? ? #$0F
? ? ? ? ? ? ? ? ? ? LDX? ? #$13
? ? ? ? ? ? ? ? ? ? CALL? ? delay_n_us? ? ? ? ; 延遲8μs
? ? ? ? ? ? ? ? ? ? DECY
? ? ? ? ? ? ? ? ? ? CPY? ? #0
? ? ? ? ? ? ? ? ? ? BNE? ? r_start
? ? ? ? ? ? ? ? ? ? STAB? ? r_buff
? ? ? ? ? ? ? ? ? ? PULY
? ? ? ? ? ? ? ? ? ? PULX
? ? ? ? ? ? ? ? ? ? PULB
? ? ? ? ? ? ? ? ? ? RTC
; 使用PIT的通道0,入口參數? 微時基參數放在 A,? PIT加載寄存器值放在 X? ?
; 除去前面的設置指令耗時, PIT延時= (A+1)*(X+1)*0.025? μs
delay_n_us:
? ? ? ? ? ? ? PSHB
? ? ? ? ? ? ? PSHX
? ? ? ? ? ? ? PSHY
? ? ? ? ? ? ? MOVB? ? #$00,PITINTE? ? ? ? ; 關PIT中斷
? ? ? ? ? ? ? MOVB? ? #$00,PITMUX? ? ? ? ; 選擇微時基0
? ? ? ? ? ? ? STAA? ? PITMTLD0? ? ? ? ? ? ; 設置微時基值
? ? ? ? ? ? ? XGDX? ? ? ? ? ? ? ? ? ? ? ? ; 交換D/X寄存器值,將PIT計數值放到D中
? ? ? ? ? ? ? STD? ? PITLD0? ? ? ? ? ? ? ; 設置PIT加載寄存器
? ? ? ? ? ? ? MOVB? ? #$81,PITCFLMT
? ? ? ? ? ? ? MOVB? ? #$01,PITCE? ? ? ? ? ; 啟動計數
? ? ? ? ? ? ? BRCLR? PITTF,mPITTF_PTF0,* ; 查詢方式,檢查是否計數溢出
? ? ? ? ? ? ? MOVB? ? #$01,PITTF? ? ? ? ? ; 清除TF標志位
? ? ? ? ? ? ? MOVB? ? #$00,PITCE
? ? ? ? ? ? ? MOVB? ? #$00,PITCFLMT? ? ? ; 關PIT
? ? ? ? ? ? ? PULY
? ? ? ? ? ? ? PULX
? ? ? ? ? ? ? PULB
? ? ? ? ? ? ? RTC