Temperature = (((Temperature >> 1) * 100) - 25) + (((Count_Per_C - Count_Remain) * 100) / Count_Per_C)
Temperature >> 1
Ovime se vrsi pomeranje (siftovanje) promenljive Temperature u desno za jedno binarno mesto tako da 21 postaje 20 .. i tako redom. Time je dobijena celobrojna vrednost temperature.
Count_Per_C - Count_Remain
sluzi da se dobije decimalni deo temperature sa vecom rezolucijom od same rezolucije DS1820 senzora (ja vise volim DS18B20 posto ima vecu rezoluciju - programabilno 9, 10, 11 ili 12 bita)
Evo ti i jedan slican/malo drugaciji program sa 2 komada DS18B20
'* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
'* Universal thermostat -25/+75 C. by R.T.G. van Steenis *
'* Digital thermostat (080090-11) from Elektor july_august 2008 *
'* Compiler : PicBasic Pro 2.44 *
'* B0 = Mode switch in (In) A0 = LCD Enable (Out) *
'* B1 = + switch in (In) A1 = LCD RS (Out) *
'* B2 = - switch in (In) A2 = "Warm" Output (Out) *
'* B3 = Not connected (Out) A3 = "Cold" Output (Out) *
'* B4 = LCD Bit 4 (Out) A4 = DQ DS1820 (In) *
'* B5 = LCD Bit 5 (Out) *
'* B6 = LCD Bit 6 (Out) *
'* B7 = LCD Bit 7 (Out *
'* *
'* modify by Niculescu Dan *
'* *
'* DUAL THERMO 2xDS18B20 ; PIC 16F628A ; LCD 2x16 *
'* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
TRISA= %11011111 ' RA5=Outputs Rest=Input
TRISB= %00000000 ' RB0..RB7=Outputs
CMCON=7 ' Disable comparators
DEFINE LCD_DREG PORTB ' LCD on port B
DEFINE LCD_DBIT 4 ' Data bits B4..B7
DEFINE LCD_RSREG PORTB ' RS on PORTB
DEFINE LCD_RSBIT 3 ' RS on B3
DEFINE LCD_EREG PORTB ' E on PORTB
DEFINE LCD_EBIT 1 ' E on B1
DEFINE LCD_BITS 4 ' LCD 4 bit mode
DEFINE LCD_LINES 2 ' 2 line LCD display
Temperature1 Var Word ' Temperature storage Sensor1
Temperature2 Var Word ' Temperature storage Sensor2
TempC Var Word
Float Var Word
TargetTemp Var Word ' Desired Temperature
Hyst Var Word ' Hystereris
V Var Word ' Var. for display
V2 Var Word ' Var. for display
B1 Var Byte ' Byte for TargetTemp calculation
B2 Var Byte ' Byte for TargetTemp calculation
Sign Var Byte ' +/- sign
Mode Var Byte ' 0=Temp. display, 1=Set Temp, 2=Set Hysteresis
DQ Var PORTA.2 ' One-wire data pin
Twist Var Bit
Twist2 Var Bit
Dummy Var Byte
DS18B20_9bit CON %00011111 ; 93.75ms, 0.5°C
DS18B20_10bit CON %00111111 ; 187.5ms, 0.25°C
DS18B20_11bit CON %01011111 ; 375ms, 0.125°C
DS18B20_12bit CON %01111111 ; 750ms, 0.0625°C (default)
DS18B20_1_12bit CON %01111111 ; 750ms, 0.0625°C
DS18B20_2_12bit CON %01111111 ; 750ms, 0.0625°C
DATA 46, 224, 20 ' Temp MSB, TEMP LSB, Hysteresis DIV 10
PORTA.5 = 0 ' Warm Output Low
PORTA.0 = 0 ' Cold Output Low
Mode = 0 ' Temperature display mode
Twist = 0
Twist2 = 0
Pause 500
low portb.2
LCDOUT $FE, 1, $FE, $0C ' Clear display, cursor off
Pause 250
Read 0, B1 ' Read TargetTemp MSB
Read 1, B2 ' Read TargetTemp LSB
TargetTemp = B1 * 256 + B2 ' Calculate TargetTemp value (Default=20.0 C.)
Read 2, B1 ' Read Hysteresis
Hyst= 10 * B1 ' Calculate Hysteresis value (Default= 2.0 C.)
OWOut DQ, 1, [$55, $28, $4F, $DF, $A0, $01, $00, $00, $7C, $4E, $FF, $FF, DS18B20_12bit] ' Init Sensor 1
OWOut DQ, 1, [$55, $28, $4F, $DF, $A0, $01, $00, $00, $7C, $48]
OWOut DQ, 1, [$55, $28, $4F, $DF, $A0, $01, $00, $00, $7C, $B8]
OWOut DQ, 1, [$55, $28, $4F, $DF, $A0, $01, $00, $00, $7C, $BE]
Pause 1000
OWIn DQ, 0, [Temperature1.Byte0, Temperature2.Byte1]
LcdOut $FE, $80, "Senzor1 INIT OK"
Pause 500
OWOut DQ, 1, [$55, $28, $80, $5E, $BF, $01, $00, $00, $63, $4E, $FF, $FF, DS18B20_12bit] ' Init Sensor 2
OWOut DQ, 1, [$55, $28, $80, $5E, $BF, $01, $00, $00, $63, $48]
OWOut DQ, 1, [$55, $28, $80, $5E, $BF, $01, $00, $00, $63, $B8]
OWOut DQ, 1, [$55, $28, $80, $5E, $BF, $01, $00, $00, $63, $BE]
Pause 1000
OWIn DQ, 0, [Temperature2.Byte0, Temperature2.Byte1]
LcdOut $FE, $C0, "Senzor2 INIT OK"
Pause 1000
MainLoop:
If PORTA.6 = 0 then ' Mode switch pressed
Pause 50 ' Debounce
LcdOut $FE, 1
LcdOut $FE, $8F, "*" ' Show that command is accepted
If PORTA.6 = 0 then MainLoop ' Wait until button is released
Mode = Mode + 1 ' Increment mode
If Mode = 2 then ' Save Target Temperature (Mode1 -> Mode2)
Write 0, TargetTemp / 256 ' TargetTemp MSB
Write 1, TargetTemp MOD 256 ' TargetTemp LSB
EndIf
If Mode > 2 Then ' Save Hysteresis (Mode 2 -> Mode 0)
Mode=0 ' Only 0, 1, 2 are valid
Write 2, Hyst / 10 ' Divide Hyst value to fit in Byte
EndIf
EndIf
If Mode = 1 then
LcdOut $FE, $80, "SET TEMPERATURE " ' Show function
V = TargetTemp ' TargetTemp in V
Gosub SelectSign ' Select +/blank/-
Gosub DTemp ' Display Target Temperature
If (PORTA.7 = 0) Or (PORTA.3 = 0) then ' Up or Down button pushed
If PORTA.7 = 0 then ' Down button
If TargetTemp > 7500 then ' Not lower than -25 C. (10000-MinTemp * 100)
TargetTemp = TargetTemp - 25 ' Decrease temperuture with 0.25 C.
EndIf
EndIf
If PORTA.3 = 0 then ' Up button
If TargetTemp < 17500 then ' Not higher than 75 C. (10000+MaxTemp * 100)
TargetTemp = TargetTemp + 25 ' Increase temperature with 0.25 C.
EndIf
EndIf
GoSub SetTargetTemp ' Display TargetTemp and delay 0.25 Sec.
EndIf
EndIf
If Mode = 2 then ' Set Hysteresis
LcdOut $FE, $80, "SET HYSTERESIS " ' Show function
Sign = " " ' No sign
V = 10000 + Hyst ' Set value for V
Gosub DTemp ' Display Hysteresis
If (PORTA.7 = 0) Or (PORTA.3 = 0) then ' Up or down button pushed
Sign = " " ' No sign for Hysteresis
If PORTA.7 = 0 then ' Down button
If Hyst > 10 then Hyst = Hyst - 10 ' Not less than 0.1 C.
EndIf
If PORTA.3 = 0 then ' Up button
If Hyst < 1000 then Hyst = Hyst + 10 ' Not more than 10.0 C.
EndIf
V = 10000 + Hyst ' Set value for V
Gosub DTemp ' Display Hysteresis
Pause 250 ' Delay 0.25 Sec.
EndIf
EndIf
If Mode > 0 then Mainloop ' Setting TargetTemperature or Hysteresis
Output DQ ' Make Pin Output
DQ = 0 ' OneWire line Low
PauseUs 480 ' Keep down for 480 µS
Input DQ ' Make Pin Input
PauseUs 70 ' Wait 70 µS
If DQ = 1 then ' No presence pulse from DS1820
LcdOut $FE, $1, "** No sensor! **" ' Show message
Pause 500 ' Wait 0.5 Sec.
Goto MainLoop ' Check again
EndIf
'===================================================================================================
Main :
Part1:
OWOut DQ, 1, [$55, $28, $4F, $DF, $A0, $01, $00, $00, $7C, $44] ' Start temp. conversion Sensor1
WaitLoop:
While not DQ
Wend
OWOut DQ, 1, [$55, $28, $4F, $DF, $A0, $01, $00, $00, $7C, $BE]
Pause 500
OWIn DQ, 0, [Temperature1.Byte0, Temperature1.Byte1]
If Temperature1.15 then
Temperature1 = ~Temperature1 +1
Twist = 1
Endif
Dummy = 625 * Temperature1
TempC = DIV32 10
TempC = (Temperature1 & $7FF) >> 4
Float = ((Temperature1.Lowbyte & $0F ) * 25 )>> 2
Temperature1 = TempC * 100 + Float
If Twist then
V = 10000 - Temperature1 ' 25 C=12500 0 C=10000 -10 C=9000
Twist = 0
else
V = 10000 + Temperature1
EndIf
If V >= 10000 then ' Above 0 C.
Temperature1 = V - 10000
Else
Temperature1 = 10000 - V ' Below 0 C.
EndIf
GoSub SelectSign ' +/blank/- Sign
GoSub DisplayTemp ' Temperature to LCD
'===================================================================================================
Part2 :
OWOut DQ, 1, [$55, $28, $80, $5E, $BF, $01, $00, $00, $63, $44] ' Start temp. conversion Sensor2
WaitLoop2:
While not DQ
Wend
OWOut DQ, 1, [$55, $28, $80, $5E, $BF, $01, $00, $00, $63, $BE]
Pause 500
OWIn DQ, 0, [Temperature2.Byte0, Temperature2.Byte1]
If Temperature2.15 then
Temperature2 = ~Temperature2 + 1
Twist2 = 1
Endif
Dummy = 625 * Temperature2
TempC = DIV32 10
TempC = (Temperature2 & $7FF) >> 4
Float = ((Temperature2.Lowbyte & $0F ) * 25 )>> 2
Temperature2 = TempC * 100 + Float
If Twist2 then
V2 = 10000 - Temperature2 ' 25 C=12500 0 C=10000 -10 C=9000
Twist2 = 0
else
V2 = 10000 + Temperature2
EndIf
If V2 >= 10000 then ' Above 0 C.
Temperature2 = V2 - 10000
Else
Temperature2 = 10000 - V2 ' Below 0 C.
EndIf
GoSub SelectSign ' +/blank/- Sign
GoSub DisplayTemp ' Temperature to LCD
Goto MainLoop ' Do it forever
' SUBROUTINES:
'===================================================================================================
SelectSign:
If v = 10000 then ' Temperature = 0 C.
Sign = " " ' No sign
Else
If v < 10000 then ' <> 0
Sign = "-" ' Temperature below 0 C.
Else
Sign = "+" ' Temperature above 0 C.
EndIf
EndIf
If v2 = 10000 then ' Temperature = 0 C.
Sign = " " ' No sign
Else
If v2 < 10000 then ' <> 0
Sign = "-" ' Temperature below 0 C.
Else
Sign = "+" ' Temperature above 0 C.
EndIf
EndIf
Return
'===================================================================================================
DisplayTemp:
If V >= 10000 then ' Above 0 C.
Temperature1 = V - 10000
Else
Temperature1 = 10000 - V ' Below 0 C.
EndIf
If V2 >= 10000 then ' Above 0 C.
Temperature2 = V2 - 10000
Else
Temperature2 = 10000 - V2 ' Below 0 C.
EndIf
LcdOut $FE, $80, "INT : ", Sign," ", DEC (Temperature1 / 100), ".", DEC2 Temperature1, " ",223,"C "
LcdOut $FE, $C0, "EXT : ", Sign," ", DEC (Temperature2 / 100), ".", DEC2 Temperature2, " ",223,"C "
Return
'===================================================================================================
SetTargetTemp:
V = TargetTemp
Gosub SelectSign
Gosub DTemp
Pause 250
Return
'===================================================================================================
DTemp :
If V >= 10000 then ' Above 0 C.
Temperature1 = V - 10000
Else
Temperature1 = 10000 - V ' Below 0 C.
EndIf
LcdOut $FE, $C0, Sign," ", DEC (Temperature1 / 100), ".", DEC2 Temperature1, " ",223,"C "
Return
'============================================= END OF PROGRAM ======================================