|
AN #24 - How to increase resolution of DS1821 temperature sensor |
|
|
How to increase resolution of DS1821 temperature sensor
This application note was written by Dusko Djuricin.
It shows how to expand the resolution of the DS1821.
Dusko included the schematic in ASCII too.
'
=========================================================================================
'
' Program: DS1821HI.BAS
' Author: Dusko Djuricin
' E-mail: djdusko@eunet.yu
'
' This program demonstrates how to increase resolution of
DS1821 temperature sensor.
' According to Dallas Application Note 105, there is an
undocumented command for reading
' remain value in DS1821 counter, which is used in
standard application for rounding the
' readout (1 Celsius degree resolution). Using this
technique it is possible to achive
' 0.5 Celsius degree resolution and an real (not integer)
readout!
' Test bed for this program was 89S8252 with minimal
hardware, 2x16 LCD and DS1821 connected
' in the following way:
'
' |
' | ---------
' P1.1 +-----o----------------| 270E |-----------o +5V
' | | ---------
' | |
' | | ---------
' P1.0 +-----|---------o------| 4K7 |-----------o +5V
' | | | ---------
' | | |
' AT89S8252 | o o
' -------------- VDD DQ
'
' Third pin of DS1821 (GND pin) should be connected
directly to GND.
'
' =========================================================================================
'-----------------------[Subroutine
declarations]---------------------------------
Declare Sub Write_ds1821(addr As Byte , N As Byte)
Declare Sub Mode_toggle_ds1821
Declare Sub Write_stat_ds1821(n As Byte)
'------------------------[variable
declarations]---------------------------------
Dim N As Byte
Dim Addr As Byte
Dim Temp_w As Word
Dim Count_remain As Word
Dim Count_per_degree As Word
Dim T As Single
Dim T1 As Single
Dim Sign As String * 1
Dim Tc$ As String * 8
Dq Alias P1.0
Vdd Alias P1.1
'-------------------------[Beginning of
Code]------------------------------------
Config 1wire = Dq ' define 1WIRE pin
Cursor Off
Cls
Lcd " DS1821 in "
Lowerline
Lcd " high resolution"
Wait 2
Cls
Lcd " presented by"
Lowerline
Lcd "djdusko@eunet.yu"
Wait 3
For N = 1 To 16
Shiftlcd Right
Waitms 150
Next N
Cls
'-----[initialize DS1821]--------------
Mode_toggle_ds1821 ' put device into 1wire mode
Write_stat_ds1821 &H01 ' write in status register:
' oneshot measure (IMPORTANT!)
' active output low,
' power up in 1wire mode
'----------[main loop]------------------
Do
1wreset ' reset 1WIRE bus
1wwrite &HEE ' start
conversion (one shot)
!L_wait: ' now...
1wreset ' reset 1WIRE bus,
1wwrite &HAC ' read status register,
N = 1wread() ' and check,
mov a,{n} ' does conversion is finished...
rlc a ' if not,
jnc L_wait ' loop for a while
1wreset ' reset 1WIRE bus
1wwrite &HAA ' and read
N = 1wread() ' measured value
Sign = "" ' prepare sign variable
If N.7 = 1 Then ' if temperature is < 0
N = 256 - N ' convert it from 2nd complement
Sign = "-" ' and mark sign
End If ' (so far it was standard procedure).
1wreset ' reset 1WIRE bus
1wwrite &HA0 ' now read remaind part of DS1821 counter
Count_remain = 1wread(2) ' (it is 9 bit long!)
1wreset ' reset 1WIRE bus
1wwrite &H41 ' send LOAD COUNTER command which prepares
1wreset ' (reset 1WIRE bus)
1wwrite &HA0 ' for
reading the internal parameter
Count_per_degree = 1wread(2) ' needed for further calculations (9 bits)
Temp_w = Count_per_degree -
Count_remain ' (see details in DALLAS AN105)
T1 = Count_per_degree 'For T >= 0:
T = Temp_w / T1 ' Count_per_degree - Count_remain
T1 = N 'T = N - 1/2LSB + -------------------------------
If Sign = "" Then ' Count_per_degree
T1 = T1 - 0.5 '
T = T1 + T 'For T < 0:
Else ' Count_per_degree
- Count_remain
T1 = T1 + 0.5 'T = N + 1/2LSB - -------------------------------
T = T1 - T ' Count_per_degree
End If '
Tc$ = Fusing(t , ##.##) ' format the readout and
Locate 1 , 4 : Lcd "T=" ; Sign ; Tc$ ; "[C] " ' display measured temperature
Loop ' loop forever
'-------------------------------[DS1821
subroutines]-------------------------------
Sub Write_ds1821(addr As Byte , N As Byte)
1wreset ' reset 1WIRE bus
1wwrite Addr ' write command
1wwrite N ' and then data
End Sub
Sub Mode_toggle_ds1821
$asm
setb Dq ' rise DQ line
nop ' (settling time required by DS1821)
clr Vdd ' now drop VDD line and
mov a,#15 ' clock DQ line 16 times ...
L_clk: ' (this is the way how to put device
clr dq ' into 1WIRE mode, if it
was previously
nop ' programmed in thermostat
mode)
setb dq
djnz a,l_clk
nop
setb Vdd ' now rise VDD line (back to normal operation)
$end Asm
End Sub
Sub Write_stat_ds1821(n As Byte)
1wreset ' reset 1WIRE bus
1wwrite &H0C ' address status register (write command)
1wwrite N ' and write data
End Sub
'---------------------------------[End of
Code]----------------------------------
|