Observatoire du Prieuré Gradignan

DS182O routines

 Accueil Remonter

 

Précédente
Suivante


I have developped these routines for the AlAudine NT switching supply application.

They incorporate subroutines for

  • detecting the presence of a DS1820 sensor,

 

  • reading from it with the maximum level of resolution available

 

  • displaying temperatures on a LCD display module in different units or scales:

  • Units: °C (Celsius) or °F (Farenheit)

 

  • Scales: Kelvin or Rankine

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 *
'********************************************************************


Accueil Remonter

Envoyez un courrier électronique à robert.soubie@free.fr pour toute question ou remarque concernant ce site Web.
copyright © 2001-2010 robert soubie ; dernière modification le 30 janvier 2010 00:08