0
\$\begingroup\$

I've been googling for about two weeks now and I still can't seem to get my I2C working. I've used this (what seems to be complete) tutorial. I followed the Master Write and Master Read examples to try and read from my sensor. I've referenced the I2C_MASTER.zip and I2C_SLAVE.zip from the Microchip site, and my I2C still does not work. Can I get some tips?

More information:

  • SDA, SCL hooked up to PIC18F's SDA1/SCL1, configured for open-drain and wired to supply voltage
  • Tried different approaches with IdleI2C1() and EEAckPolling1(address) with no progress
  • Followed the Microchip example of checking the collision bit, but still doesn't work
  • Using i2c.h from the XC8 Compiler
  • SSP1ADD is set to 19, but maybe it's not right? I have my clock running at 8 Mhz with the internal oscillator, and got that value using Fclock = Fosc / (( SSPxADD + 1 ) * 4), where Fclock is 100 kHz and Fosc is 8 Mhz
  • I do not have an oscilloscope to view signals

Does anyone know of any libraries I can easily use for reading and writing without worrying about Ack/Nack signals?

Here's the relevant code:

void init()
{
    CloseI2C1();
    OpenI2C1(MASTER,SLEW_OFF);
    SSP1ADD = 19;

    getEEPROM();
}

void getEEPROM()
{
    static signed char status,data;
    IdleI2C1();
    StartI2C1();
    while(SSPCON2bits.SEN);
    do{
        status = WriteI2C1(MLX_EEPROM_WRITE);// Signal to EEPROM start point
        if(status == -1)
        {
            data = SSPBUF;
            SSPCON1bits.WCOL = 0;
        }
    }while(status!=0);
    IdleI2C1();
    do{
        status = WriteI2C1(0x00);// Signal to EEPROM start point
        if(status == -1)
        {
            data = SSPBUF;
            SSPCON1bits.WCOL = 0;
        }
    }while(status!=0);
    IdleI2C1();
    RestartI2C(); 
    do{
        status = WriteI2C1(MLX_EEPROM_READ);// Signal to EEPROM start point
        if(status == -1)
        {
            data = SSPBUF;
            SSPCON1bits.WCOL = 0;
        }
    }while(status!=0);
    IdleI2C1();
    getsI2C1(eepromData,255);
    /* // supposed to be the same as getsI2C1
    for(i = 0; i < 256; i++)
    {
        eepromData[i] = ReadI2C1();
        IdleI2C1();
    }
   */
    NotAckI2C();
    while ( SSPCON2bits.ACKEN );
    StopI2C();
    while ( SSPCON2bits.PEN );
}
\$\endgroup\$
  • \$\begingroup\$ "SDA, SCL hooked up to PIC18F's SDA1/SCL1, configured for open-drain and wired to supply voltage." Are you wiring these directly to the supply voltage, or are you using pullup resistors? If it's direct, those pins have probably been damaged. \$\endgroup\$ – bitsmack Apr 10 '14 at 6:49
1
\$\begingroup\$

Start simple, see if you can get an ack from the device, the proceed further. Here is some working code from a pic18f87j50.

void InitEEprom(void) {
    TRISDbits.TRISD6 = 0;
    TRISDbits.TRISD5 = 1;
    OpenI2C2(MASTER, SLEW_OFF);
    SSP2ADD = 0x36;
}

int FindDevice(unsigned char Control) {
    unsigned int ErrorCode;
    IdleI2C2(); //Ensure Module is Idle
    StartI2C2(); //Generate Start COndition
    SSP2BUF = Control;
    //WriteI2C2(Control); //Write Control byte
    IdleI2C2();
    ErrorCode = ACKStatus();
    StopI2C2();
    return ErrorCode; //Return ACK Status
}
\$\endgroup\$
  • \$\begingroup\$ And who knows why they had to go and combine spi and i2c on these chips!? \$\endgroup\$ – Erik Friesen Apr 9 '14 at 20:08
  • \$\begingroup\$ What is ACKStatus? \$\endgroup\$ – WayneDinh Apr 11 '14 at 22:44
  • \$\begingroup\$ It is the ack from the device from the last byte sent. \$\endgroup\$ – Erik Friesen Apr 12 '14 at 11:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.