OneWire - DS18B20 - PIC18F4550 code query

Find out how to setup your programmer's software and how to solve many common problems.

Moderator: phalanx

Post Reply
GrafZeppelin
Posts: 1
Joined: Thu Jun 16, 2016 8:57 am

OneWire - DS18B20 - PIC18F4550 code query

Post by GrafZeppelin » Thu Jun 16, 2016 9:00 am

Hello all,

In the last three days I was struggling to read temperature data from a single DS18B20 when using non-parasitic OneWire protocol and a PIC18F4550. Finally I had a break-trough (at least I think I have), when I decided to take baby steps and : 1. Read a presence pulse; 2. Read device family code; 3. Attempt to read temperature data. So far points 1 and 2 were accomplished successfully, I was able to read the presence pulse (0) and a family code (0x28). But the last point, I am still struggling bad. I understand that in order to read temperature values, I first need to write a command to convert temperature (0x44), then reset the OneWire, give a 0.75s delay for the conversion to be completed, and then write to the scratchpad 0xBE to read from the register. I've tried combining the codes I found in maxim website and as well some other codes I found all over the web. LCD now displays Temperature: 11, when my room temperature is currently ~27 degrees C. Please can someone check my codes to see whether there is an issue somewhere? Thanks!

DS18B20 header file:

Code: Select all

#define __XTAL_FREQ 8000000

#define Data_pin RB2
#define Data_bus TRISB2
#define Skip_ROM 0xCC                // 0b11001100
#define Convert_temperature 0x44    // 0b01000100
#define Read_scratchpad 0xBE            // 0b10111110
#define Read_deviceFamily 0x33

int OneWire_reset()
{
    Data_bus = 0;        //Set as output
	Data_pin = 0;        //Drive Low
    __delay_us(480);
    Data_bus = 1;        //Release, Set back as input
    __delay_us(70);
   
if (Data_pin == 0)        // Sample bus
    {
        __delay_us(410);
        return 0;        // Device present
    }
    else
    {
        __delay_us(410);
        return 1;        // No device present
    }
}

int OneWire_readByte(void)
{
    int l, result = 0;
    for(l=0;l<8;l++)
    {
        result >>= 1;
        if(OneWire_readBit())
            result |= 0x80;
    }
    return result;
}

int OneWire_readBit(void)
{
    unsigned int Read_state = 0;
    
    Data_bus = 0;        //Set as output
	Data_pin = 0;        //Drive low
    __delay_us(6);
    Data_bus = 1;        //Release, set as input
    __delay_us(9);
    Read_state = Data_pin;
    
    return Read_state;
}

void OneWire_writeBit(unsigned int b)
{
    Data_bus = 0;        //Set as output
   	Data_pin = 0;        //Drive low

    if(b == 1)
    {
        __delay_us(3);
        Data_bus = 1;    //Release, set as input
        __delay_us(62);
    }
    else
    {
        __delay_us(57);
        Data_bus = 1;    //Release, set as input
        __delay_us(7);
    }
}

void OneWire_writeByte(unsigned int data)
{
    int l;
    for(l=0;l<8;l++)
    {
        OneWire_writeBit(data & 0x01);
        data >>= 1;
    }
}
And the main code:

Code: Select all

#define _XTAL_FREQ 8000000

#include <xc.h>
#include <stdio.h>
#include "LCD_4bit_config.h"
#include "DS18B20_config.h"
#include "delay.h"

OneWire_init()
{
	int i;
	char buf1[10];
	char buf2[10];
		
	LCD_setCursor(1,1);
    	LCD_writeString("Presence:");
        
        i = OneWire_reset();
        	
        sprintf(buf1,"%d",i);
        LCD_setCursor(2,1);
        LCD_writeString(buf1);
        
        delay_ms(3000);
        LCD_clr();
        	
        OneWire_reset();
        
        LCD_setCursor(1,1);
        LCD_writeString("Device family:");
        	
        OneWire_writeByte(Read_deviceFamily);
        	
        i = OneWire_readByte();
        	
        sprintf(buf2,"%d",i);
        LCD_setCursor(2,1);
        LCD_writeString(buf2);
        	
        delay_ms(3000);
        LCD_clr();
        	
       	OneWire_reset();
}

void main()
{	
	char temp_lsb,temp_msb,temp;
	
	char buf3[10];
	
	char getBit[10];

	int k;
	 
	OSCCON = 0b11110010;    // Set PIC18F4550 internal oscillator at 8MHz
	
	ADCON1 = 0x0F;            // Set all pins as digital I/O
        CMCON = 0x07;             // Set all comparators as digital I/O
    
	LATD = 0;			    // Clear port D
	TRISD = 0b00000000;		// Set all port D pins as digital outputs
	
	LATB = 0;
	TRISB = 0x00;
	
        LCD_init();				// Initialize LCD
        OneWire_init();
        	    
    while(1)
    {
       		
       	if (!OneWire_reset())
       	{
       	    LCD_setCursor(1,1);
    	    LCD_writeString("Temperature:");
    	    
    	    OneWire_writeByte(Skip_ROM);          
            OneWire_writeByte(Convert_temperature);
		
			OneWire_reset();
			delay_ms(750);
    	    
    	    OneWire_writeByte(Skip_ROM);
    	    OneWire_writeByte(Read_scratchpad);
    	    
    	    for (k=0;k<9;k++)
    	    	{
	    	    	getBit[k] = OneWire_readByte();	
	    	    }
	    	    
	    	temp_msb = getBit[1];
	    	temp_lsb = getBit[0];
	    	    			
	    	temp = (temp_msb << 8) + temp_lsb;
	    	
	    	temp = temp >> 4;
	    	
			sprintf(buf3,"%d",temp);
        	LCD_setCursor(2,1);
        	LCD_writeString(buf3);
        	
        	delay_ms(1000);
    	   	}
   	}
}

Post Reply