PDA

View Full Version : DS1820 and 18f2550



rjones2102
- 2nd October 2007, 10:25
There are so many threads/ articles on the net about this but I am still failing to get it working. If anyone has a good idea, please HELP ME!

I have the DS1820 wired with 5 volts on pin 3, a 4.7 k pullup on pin 2 to PortA.0 on Pic and pin 1 to gnd. I have measured voltages with and without the 18f2550 in place to verify the voltage on pin 3 of DS1820 is coming from pullup. I am 99.999% certain electrically it is all good.

My fuse are setup as follows as I have USB comms running but not for the duration of the DS1820 tests just to make it simple. I am using a 20Mhz OSC and USB comms works fine so I am confident about Osc config etc at least for USB. OW doesn't have any special requirements does it?.



__CONFIG _CONFIG1L, _PLLDIV_5_1L & _CPUDIV_OSC1_PLL2_1L & _USBDIV_2_1L
; ; USB clock source comes from the 96 MHz PLL divided by 2
; ; [OSC1/OSC2 Src: /1][96 MHz PLL Src: /2]
; No prescale (4 MHz oscillator input drives PLL directly)

__CONFIG _CONFIG1H, _FOSC_HSPLL_HS_1H & _FCMEN_OFF_1H & _IESO_OFF_1H
; ; ; Oscillator Switchover mode disabled
; ; Fail-Safe Clock Monitor disabled
; XT oscillator, PLL enabled, XT used by USB

__CONFIG _CONFIG2L, _PWRT_ON_2L & _BOR_ON_2L & _BORV_2_2L & _VREGEN_ON_2L
__CONFIG _CONFIG2H, _WDT_OFF_2H
__CONFIG _CONFIG3H, _MCLRE_ON_3H & _LPT1OSC_OFF_3H & _PBADEN_OFF_3H & _CCP2MX_ON_3H
__CONFIG _CONFIG4L, _STVREN_ON_4L & _LVP_OFF_4L & _XINST_OFF_4L & _DEBUG_OFF_4L


I have tried 2 pieces of code. First one just outputs
Busy
Busy
Busy
.....

To Hyperterm:



DEFINE OSC 48 ' We're using a 20MHz oscillator
ADCON1 = 7 ' Make pins digital
DEFINE HSER_RCSTA 90h ' Enable serial port & continuous receive
DEFINE HSER_TXSTA 24h ' Enable transmit, BRGH = 1
DEFINE HSER_CLROERR 1 ' Clear overflow automatically
DEFINE HSER_SPBRG 225 ' 9600 Baud @ 48MHz, 0.0%
SPBRGH = 4
BAUDCON.3 = 1 ' Enable 16 bit baudrate generator

HSEROUT [13,10,"Starting"]
Comm_Pin VAR PortA.0 ' One-wire Data-Pin "DQ" on PortC.0
Busy VAR BIT ' Busy Status-Bit
R_Temp VAR WORD ' RAW Temperature readings
TempC VAR WORD ' Temp in deg C
TempF VAR WORD ' Temp in deg F
Float VAR WORD ' Holds remainder for + temp C display
Cold_Bit VAR R_Temp.Bit11' Sign-Bit for +/- Temp. 1 = Below 0 deg C
Real_Cold CON 1 ' Define Real_Cold = 1
BAUD CON 16468 ' N9600 for serial LCD
DISP VAR PortB.0 ' Pin to drive serial LCD
Deg CON 223 ' Data to display Deg ° symbol
CLR CON 1 ' CLR LCD command
LINE1 CON 128 ' LCD line #1
LINE2 CON 192 ' LCD line #2
LINE3 CON 148 ' LCD line #3
LINE4 CON 212 ' LCD line #4
INS CON 254 ' LCD command mode parameter
Sign VAR BYTE ' +/- sign for temp display
Dummy VAR BYTE ' Dummy for Div32

Start_Convert:
OWOUT Comm_Pin, 1, [$CC, $44]' Skip ROM search & do temp conversion
Pause 2000
Wait_Up:
OWIN Comm_Pin, 4, [Busy] ' Read busy-bit
hserout [13,10,"Busy"]
pause 100
IF Busy = 0 THEN Wait_Up ' Still busy..?, Wait_Up..!
OWOUT Comm_Pin, 1, [$CC, $BE]' Skip ROM search & read scratchpad memory
OWIN Comm_Pin, 2, [R_Temp.Lowbyte, R_Temp.Highbyte]' Read two bytes / end comms
GOSUB Convert_Temp
GOTO Start_Convert

Convert_Temp: ' +32.0 to +257 F
IF Cold_Bit = Real_Cold THEN Yikes ' If Cold_Bit = 1, it's below "0" deg C
Sign = "+"
Dummy = 625 * R_Temp ' Multiply to load internal registers with 32-bit value
TempC = DIV32 10 ' Use Div32 value to calculate precise deg C
Dummy = 1125 * R_Temp
TempF = DIV32 100
IF TempF >6795 THEN ' Over 99.5 deg F..?
TempF = TempF + 3200
HSEROUT [13,10, " TempF = ",Sign,DEC TempF DIG 4,_
DEC TempF DIG 3,DEC TempF DIG 2,".",DEC2 TempF,Deg,"F "]
ELSE
TempF = TempF + 3200
HSEROUT [13,10, " TempF = ",Sign,DEC TempF DIG 3,_
DEC TempF DIG 2,".",DEC2 TempF,Deg,"F "]
ENDIF
TempC = (R_Temp & $0FF0) >> 4 ' Mask middle 8-bits, shift into lower byte
Float = ((R_Temp.Lowbyte & $0F) * 625) ' Lower 4-bits of result * 625
HSEROUT [13,10, " TempC = ",Sign,DEC TempC,".",DEC Float,Deg,"C "]
HSEROUT [13,10, "Raw", IBIN16 R_Temp]
RETURN

Yikes: ' Display full range -C to -F conversion
Sign = "-" ' Display - symbol for negative temp
Dummy = 625 * ~R_Temp+1' Multiply to load internal registers with 32-bit value
TempC = DIV32 10 ' Use Div32 value to calculate precise deg C
TempF = ~R_Temp / 16 ' Begin conversion from -C to deg +/-F
IF TempF >=18 THEN ' Check for -degrees F "-18 C = -0.4 F"
TempF = ((((TempF + 50) * 9) /5) -122) ' -C to -F below -17 deg C
HSEROUT [13,10, " TempF = ",Sign, DEC TempF,Deg,"F "]
HSEROUT [13,10, " TempC = ",Sign,DEC TempC DIG 4,_
DEC TempC DIG 3,".",DEC3 TempC,Deg,"C "]
HSEROUT [13,10, "Raw", IBIN16 R_Temp]
ELSE ' Else result = +deg F
TempF = ((((-TempF + 50) * 9) /5) -58)' -C to +F below 32.0 deg F to -17 deg C
HSEROUT [13,10, " TempF = ","+",DEC TempF,Deg,"F "]
HSEROUT [13,10, " TempC = ",Sign,DEC TempC DIG 4,_
DEC TempC DIG 3,".",DEC3 TempC,Deg,"C "]
HSEROUT [13,10, "Raw", IBIN16 R_Temp]
ENDIF
RETURN

END


The second really simple bit of code just outputs 00.0



define OSC 48
ADCON1 = 7 ' Set PORTA to digital
DEFINE HSER_RCSTA 90h ' Enable serial port & continuous receive
DEFINE HSER_TXSTA 24h ' Enable transmit, BRGH = 1
DEFINE HSER_CLROERR 1 ' Clear overflow automatically
DEFINE HSER_SPBRG 225 ' 9600 Baud @ 48MHz, 0.0%
SPBRGH = 4
BAUDCON.3 = 1 ' Enable 16 bit baudrate generator
HSEROUT [13,10,"Starting"]

DQ var PORTA.0
temp var word

loop:
owout DQ,1,[$cc]
owout DQ,0,[$44]
Pause 2000
owout DQ,1,[$cc]
owout DQ,0,[$be]
owin DQ,0,[temp.byte0,temp.byte1]
temp=temp*5
HSEROUT [13,10, " Temp = ",DEC2 temp/10,".", dec1 temp," ","C"]
goto loop


These bits of code come from sources that swear they work. What else could it be?!?!! For now I will try and send something else down USB to VB!!

Hope someone can help.

Thanks a lot

Rich

Acetronics2
- 2nd October 2007, 11:12
Hi, Rich

I have a DS1820 "on board" ... I look at that.

Here is an excerpt of my test program:



'************************************************* ****************************
' Start temperature conversion
'************************************************* ****************************

mainloop: OWOut DQ, 1, [$CC, $44 ]

'************************************************* ****************************
' Check for still busy converting ( ~ 4500 times ... )
'************************************************* ****************************

waitloop:

INPUT DQ
If NOT DQ Then waitloop

'************************************************* ****************************
' Read the temperature
'************************************************* ****************************

OWOut DQ, 1, [$CC, $BE ]

OWIn DQ, 0, [temperature.LOWBYTE, temperature.HIGHBYTE, Skip 4, count_remain, count_per_c]

'************************************************* ****************************
' Calculate temperature in degrees C to 2 decimal places (not valid for negative temperature)
'************************************************* ****************************

temperature = (((temperature >> 1) * 100) - 25) + (((count_per_c - count_remain) * 100) / count_per_c)+ offset

Lcdout $fe, 1, DEC (temperature / 100), ".", DEC2 temperature, " ",$DF,"C"

'************************************************* ****************************
' Calculate temperature in degrees F to 2 decimal places (not valid for negative temperature)
'************************************************* ****************************

temperature = (temperature */ 461) + 3200
Lcdout $fe, $c0, DEC (temperature / 100), ".", DEC2 temperature, " ",$DF,"F"






the major thing is see is here :

OWIn DQ, 0, [temperature.LOWBYTE, temperature.HIGHBYTE, Skip 4, count_remain, count_per_c]

as you receive more than 16 bits ... and your "buffer" is only 16 bits.

The Scratchpad is always FULLY read ( 8 bytes ), so you must skip the last locations.

see datasheet on page 8 for scratchpad details.

Alain

rjones2102
- 2nd October 2007, 14:01
Thanks for your help mate,

I tried using your code but my problem is earlier on than the number of bytes being read. I put this 'turn LED line on' line after the wait loop. The LED never comes on. My ds1820 is never being ready I guess. I have double checked wiring. I know it's an odd one. Any more ideas just to get me past the wait loop. Once I am past there I can work the rest out from your fabulous info!

If NOT DQ Then waitloop
high PORTA.5
' the LED never comes on (but of course it does if I put the line before the loop!)

Regards

Rich

Acetronics2
- 2nd October 2007, 14:07
Ok,

Reading closer the datasheet shows there are time slots for writing and reading ...

so, rub out your PAUSE 2000 ...

but keep on polling DQ !

Alain

rjones2102
- 2nd October 2007, 15:10
Thanks again mate but your code, the code I tried last, didn't have a pause 2000. That was mine. Your code never gets past the wait loop either. Here is code again for clarity. I appreciate it isn't going to work later in code as I haven't done anything with offset etc but there is no point till I get past the wait loop for ds1820 to become ready.



define OSC 48
ADCON1 = 7 ' Set PORTA to digital
DEFINE HSER_RCSTA 90h ' Enable serial port & continuous receive
DEFINE HSER_TXSTA 24h ' Enable transmit, BRGH = 1
DEFINE HSER_CLROERR 1 ' Clear overflow automatically
DEFINE HSER_SPBRG 225 ' 9600 Baud @ 48MHz, 0.0%
SPBRGH = 4
BAUDCON.3 = 1 ' Enable 16 bit baudrate generator
HSEROUT [13,10,"Starting"]

DQ var PORTA.0
temperature var word
count_remain var word
count_per_c var word
offset var word
'************************************************* ****************************
' Start temperature conversion
'************************************************* ****************************

mainloop: OWOut DQ, 1, [$CC, $44 ]

'************************************************* ****************************
' Check for still busy converting ( ~ 4500 times ... )
'************************************************* ****************************

waitloop:

INPUT DQ
If NOT DQ Then waitloop

high PORTA.5 ' turn on LED if it gets past this point

'************************************************* ****************************
' Read the temperature
'************************************************* ****************************

OWOut DQ, 1, [$CC, $BE ]

OWIn DQ, 0, [temperature.LOWBYTE, temperature.HIGHBYTE, Skip 4, count_remain, count_per_c]

'************************************************* ****************************
' Calculate temperature in degrees C to 2 decimal places (not valid for negative temperature)
'************************************************* ****************************

temperature = (((temperature >> 1) * 100) - 25) + (((count_per_c - count_remain) * 100) / count_per_c)+ offset

Lcdout $fe, 1, DEC (temperature / 100), ".", DEC2 temperature, " ",$DF,"C"

'************************************************* ****************************
' Calculate temperature in degrees F to 2 decimal places (not valid for negative temperature)
'************************************************* ****************************

temperature = (temperature */ 461) + 3200
'Lcdout $fe, $c0, DEC (temperature / 100), ".", DEC2 temperature, " ",$DF,"F"
HSEROUT [13,10, " Temp = ",DEC (temperature / 100), ".", DEC2 temperature, " ","F"]
goto mainloop

Bruce
- 2nd October 2007, 16:12
Try ADCON1 = 15 VS ADCON1 = 7. You are leaving most of PORTA setup as analog inputs.

Acetronics2
- 2nd October 2007, 16:34
Did you disable Porta Comparators ??? looks no ...

Default setting ... ok, but ...

EXAMPLE 10-1: INITIALIZING PORTA

CLRF PORTA ; Initialize PORTA by
; clearing output
; data latches
CLRF LATA ; Alternate method
; to clear output
; data latches
MOVLW 0Fh ; Configure A/D
MOVWF ADCON1 ; for digital inputs
MOVLW 07h ; Configure comparators
MOVWF CMCON ; for digital input
MOVLW 0CFh ; Value used to
; initialize data
; direction
MOVWF TRISA ; Set RA<3:0> as inputs
; RA<5:4> as outputs

Even Microchip does it !!! ...

Alain

rjones2102
- 2nd October 2007, 18:11
Bruce/Alain THANKYOU SO MUCH!!

The ADCON1=15 did it and I also tried your ASM example Alain. They both fixed it. Sorry, I am new to this (well, 2 weeks new) and keep thinking I have the hang of it then learning more! I thought ADCON1=7 had disabled analogue inputs on all pins. I'll read that bit of DS before I go to bed so I have actually learnt it rather than having been spoon fed! Thanks!! OK, read it and learnt something very important. The DS is the bible, if only I could understand it!

Just read example 10.1. For the first time ever the example makes some sense to me and I can see why it is relevant to us PBPers. Wow!

I was just about to go to bed miserable. I got USB going today, wanted to feed temperature to VB instead of just my name. So much is coming together! 24LC256 challenge tomorrow!

Now I can wake up to a new day and a new phase of project!

THANKS SO MUCH
Rich