i2c not working

Discussion in 'Embedded Systems and Microcontrollers' started by kingsloth, Dec 28, 2015.

  1. kingsloth

    Thread Starter New Member

    Dec 28, 2015
    12
    0
    i'm trying to read values with the following routine

    Code (C):
    1.  
    2. void read()
    3. {
    4.   unsigned int lsb = 0;
    5.   unsigned char msb = 0;
    6.   char str[20];
    7.  
    8.   if (I2CBusIsIdle(I2C1))
    9.   {
    10.   I2CStart(I2C1);
    11.   }
    12.  
    13.   I2CSendByte(I2C1, REG_WRITE);
    14.   IdleI2C1();
    15.   I2CSendByte(I2C1, DATA_OUTPUT_X);
    16.   IdleI2C1();
    17.   I2CRepeatStart(I2C1);
    18.   IdleI2C1();
    19.   I2CSendByte(I2C1,REG_READ);
    20.   IdleI2C1();
    21.  
    22.   I2CReceiverEnable(I2C1, TRUE);
    23.  
    24.   if (I2CReceivedDataIsAvailable(I2C1))
    25.   {
    26.   I2CAcknowledgeByte(I2C1, TRUE);
    27.   msb = I2CGetByte(I2C1);
    28.   }
    29.   IdleI2C1();
    30.   I2CReceiverEnable(I2C1, TRUE);
    31.   IdleI2C1();
    32.  
    33.   if (I2CReceivedDataIsAvailable(I2C1))
    34.   {
    35.   I2CAcknowledgeByte(I2C1, TRUE);
    36.   lsb = I2CGetByte(I2C1);
    37.   }
    38.   IdleI2C1();
    39.   X_axis=((msb<<8) | lsb);
    40.   I2CReceiverEnable(I2C1, TRUE);
    41.   IdleI2C1();
    42.  
    43.   if (I2CReceivedDataIsAvailable(I2C1))
    44.   {
    45.   I2CAcknowledgeByte(I2C1, TRUE);
    46.   msb = I2CGetByte(I2C1);
    47.   }
    48.   IdleI2C1();
    49.   I2CReceiverEnable(I2C1, TRUE);
    50.   IdleI2C1();
    51.  
    52.   if (I2CReceivedDataIsAvailable(I2C1))
    53.   {
    54.   I2CAcknowledgeByte(I2C1, TRUE);
    55.   lsb = I2CGetByte(I2C1);
    56.   }
    57.   IdleI2C1();
    58.   Z_axis=((msb<<8) | lsb);
    59.   I2CReceiverEnable(I2C1, TRUE);
    60.   IdleI2C1();
    61.  
    62.  
    63.   if (I2CReceivedDataIsAvailable(I2C1))
    64.   {
    65.   I2CAcknowledgeByte(I2C1, TRUE);
    66.   msb = I2CGetByte(I2C1);
    67.   }
    68.   IdleI2C1();
    69.   I2CReceiverEnable(I2C1, TRUE);
    70.   IdleI2C1();
    71.  
    72.   if (I2CReceivedDataIsAvailable(I2C1))
    73.   {
    74.   I2CAcknowledgeByte(I2C1, FALSE);
    75.   lsb = I2CGetByte(I2C1);
    76.   }
    77.   IdleI2C1();
    78.   Y_axis=((msb<<8) | lsb);
    79.  
    80.  
    81.   I2CStop(I2C1);
    82.  
    83. }
    84.  
    I always get 0.0, what am i doing wrong? I have SDA on pin RG3 and SCL on RG2, both with a resistence of 4k7 to 3.3V.

    Moderators note : used code tags for C
     
    Last edited: Jan 2, 2016
  2. sailorjoe

    Member

    Jun 4, 2013
    361
    63
    What i2c library are you using, please?
    Since I don't have the library information, I'm just guessing here. At line 24, consider what happens if no data is available. Does the i2c function I2CReceivedDataIsAvailable() wait for data, or return false if data hasn't arrived yet?
     
  3. spinnaker

    AAC Fanatic!

    Oct 29, 2009
    4,887
    1,016
    Have you scoped the output of the mcu to see if you are even putting out data?
     
  4. kingsloth

    Thread Starter New Member

    Dec 28, 2015
    12
    0
    It only returns true or false.
     
    Last edited: Jan 2, 2016
  5. kingsloth

    Thread Starter New Member

    Dec 28, 2015
    12
    0
    This is the only thing i get, ch1 - SCL ch2- SDA.
     
  6. RRITESH KAKKAR

    Senior Member

    Jun 29, 2010
    2,831
    89
    From where you got the library for MPlab
     
  7. kingsloth

    Thread Starter New Member

    Dec 28, 2015
    12
    0
    don't know if i'm doing it right or not but i just pressed F1 (help) and there was a bunch of routines to use i2c, i just read them and use them. It compiled so i thought i was doing good. I'm trying to re-write the code making my own i2c functions, maybe it will work...
     
  8. RRITESH KAKKAR

    Senior Member

    Jun 29, 2010
    2,831
    89
    Is that your Oscilloscope?
    With it help you can do easily.
    I have done but the code was not mine.
     
  9. spinnaker

    AAC Fanatic!

    Oct 29, 2009
    4,887
    1,016

    MPLabX is not a compiler it is a development enviroment.. What compiler are you using? It isn't XC8 because the documentation does not match your calls unless you are using your own wrapper around the XC8 calls. So which is it?
     
  10. spinnaker

    AAC Fanatic!

    Oct 29, 2009
    4,887
    1,016
    This is good. At least something is coming out. Can you see if you are getting a response from the slave? You don't happen to have a logic analyzer? They can be a huge hel in situations like this.

    Next thing to check after that is all of your settings are the way you need them
     
  11. RRITESH KAKKAR

    Senior Member

    Jun 29, 2010
    2,831
    89
    May be compiler Hi Tech C
     
  12. ErnieM

    AAC Fanatic!

    Apr 24, 2011
    7,394
    1,606
    The scope picture looks perfect for the address to write to this device, and since the 9th bit is zero the slave is acknowledging it is being addressed. Doesn't get any better than that.

    The next step is to grab an entire write sequence and then the read sequence. See if things keep jetting that nice ACK bit set. And don't forget when reading multiple bytes your master pic must do the ACK, your lib has that function.

    Getting these low level transactions to all play together is a major piece of my debugging time. The good news is you have a scope as a reality check.

    I would strongly suggest you find some example code on the interwebs where someone shows the sequence that worked for them to bang this device. I am not sure how I would do it after peeking at the operational examples of the device data sheet.
     
  13. spinnaker

    AAC Fanatic!

    Oct 29, 2009
    4,887
    1,016
    Wow that is where experience pays off! :)


    The XC8 manual has examples. But as I mention this is not XC8 unless is it is a wrapper. What confuses me id there is no configuration in the code as posted.
     
  14. kingsloth

    Thread Starter New Member

    Dec 28, 2015
    12
    0
    I'm using XC32
     
  15. dannyf

    Well-Known Member

    Sep 13, 2015
    1,828
    364
    You didn't read the PLIB manual / example code.
     
  16. kingsloth

    Thread Starter New Member

    Dec 28, 2015
    12
    0
    Thing is the only thing i got from the scope was that, nothing more, so probably it's only writing to device, never reads it
     
  17. spinnaker

    AAC Fanatic!

    Oct 29, 2009
    4,887
    1,016

    I cannot imagine the xc32 peripheral library calls are that much different than XC8. If they are similar then what you posted is not from the perphial library.
     
  18. ErnieM

    AAC Fanatic!

    Apr 24, 2011
    7,394
    1,606
    Oh bleep, spinnaker talks me up then I have to take it back.

    Most of the transmission looks ok, but the address should begin with a START transaction, which is SCL hi while SDA goes low. If you only see this pattern over and over the sequence never sends a STOP signal.

    I am typing on a silly iPad and can't copy and paste code. If I was doing this I would forget all that code you have and begin with a simple config command, which btw I do not see in your code, do you initial the device?

    One trick is to use a spare I/O pin as a flag, set it hi when you start a transaction and set lo when done. This gives you a solid signal to trigger your (very nice) scope.
     
  19. kingsloth

    Thread Starter New Member

    Dec 28, 2015
    12
    0

    yeah im doing:

    I2CSetFrequency(I2C1, FPB, FSCK); // it gives 100kHz, thats right
    I2CEnable(I2C1, TRUE);

    To me looks like the problem is I2CStop(I2C1) isn't working, dont know how to solve it though.
     
  20. ErnieM

    AAC Fanatic!

    Apr 24, 2011
    7,394
    1,606
    Without more of your code no one could tell what that statement could possibly mean, though I do hope you enable the I2C before you attempt to use it.
     
Loading...