No output from I2C

Discussion in 'Embedded Systems and Microcontrollers' started by spinnaker, Feb 13, 2015.

  1. spinnaker

    Thread Starter AAC Fanatic!

    Oct 29, 2009
    4,886
    1,010
    I am trying to get I2C working for the first time. I am using XC8 and the peripheral library.

    My chip is the pic18f26k22. I have pines 14 - I2C clock and pin 15 - I2C data tied high via a 10K pullup.

    I tried the following code
    Code (Text):
    1.  
    2.   ANSELC = 0;  
    3.   OpenI2C1(MASTER,SLEW_OFF);
    4.   SSP1ADD = 0x09;
    5.   while (1)
    6.   {
    7.       WriteI2C1(255);  
    8.       i = 1;
    9.   }
    10.  
    but get no output on either pin. All I see is the +5V from the pullup. No transitions .

    Is there something else that I am missing?

    Do I need an active slave to see output from the master???
     
    Last edited: Feb 13, 2015
  2. shteii01

    AAC Fanatic!

    Feb 19, 2010
    3,392
    497
    0x09 is the device address?
     
  3. spinnaker

    Thread Starter AAC Fanatic!

    Oct 29, 2009
    4,886
    1,010
    0x0A. But no device currently connected. I just want to see an output from the pic. I am thinking my pull up might be too high resistance? Going to try that next.
     
  4. ErnieM

    AAC Fanatic!

    Apr 24, 2011
    7,388
    1,605
    A larger resistor is even easier to pull down. It is not the problem.

    I2C is more complicated then just writing a byte to the bus. Unfortunately the Doc-O-Matic help file does not contain the examples you will need to work out what steps the library need to open the module and perform transactions.

    You need to find these as it's a code problem and not hardware.
     
  5. JohnInTX

    Moderator

    Jun 26, 2012
    2,346
    1,028
    10K is fine for now, 4.7K is typical. The actual value depends on bus speed vs. loading etc.
    You don't need an active slave to see output from the master.

    What you are missing is that I2C has a protocol that is enforced by the MSSP state machine. You can't just send a byte to the port. After proper configuration (IO ports, bus frequency, master-mode, enable I2C etc) you have to conform to the I2C protocol to get anything out of the port. To send a byte to wiggle SDA/SCL with no slave on the bus you have to:

    Enable I2C
    Verify that the bus is idle
    Send a Start condition
    Send the slave address
    Test for NAK - no slave means NAK so that's what you'll get for now.
    Send stoP condition to terminate the transaction. This is necessary to reset the I2C state machine to the idle state. It also expected by the addressed slave to reset its state machine to look for the next Start condition.

    The examples in the XC8 Peripheral Libraries sec 8.10.3 show what you have to do for a minimal implementation.

    Doc-O-Matic - I thought ErnieM was kidding...

    Good Luck.
     
  6. spinnaker

    Thread Starter AAC Fanatic!

    Oct 29, 2009
    4,886
    1,010
    What happens on the bus when sending a "Start Condition" ? Should I see clock or something?

    What happens if my slave is not responding? Should I still see something out of the master?
     
  7. JohnInTX

    Moderator

    Jun 26, 2012
    2,346
    1,028
    An IDLE condition is defined as both SCL and SDA high (after a stoP). A Start condition is defined as SDA dropping followed by SCL. A stoP condition is defined as SCL going high followed by SDA. Since data transitions on SDA are allowed only when SCL is low, these two conditions are unique and have specially defined meanings.

    So the answer to your question is yes, you should see the Start followed by some SCL clocking out the slave address on SDA.

    All of this and more is described in the I2C spec attached.

    Also attached is an old scope shot showing SCL on CH1 and SDA on CH2 (don't know what 3 and 4 are). You can see the Start at the left followed by 7 SCL clocking out the 7bit address 0001001. The 8th SCL clocks a low which tells the slave that the master is WRITING to it. The 9th clock clocks IN a low (the master releases SDA for one clock) - that's the slave ACKing its address by pulling SDA low. The master knows there is a slave there and continues clocking out the next byte 01010001 on the next 8 SCL. Again, on the 9th SCL, the slave ACKs by pulling SDA low. As the traces exit the screen on the right, you can see why a Beagle analyser comes in handy. My scope has a large memory but it gets to be a beating scrolling through long I2C sequences.
     
    Last edited: Feb 14, 2015
  8. ErnieM

    AAC Fanatic!

    Apr 24, 2011
    7,388
    1,605
    Just to see something you might want to try putting StartI2C1() and StopI2C1() into a small loop to see the bus wiggle.
     
  9. spinnaker

    Thread Starter AAC Fanatic!

    Oct 29, 2009
    4,886
    1,010
    Got it working, Finally thanks. Was even able to get a response from my chip and was able to see the exchange of data with my logic analyzer.
     
Loading...