Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

1-Wire and PIC24FJ128GA010

Status
Not open for further replies.

drkidd22

Member
Hello,

I'm trying to learn how the 1-wire works and have been trying to read the ROM from a DS2431, but have not been successful.
When I run the program the serial_number gets all 0xFF, not sure if this is how it's supposed to work.
I'm using RD2 and a 3.8K resistor to VCC on the 1-wire data line.


Any help will be appreciate it.

Code:
#define FCY 4000000 
#include <p24Fxxxx.h> 
#include <libpic30.h> 


//.....Configuration bits....// 
_CONFIG2(FNOSC_PRI) 
_CONFIG1(JTAGEN_OFF & FWDTEN_OFF) 


void OW_write_byte (unsigned char write_data); 
void OW_write_bit (unsigned char write_bit); 
void drive_OW_low (void); 
void drive_OW_high (void); 
unsigned char OW_read_byte (void); 
unsigned char OW_read_bit (void); 
unsigned char read_OW (void); 


#define READ_COMMAND_DS2431   0x33 
#define OW_PIN_DIRECTION  LATDbits.LATD2 
#define OW_WRITE_PIN   TRISDbits.TRISD2 
#define OW_READ_PIN PORTDbits.RD2 
#define OUTPUT 0 
#define LOW 0 
#define HIGH 1 
#define INPUT  1 
#define SET 1 
#define CLEAR 0 


//....Start Main....// 
void main (void) 
{ 


unsigned char temp; 
unsigned char serial_number[8]; 


OW_write_byte (READ_COMMAND_DS2431); 


for(temp = 0; temp<8; temp++) 
    serial_number[temp] = OW_read_byte(); // Read 64-bit registration (48-bit serial number) number from 1-wire Slave Device 
while(1); 


} 
//.....End Main.....// 


void OW_write_byte (unsigned char write_data) 
{ 
unsigned char loop; 

for (loop = 0; loop < 8; loop++) 
{ 
OW_write_bit(write_data & 0x01);  //Sending LS-bit first 
write_data >>= 1; // shift the data byte for the next bit to send 
} 
} 


void OW_write_bit (unsigned char write_bit) 
{ 
if (write_bit) 
{ 
//writing a bit '1' 
drive_OW_low();  // Drive the bus low 
//wait(DELAY_6Us); // delay 6 microsecond (us) 
__delay_us(6); 
                  drive_OW_high ();   // Release the bus 
//wait(DELAY_64Us); // delay 64 microsecond (us) 
                  __delay_us(64); 
} 
else 
{ 
//writing a bit '0' 
drive_OW_low();  // Drive the bus low 
// wait(DELAY_60Us); // delay 60 microsecond (us) 
                   __delay_us(60); 
drive_OW_high ();   // Release the bus 
// wait(DELAY_10Us); // delay 10 microsecond for recovery (us) 
                   __delay_us(10); 
} 
} 


void drive_OW_low (void) 
{ 
OW_PIN_DIRECTION = OUTPUT; 
OW_WRITE_PIN=LOW; 
} 


void drive_OW_high (void) 
{ 
OW_PIN_DIRECTION = OUTPUT; 
OW_WRITE_PIN = HIGH; 
} 


unsigned char OW_read_byte (void) 
{ 
unsigned char loop, result=0; 

for (loop = 0; loop < 8; loop++) 
{ 

result >>= 1;  // shift the result to get it ready for the next bit to receive 
if (OW_read_bit()) 
result |= 0x80; // if result is one, then set MS-bit 
} 
return result; 
} 


unsigned char OW_read_bit (void) 
{ 
unsigned char read_data;  
//reading a bit  
drive_OW_low();  // Drive the bus low 
        __delay_us(6); 
         //wait(DELAY_6Us); // delay 6 microsecond (us) 
drive_OW_high ();   // Release the bus 
__delay_us(9); 
          //wait(DELAY_9Us); // delay 9 microsecond (us) 


read_data = read_OW(); //Read the status of OW_PIN 
          __delay_us(55); 
//wait(DELAY_55Us); // delay 55 microsecond (us) 
return read_data; 
} 


unsigned char read_OW (void) 
{ 
unsigned char read_data=0; 

OW_WRITE_PIN = INPUT; 


 if (HIGH == OW_READ_PIN) 
  read_data = SET; 
 else  
read_data = CLEAR; 

return read_data; 
}
 
Code:
void drive_OW_high (void) 
{ 
   OW_PIN_DIRECTION = OUTPUT; 
   OW_WRITE_PIN = HIGH; 
}
The OW bus is open collector. Each device that shares it
either drives it low or lets it float high.

The above code drives it high by making the pin an output
setting it high. This is a big no no. It does not allow
any other devices on the bus to use it!

Code:
void drive_OW_high (void) 
{ 
  OW_PIN_DIRECTION = INPUT; 
}
There are other problems with the code but as long as you drive the line high with the uC you will never read anything but 0xFF,

I would expect to see OWTouch(). Maybe take another look at the datasheet.

It would be real good if you could look at what is happening on the pin. If you have a logic analyzer or a PICkit2 take a look at what you OW line is doing. Up to the point where you expect input you can view OW in the simulator LA.

EDIT: There are some cases where OW devices need more current then the weak pull up can deliver. An example of this is when the DS18S20 does its temperature conversion. If your device has a similar need you would want to drive the OW line high. But only for the period when the extra current is required. Or provide a power wire instead of using parasitic power.
 
Last edited:
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top