Evo moj source code za PIC Termostat
Code: Select all
DEFINE LCD_DREG PORTB ' LCD on port B
DEFINE LCD_DBIT 4 ' Data bits B4..B7
DEFINE LCD_RSREG PORTA ' RS on PORTA
DEFINE LCD_RSBIT 1 ' RS on A1
DEFINE LCD_EREG PORTA ' E on PORTA
DEFINE LCD_EBIT 0 ' E on A0
DEFINE LCD_BITS 4 ' LCD 4 bit mode
DEFINE LCD_LINES 2 ' 2 line LCD display
'*****************************************************************************
'Pinout for Elektor
'*****************************************************************************
Heat Var PORTA.2
Cool Var PORTA.3
DQ Var PORTA.4 ' One-wire data pin
Mode_B Var PORTB.0
UP_B Var PORTB.1
DOWN_B Var PORTB.2
'*****************************************************************************
'*****************************************************************************
' I/o Settings
'*****************************************************************************
PORTA = 0
PORTB = 0
TRISA= %11110000 ' RA0..3=Outputs RA4=Input
TRISB= %00000111 ' RB0..RB2=Inputs, RB3..RB7=Outputs
'*****************************************************************************
'*****************************************************************************
' Variables
'*****************************************************************************
Temperature Var Word ' Temperature storage
TempC Var Word
Float Var Word
TargetTemp Var Word ' Desired Temperature
Hyst Var Word ' Hystereris
V Var Word ' Var. for display
B1 Var Byte ' Byte for TargetTemp calculation
B2 Var Byte ' Byte for TargetTemp calculation
'Count_Remain Var Byte ' Count remaining
'Count_Per_C Var Byte ' Count per degree C
Sign Var Byte ' +/- sign
Mode Var Byte ' 0=Temp. display, 1=Set Temp, 2=Set Hysteresis
Twist Var Bit
'*****************************************************************************
'*****************************************************************************
' Resolution
'*****************************************************************************
DS18B20_9bit CON %00011111 ' 93.75ms, 0.5°C
DS18B20_10bit CON %00111111 ' 187.5ms, 0.25°C <-- My favorite
DS18B20_11bit CON %01011111 ' 375ms, 0.125°C
DS18B20_12bit CON %01111111 ' 750ms, 0.0625°C (default)
DATA 46, 224, 20 ' Temp MSB, TEMP LSB, Hysteresis DIV 10
Heat=0 ' Warm Output Low
Cool=0 ' Cold Output Low
Mode=0 ' Temperature display mode
Twist = 0
PAUSE 500
LCDOUT $FE, 1, $FE, $0C ' Clear display, cursor off
PAUSE 250
'*****************************************************************************
'*****************************************************************************
' DS 18B20 Config
'*****************************************************************************
OWOUT DQ, 1, [$CC, $4E, 0, 0, DS18B20_12bit] 'Skip ROM search and write N_bits
' ' resolution to scratch pad
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.)
MainLoop:
If Mode_B=0 then ' Mode switch pressed
Pause 50 ' Debounce
LcdOut $FE, $8F, "*" ' Show that command is accepted
If Mode_B=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 ' Set Target Temperature
LcdOut $FE, $80, "POST. TEMPERATURE " ' Show function
V=TargetTemp ' TargetTemp in V
Gosub SelectSign ' Select +/blank/-
Gosub DisplayTemp ' Display Target Temperature
If (UP_B=0) Or (DOWN_B=0) then ' Up or Down button pushed
If DOWN_B=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 UP_B=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, "HISTEREZA " ' Show function
Sign=" " ' No sign
V= 10000+Hyst ' Set value for V
Gosub DisplayTemp ' Display Hysteresis
If (UP_B=0) Or (DOWN_B=0) then ' Up or down button pushed
Sign=" " ' No sign for Hysteresis
If DOWN_B=0 then ' Down button
If Hyst > 10 then Hyst=Hyst-10 ' Not less than 0.1 C.
EndIf
If UP_B=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 DisplayTemp ' Display Hysteresis
Pause 250 ' Delay 0.25 Sec.
EndIf
EndIf
If Mode > 0 then Mainloop ' Setting TargetTemperature or Hysteresis
LcdOut $FE, $80, "TEMPERATURA " ' Show function
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, "** Nema senzora! **" ' Show message
Pause 500 ' Wait 0.5 Sec.
Goto MainLoop ' Check again
EndIf
'*****************************************************************************
'*****************************************************************************
' Temp reading
'*****************************************************************************
OWOut DQ, 1, [$CC, $44 ] ' Start temperature conversion
'WaitLoop: OWIn DQ, 4, [Count_Remain] ' Check for still busy converting
' If Count_Remain = 0 Then WaitLoop ' Busy
' OWOut DQ, 1, [$CC, $BE] ' Read the temperature
' OWIn DQ, 0, [Temperature.LowByte, Temperature.HighByte, Skip 4, Count_Remain, Count_Per_C]
' Temperature = (((Temperature >> 1) * 100) - 25) + (((Count_Per_C - Count_Remain) * 100) / Count_Per_C)
' if Temperature > 32767 then
' Temperature= ~Temperature
waitloop:
WHILE NOT DQ
WEND
OWOUT DQ, 1, [$CC, $BE ] ' Skip ROM search & read scratchpad memory
OWIN DQ, 2, [Temperature.Lowbyte, Temperature.Highbyte]' Read two bytes / end comms
Convert_Temp:
IF Temperature.15 THEN
Temperature = ~Temperature + 1
Twist = 1
ENDIF
TempC = ( Temperature & $7FF ) >> 4 ' Partie Entičre '4
Float = ((Temperature.Lowbyte & $0F ) * 25 )>> 2 ' Partie décimale 100čmes
Temperature = TempC*100 + Float 'Préparation 1/100 degrés
IF Twist THEN
V= 10000 - Temperature ' 25 C=12500 0 C=10000 -10 C=9000
Twist = 0
else
V= 10000 + Temperature
EndIf
If V < TargetTemp - Hyst then ' Below Target temperature - Hysteresis
Heat=1 ' Activate Warm Output
Cool=0 ' Deactivate Cold Output
EndIf
If V > TargetTemp + Hyst then ' Above Target temperature + Hysteresis
Heat=0 ' Deactivate Warm output
Cool=1 ' Activate Cold Output
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
Return
'*****************************************************************************
DisplayTemp:
If V >= 10000 then ' Above 0 C.
Temperature=V-10000
Else
Temperature=10000-V ' Below 0 C.
EndIf
LcdOut $FE, $C0, Sign, DEC (Temperature / 100), ".", DEC2 Temperature, " ",223,"C "
Return
'*****************************************************************************
SetTargetTemp:
V=TargetTemp
Gosub SelectSign
Gosub DisplayTemp
Pause 250
Return
'*****************************************************************************
END
http://www.dodaj.rs/f/2q/1l/3hEkuaS6/1.jpg
Ikakve ideje?