| |
I have developped these routines for the AlAudine NT switching
supply application.
They incorporate subroutines for
They could easily be modified to work on serial communications
using the SEROUT or HSEROUT instructions.
27 février 2004: routines have
been updated, and now include validity check by CRC computation.
They may be downloaded from this page
'********************************************************************
'* Name : DS1820_Routines.PBP *
'* Author : Robert Soubie <robert.soubie@free.fr> *
'* Notice : Copyright (c) 2003 robert soubie *
'* Date : 09/12/2003 *
'* Version : 1.0 *
'* Notes : Temperature is stored in hundredth of a degree C, *
'* : with an offset of 27400; this is the same value *
'* as (Kelvin*100) + 85; hence the range is from *
'* -273.15 °C to +381.4 °C, which should be sufficient *
'* for most purposes. If the Farenheit scale is used, *
'* then the maximum usable temperature is 195°F *
'* Four routines can be used to display the temperature *
'* in the following formats: *
'* - degrees Celsius *
'* - degrees Farenheit *
'* - Kelvin scale value *
'* - Rankine scale value *
'* These routines can be freely used in any context *
'********************************************************************
'********************************************************************
' Reusable routines *
'********************************************************************
'*******************************************************************************************
' Explanation of temperature scales and storage encoding; N/M = meaningless
temperature *
'*******************************************************************************************
' VAL | 0 84 85 25622 27400 *
' °C |-274,0 -273,16 -273,15 -17.78°C 0°C *
' K | N/M N/M 0 K 255,37 273,15 *
' °F | N/M N/M -459,67°F 0°F 32°F *
' R | N/M N/M 0 R 459,67R 491,67R *
' | |-------|----------|-----/........../---------|--------------|--------->
warmer *
' | | | | *
' | | | |--- Physical absolute zero temperature *
' | | |-------------- Meaningless temperature used to imply "sensor not found" *
' | |---------------------- Origin of stored and displayed temperature values *
'*******************************************************************************************
' These values have been carefully chose for accuracy of the storage and
conversion and
' the ability to display them. Do not modify.
ScaleOffset con 85
AbsZero CON 27315
DeltaC CON AbsZero _
+ ScaleOffset ' Offset for managing negative temperatures (to -273.15° Celsius
or 0 Kelvin)
DeltaF CON 45967 ' Offset for managing negative temperatures (to -459.67°
Farenheit or 0 Rankine)
Celsius con "C" '
Farenheit con "F" '
Kelvin con "K" '
Rankine con "R" '
DegreeSign con $DF ' "°" sign
LeadingSpaces var bIT
' Comment out one of these:
DecimalSign CON "," ' France
' DecimalSign CON "." ' Rest of the world
Temperature var word ' Temperature read from sensor
TEMPE1 var byte ' Temporary variable
TEMPE2 var byte ' Temporary variable
' use for displaying values
SIGN VAR BYTE ' Sign character
DECI var word ' Decimal part of number
FRAC var word ' Fractionnal part
ValueTemp VAR WORD ' Temperature value to display
SValueTemp VAR WORD ' Temperature value to display
DS1820Found var byte ' Sensor presence flag
DQ VAR PORTB.1 ' Alias DS18S20 data pin
DQ_DIR VAR TRISB.1 ' Alias DS18S20 data direction pin
' Uncomment those if they are not defined yet
' FALSE con 0
' TRUE con 1
Goto OverDS1820Routines
' Check for sensor presence
CheckForDS1820:
DS1820Found = TRUE
LOW DQ ' INIT pin DATA
PAUSEUS 500 ' Wait > 480us
DQ_DIR = 1 ' Port C.0 dans le sens IN
PAUSEUS 100 ' Wait > 60us
IF DQ = 1 THEN DS1820Found = FALSE ' Test for sensor presence
return
' Return temperature from sensor; if "0" then sensor was not detected
DS1820Read:
LOW DQ ' Pin data
PAUSEUS 500 ' Wait > 480us
DQ_DIR = 1 ' Pin direction
PAUSEUS 100 ' Wait > 60us
IF DQ = 1 THEN
DS1820Found = FALSE
Temperature = 0 ' Not a meaningful temperature, implies "no sensor"
RETURN
ENDIF
PAUSEUS 400 ' Wait for end of presence pulse
' Launch measurement
OWOUT DQ, 1, [$CC, $44] ' Start Temperature conversion
DS1820LooP:
OWIN DQ, 4, [TEMPE1]
IF TEMPE1 = 0 THEN DS1820LOOP ' Loop while conversion takes place
OWOUT DQ, 1, [$CC, $BE] ' Read temperature
OWIN DQ, 0, [Temperature.LOWBYTE, Temperature.HIGHBYTE, Skip 4, TEMPE1, TEMPE2]
' Express temperature in Kelvin * 100
Temperature = (((Temperature >> 1) * 100) - 25) + (((TEMPE2 - TEMPE1) * 100) /
TEMPE2) + DeltaC
' To check remarkable values, comment out one of these
' Temperature = 85 ' Absolute zero (0 Kelvin, 0 Rankine, -273,15°C, -459,67°F)
' Temperature = 25622 ' Zero Farenheit (0°F)
' Temperature = 27400 ' Zero (0°C) Ice
' Temperature = 37400 ' Zero (0°C) Boiling Water
' Temperature = $FFFF ' Maximum temperature that can be represented
if Temperature < 85 then Temperature = 85 ' Meaningless temperature, don't even
try to display
RETURN
DisplayCelsius: ' Display temperature in ° Celsius
SValueTemp = ValueTemp ' This routine preserves ValueTemp
FRAC = ValueTemp - DeltaC
IF ValueTemp >= DeltaC Then
SIGN = "+"
else
SIGN = "-"
FRAC = 1 + ~FRAC
ENDIF
goto DisplayTemperatureValue
DisplayFarenheit: ' Display temperature in ° Farenheit
SValueTemp = ValueTemp ' This routine preserves ValueTemp
' Express Temperature in Rankine (same origin as Kelvin, but different scale
factor):
ValueTemp = ValueTemp - 85 ' Kelvin * 100
ValueTemp = VAlueTemp * 9
ValueTemp = div32 5
FRAC = ValueTemp - DeltaF
IF ValueTemp >= Deltaf Then
SIGN = "+"
else
SIGN = "-"
FRAC = 1 + ~FRAC
ENDIF
' The rest of the logic is the same for Celsius and Farenheit...
DisplayTemperatureValue:
DECI = FRAC / 100
if LeadingSpaces then
' if DECI < 100 then lcdout " "
if Deci < 10 then lcdout " "
endif
LCDOUT SIGN
if DECI < 10 then
LCDOUT dec1 DECI
else
if deci < 100 then
lcdout DEC2 deci
else
lcdout dec3 DECI
endif
endif
LCDOUT DecimalSign
LCDOUT dec1 ((FRAC + 5) / 10)
ValueTemp = SValueTemp
return
DisplayKelvin: ' Display temperature in Kelvin
SValueTemp = ValueTemp ' This routine preserves ValueTemp
Valuetemp = VAlueTemp - 85
' no "degree" sign, Kelvin is a unitless scale
LCDOUT DEC3 (ValueTemp / 100), DecimalSign, DEC1 ((ValueTemp + 5) / 10)
ValueTemp = SValueTemp ' Display temperature in ° Celsius
RETURN
DisplayRankine ' This routine preserves ValueTemp
SValueTemp = ValueTemp ' Display temperature in Rankine
' no "degree" sign, Rankine is a unitless scale
ValueTemp = VAlueTemp - 85
ValueTemp = ValueTemp * 9
ValueTemp = div32 5
LCDOUT DEC3 (ValueTemp / 100), DecimalSign, DEC1 ((ValueTemp + 5) / 10)
ValueTemp = SValueTemp
RETURN
DisplayCelsiusSuffix:
lcdout DegreeSign, Celsius ' Display "°C"
return
DisplayFarenheitSuffix:
lcdout DegreeSign, Farenheit ' Display "°F"
return
DisplayKelvinSuffix:
lcdout Kelvin ' Display "K" for the Kelvin scale
return
DisplayRankineSuffix:
lcdout Rankine ' Display "R" for the Rankine scale
return
OverDS1820Routines:
'********************************************************************
' End of reusable routines *
'********************************************************************
|