Code:
;************************ 16F88 Configuration Fuses ****************************
@ __CONFIG _CONFIG1, _CP_OFF & _CCP1_RB3 & _DEBUG_OFF & _WRT_PROTECT_OFF & _CPD_OFF & _LVP_OFF & _BODEN_ON & _MCLR_OFF & _PWRTE_ON & _WDT_ON & _XT_OSC
; Code Protection - _CP_OFF, CP_ON
; CCP1 Pin Selection - _CCP1_RB0, _CCP1_RB3
; In-Circuit Debugger Mode - _DEBUG_OFF, _DEBUG_ON
; Flash Program Memory Write Enable - _WRT_PROTECT_OFF, _WRT_PROTECT_256, _WRT_PROTECT_2048, _WRT_PROTECT_ALL
; Data EE Memory Code Protection - _CPD_OFF, _CPD_ON
; Low-Voltage Programming Enable - _LVP_OFF, _LVP_ON
; Brown-Out Reset - _BODEN_OFF, _BODEN_ON
; RA5/MCLR/Vpp Pin Function - _MCLR_OFF, _MCLR_ON
; Power-Up Timer - _PWRTE_OFF, _PWRTE_ON
; Watchdog Timer - _WDT_OFF, _WDT_ON
; Oscillator Selection - _EXTRC_CLKOUT, _EXTRC_IO, _INTRC_CLKOUT, _INTRC_IO, _EXTCLK, _HS_OSC, _XT_OSC, _LP_OSC,
;
@ __CONFIG _CONFIG2, _IESO_OFF & _FCMEN_ON
; Oscillator Switchover - _IESO_OFF, _IESO_ON
; Fail-Safe Clock Monitor - _FCMEN_OFF, _FCMEN_ON
;*******************************************************************************
;------------------------- Port Assignments --------------------------------
; PORTB.6 DS18B20 - Data Line
;--------------------------- Setup DEFINE;s ----------------------------------
DEFINE OSC 4
DEFINE ADC_BITS 10 ; Set resolution of conversion
DEFINE ADC_CLOCK 8 ; Set clock source (x/FOSC or FRC)
DEFINE ADC_SAMPLEUS 50 ; Set sampling time (in uS)
;------------------------ Port Initialization -------------------------------
CCP1CON = %00000000 ; Disable CCP Module
SSPCON.5 = 0 ; Disable SSP Module
TXSTA.5 = 0 ; Disable AUSART Tx
RCSTA.7 = 0 ; Disable Serial Port
ANSEL = %01000000 ; Set analog ports to digital mode except RB7/AN6
CMCON = %00000111 ; Turn off comparator
OPTION_REG.6 = 0
ADCON1 = %10000000
TRISA = %100000
TRISB = %11110101
;----------------------------- Debug Settings ----------------------------------
cmd con 254 ; Control byte
clr con 1 ; Clear the display
line1 con 128 ; Move cursor to home position on line 1
line2 con 192 ; Move cursor to home position on line 2
line3 con 148 ; Move cursor to home position on line 3
line4 con 212 ; Move cursor to home position on line 4
; ----------------------------- Port Aliases ---------------------------------
DSDataPin var portb.6
;---------------------- Miscellaneous Variables ------------------------------
i var byte ; Loop counter
x var word ; Variable for calculations
DataBit var bit ; Bit shift variable
dummy var word ; Dummy variable for DIV32 function
DataByte var byte ; Byte to perform CRC calculation on
DQ var byte[9] ; 9 Byte Arrray for DS18B20 data
CRCCalc var byte ; Calculated CRC value
NegBit var rawtemp.Bit11 ; +/- indicator: 1 = < 0ºC
RawTemp var word ; Raw Temperature
SignC var byte ; +/- Sign for celcius temperature
SignF var byte ; +/- Sign for fahrenheit temperature
TempC var word ; Temperature in ºC
TempF var word ; Temperature in ºF
TempK var word ; Temperature in Kelvin
CRCError var byte ; Temperature Sensor CRC Error Flag
;--------------------------- Main Program Loop -------------------------------
main:
gosub ReadDS18B20
lcdout cmd,line1,SignC,dec3 TempC/100,".",dec2 TempC//100,223,"C"
lcdout cmd,line2,SignF,dec3 TempF/100,".",dec2 TempF//100,223,"F"
lcdout cmd,line3," ",dec3 TempK/100,".",dec2 TempK//100," K"
goto main
;---------------------------- Read DS18B20 Sensor ------------------------------
ReadDS18B20:
owout DSDataPin,1,[$CC,$44] ; Tell sensor to start a temperature conversion
owout DSDataPin,1,[$CC,$BE] ; Tell sensor you want to read the temperature
owin DSDataPin,0,[STR DQ\9] ; Receive temperature from the sensor
RawTemp.Byte0 = DQ[0] ; Extract the temperature portion and put it in its one word variable
RawTemp.Byte1 = DQ[1]
gosub GetCRC ; Calculate the CRC for comparison
gosub ConvertCelcius ; Convert temperature to ºC
gosub ConvertToFahrenheit ; Convert temperature to ºF
gosub ConvertToKelvin ; Convert temperature to K
return
;------------------------ Calculate the CRC from Byte 9 ------------------------
GetCRC:
for x = 0 to 7 ; Get CRC for each of the 8 bytes
DataByte = DQ[x] ; Assign array pointer using value of x
gosub CalcCRC ; Get CRC value
next x ; Repeat until all bytes are done
if DQ[8] <> CRCCalc then ; Do the CRC values match?
CRCError = 1 ; Set flag indicating a problem with this sensor
else
CRCError = 0 ; Set flag indicating no problem with this sensor
endif
CRCCalc = 0 ; Reset CRC calculation variable
return
;--------------------- CRC Bit Calcuation Method -------------------------------
CalcCRC:
for i = 0 to 7 ; Do for all 8 bits in DataByte
DataBit = CRCCalc.0 ^ DataByte.0 ; XOR bit0 of DataByte and CRC
DataByte = DataByte >> 1 ; Position DataByte for next bit test
if DataBit = 0 then Shift ; If test bit not set, just shift CRCCalc
CRCCalc = CRCCalc ^ $18 ; If set, account for EXOR feedback
shift:
CRCCalc = CRCCalc >> 1 ; Shift right the CRCCalc byte
CRCCalc.7 = DataBit ; CRC bit 0 to bit bucket
next i ; Data bit rotates into CRC bit 7
return
;--------------------------- Convert to Celcius --------------------------------
ConvertToCelcius:
if negbit = 1 then
SignC = "-"
else
SignC = "+"
endif
if SignC = "-" then
dummy = 0
RawTemp.Byte0 = RawTemp.Byte0 ^ 255
RawTemp.Byte1 = RawTemp.Byte1 ^ 255
dummy = 625 * RawTemp + 1
TempC = DIV32 100
else
dummy = 625 * RawTemp
TempC = DIV32 100
endif
return
;------------------------ Convert to Fahrenhiet --------------------------------
ConvertToFahrenheit:
if SignC = "+" then
SignF = "+"
dummy = TempC * 18
TempF = div32 10
TempF = TempF + 3200
else
TempF = (tempc + 5000) * 900
TempF = DIV32 500
if TempC => 1778 and SignC = "-" then
TempF = TempF - 12200
SignF = "-"
else
TempF = 12200 - TempF
SignF = "+"
endif
endif
return
;-------------------------- Convert to Kelvin ----------------------------------
ConvertToKelvin:
if SignC = "-" then
TempK = 27315 - TempC
else
TempK = tempC + 27315
endif
return
Bookmarks