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.

I2C write problem with PIC18 microcontroller and ADC slave

Status
Not open for further replies.

diogenes500

New Member
Hello,

I’m having a strange problem concerning the writing of I2C bytes by a PIC18 microcontroller master to a slave. Using the C18 peripherals library ( “i2c.h”, which seems to be the same for either XC8 or C18 compilers) I can write the first byte just fine, from which I think I get an acknowledgement if it is the slave address, but all bytes after that are related to the first written byte. They often appear to be some shifted version of the first byte. If I issue a RestartI2C() command between each byte then the bytes are correct and independent but the slave, understandably, doesn't seem to like this/doesn't respond correctly. The follow code is a stripped down version of what should be the initializing sequence for the device. The image is the subsequent SDA (CH1) and SCK (CH2) signals. As you can see, the first byte seems fine, but the following ones simply are not what I’m trying to write.

I've tried numerous variations of using idle, restart, ack, etc, and nothing seems to work. Any help would be appreciated, I've spent an embarrassing number of hours trying to make this work/searching online for answers.


Hardware/compiler:
Master = PIC18f2525 , Slave = NAU7802 ADC.
I’ve tried both XC8 and C18 compilers (same peripheral library)


Code:
//#include <p18f2525.h>
#include <xc.h>
#include <plib.h>
#include "i2c.h"
#include <delays.h>


#pragma config OSC = INTIO67
#pragma config WDT = OFF //Disable watchdog timer
#pragma config LVP = OFF //Disable Low Voltage Programming
#pragma config MCLRE = OFF//

#define _XTAL_FREQ 8000000
#define FREQ 8000000

unsigned char sync_mode = 0, slew = 0, add1, add2, w, data, status, length;

//************ I2C MASTER ****************************

void main(void) {

    //run at 8 MHz
    OSCCONbits.IRCF2 = 1;
    OSCCONbits.IRCF1 = 1;
    OSCCONbits.IRCF0 = 1;

    add1 = 0b01010100; //address + write
    add2 = 0b01010101; //address + read

//    sync_mode = MASTER;
//    slew = SLEW_OFF;
//    OpenI2C(sync_mode, slew);
    OpenI2C(MASTER, SLEW_OFF);
    SSPADD = 0x31; //with clock at 8 MHZ, this should put I2C clock at 50 kHz.
   
    __delay_ms(1);

    //---START I2C---
        StartI2C();

        //start up sequence for NAU7802 (ADC + amplifier)
        status = WriteI2C(add1);
        IdleI2C();
        AckI2C();

        //RestartI2C();

        status = WriteI2C(0x00);
        IdleI2C();
        AckI2C();

        //RestartI2C();

        status = WriteI2C(0x06);
        IdleI2C();
        AckI2C();
    
        //RestartI2C();
    
        status = WriteI2C(add1);
        IdleI2C();
        AckI2C();

        //RestartI2C();
        status = WriteI2C(0x00);
        IdleI2C();
        AckI2C();
        
        //RestartI2C();

        status = ReadI2C();
        IdleI2C();
        AckI2C(); //possibly NotAckI2C(); ? 
    
        StopI2C();

        while(1);

}
 

Attachments

  • Trace.jpg
    Trace.jpg
    236 KB · Views: 483
Yeah, I wasn't quite sure what you meant, and a quick search didn't illuminate anything. At a quick glance, does anything seem obviously wrong? This half-working (first write byte fine) seems like a strange error.
 
Hi,

I just tested your code (sending the first three bytes). At first the data was rubbish - like yours. Then I removed the ACKs - because they are not required when master is sending.

Now the data looks fine on the scope (first three bytes anyway).

**broken link removed**

Code:
/*  23:46 28 April 2013
*
*   E:\Electronics\PIC Projects\Electrotech\Z_test sw i2c\Source Files\Test Main.c
*
*   xc8 v1.12
*
*   PIC18F2420
*
*   
*
*/

#include <xc.h>
#include "i2c.h"

/*------------------------------------------------------------------------*/

#pragma config OSC = INTIO67
#pragma config WDT = OFF //Disable watchdog timer
#pragma config LVP = OFF //Disable Low Voltage Programming
#pragma config MCLRE = OFF//
 
#define I2C (V4)
#define I2CIO (V1)

unsigned char sync_mode = 0, slew = 0, add1, add2, w, data, status, length;

/*------------------------------------------------------------------------*/

#define _XTAL_FREQ (8000000)

/*------------------------------------------------------------------------*/

void main (void)
{
    OSCCON = 0b01110010;            // Fosc = 8MHz
    ADCON1 = 0xF;                   // No analog, all digital i/o
    TRISC = 0x0;
    LATC = 0x0;

    add1 = 0b01010100; //address + write
    add2 = 0b01010101; //address + read

    OpenI2C(MASTER, SLEW_OFF);
    SSPADD = 0x31; //with clock at 8 MHZ, this should put I2C clock at 50 kHz.
    
while(1)
{
    __delay_ms(50);         // Degug delays
    __delay_ms(50);
    __delay_ms(50);
    __delay_ms(50);
    __delay_ms(50);

    StartI2C();
    WriteI2C(0b01010100);   // address
    IdleI2C();
    StopI2C();

    StartI2C(); 
    WriteI2C(0x00);
    IdleI2C();
    //AckI2C(); Slave ackowledges when master sends.
    
    WriteI2C(0b00000110);
    IdleI2C();
    //AckI2C(); Slave ackowledges when master sends.

    StopI2C();

    while(1);

    }
 }
 
Last edited:
Thanks! That worked like a charm, I don't know why I didn't try that. I appreciate you checking that it worked. This should get me on my way to being able to properly communicate with the slave device.
 
Status
Not open for further replies.

Latest threads

Back
Top