This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

I2C Read Problem

Hello,
I am trying to write a Set of Bit Bang I2C Functions to communicate with a SRF08 Range Finder. I found some code by Grant Beattie for the HC11 and have addapted it for the 89LPC932. Now I have the Start, stop, and Write Byte functions working, but the Read function is not working. I have the suggested pull-up resistors and when I run the code the value outputs 255 meaning the data line never falls. This is my code please help.

unsigned char I2cRead(unsigned char count)
{
unsigned char mask;
unsigned char value;
unsigned char index = 0;

while(count)
   {
   mask  = 0x80;
   value = 0x00;
   while(mask)      // Do the 8 data bits...
      {

      SclHi();       // Set SCL
                  //and wait for it to go hi.

     I2cDelay();

      if( GetSda() ) // Read the bit
         value |= mask; // the returned byte.

      SclLo();  // Bring SCL low again
      I2cDelay();
      mask >>= 1;
      }

  Readvalue = value;   // Save the read byte.

   index++;
   count--;
   if(count) // If not the last byte, ACK
      {
      SdaLo();      // Bring SDA low for ACK.
      SclHi();      // Clock high.
      I2cDelay();
      SclLo();      // Clock low.
      SdaHi();      // Release SDA.
      I2cDelay();
      }
   }

SdaHi();   // SDA high for NACK on last byte.
SclHi();       // Clock high.
I2cDelay();
SclLo();       // Clock low.
I2cDelay();

return 0;
} 

Parents Reply Children
  • I could not get the internal interrupt to work.
    You probably do not have it enabled.
    If you have done this succesfully I would like to see your code.
    Use codearchitect and you will see what I have.

    There are some 'small pieces' that are easy to 'forget' or 'kill'
    a) the initializizations must be called
    b) the pin config settings should not be overwritten later (I goofed on that one)
    c) the interrupt enable bits should not be overwritten later.

    Check the above.

    Erik

    Erik

  • Hey Eric,
    I am trying to use the Code architect code. Is this the way you would use the functions. I send a transmit and try to wait for the interrupt to take care of the rest. I have set EI2C =1 and EA =1 in my i2c_init, which I call.

    int read_SRF08(int device, int reg)
    {
    	unsigned char databyte;
    
    	 i2c_transmit(SRF08_1);
    	 printf("\ninto the i2cok loop %d\n",SI);
    	 while (i2c_getstatus() & I2C_BUSY) printf("\nSI=%d\n",SI);
    
    	 printf("out of the i2cok loop\n");
     		//databyte=i2c_recieve();
    	return databyte;
     }

  • I am trying to use the Code architect code. Is this the way you would use the functions. I send a transmit and try to wait for the interrupt to take care of the rest. I have set EI2C =1 and EA =1 in my i2c_init, which I call.

  • in my i2c_init
    There is an IICinit in the codearchitect, make sure nothing (eg pin configurations) is lost from there. Also, do you have pullup resisttors on the two lines?

    Erik

  • Pin Configs are OK and I have 1.5k pull ups.

  • Hey Erik,
    Looks Like it was a bad Emulator the SCL pin was always high. Put in a New Emulator and it is starting to work. I think It is good now. Thank You for all of your help.

    Kenny

  • One more question if you are still there Erik. I have the code architect functions working in that they go to all of the correct interrupts, but I do not receive any data back from case 58: my I2Dat value is always zero. Just wondering if you have seen this before. This is my Init routine.

    void i2c_init(
      unsigned char address,  // The 7-bit I2C address to use
      bit generalcall         // 1 = respond to general call, 0 = ignore
                              // general call
      )
    {
      // set pins to open-drain
      P1M1 |= 0x0C;
      P1M2 |= 0x0C;
    
      // configure I2C address
      I2ADR = 0x00;
      //I2ADR = address << 1;
      //if (generalcall)
      //{
      //  I2ADR |= 0x01;
      //} // if
    
      // configure internal SCL generator
      //Page 79 of the user manual gives these values for close to 400Kbit/S
      //SCLH (SCL Duty Cycle Register High Byte)
      I2SCLH =0x08;
      //SCLL (SCL Duty Cycle Reister Low Byte)
      I2SCLL =0x07;
    
      // configure I2C interface
      // use internal SCL generator
      I2CON = 0x44;
    
      // set interrupt priority to 0
      IP1 &= ~0x01;
      IP1H &= ~0x01;
    
      // initial status
      mi2cstatus = I2C_IDLE;
    
      // enable interrupt
    
      EI2C = 1;
      EA=1;
    } // i2c_init
    

  • but I do not receive any data back from case 58:

        // no ACK for data byte
        case 0x58

    why would you, if the other and does not ACK, how would the byte be there

    Erik