« Close

Datasheets and User Guides

App Notes

Software & Driver

 

4.3.11 - I²C Serial Communication

The U3 (hardware version 1.21+ only) supports Inter-Integrated Circuit (I²C or I2C) communication as the master only. I²C is a synchronous serial protocol typically used to communicate with chips that support I²C as slave devices. Any 2 digital I/O lines are used for SDA and SCL. Note that the I²C bus generally requires pull-up resistors of perhaps 4.7 kΩ from SDA to Vs and SCL to Vs, and also note that the screw terminals labeled SDA and SCL (if present) are not used for I²C.

This serial link is not an alternative to the USB connection. Rather, the host application will write/read data to/from the U3 over USB, and the U3 communicates with some other device using the serial protocol. Using this serial protocol is considered an advanced topic. A good knowledge of the protocol is recommended, and a logic analyzer or oscilloscope might be needed for troubleshooting.

There is one IOType used to write/read I²C data:


LJ_ioI2C_COMMUNICATION

The following are special channels used with the I²C IOType above:


LJ_chI2C_READ      // Value= number of bytes (0-52). x1= array.
LJ_chI2C_WRITE     // Value= number of bytes (0-50). x1= array.
LJ_chI2C_GET_ACKS

The following are special channels, used with the get/put config IOTypes, to configure various parameters related to the I²C bus. See the low-level function description in Section 5.2.19 for more information about these parameters:


LJ_chI2C_ADDRESS_BYTE
LJ_chI2C_SCL_PIN_NUM   // 0-19. Pull-up resistor usually required.
LJ_chI2C_SDA_PIN_NUM   // 0-19. Pull-up resistor usually required.
LJ_chI2C_OPTIONS
LJ_chI2C_SPEED_ADJUST

The LJTick-DAC is an accessory from LabJack with an I²C 24C01C EEPROM chip. Following is example pseudocode to configure I²C to talk to that chip:


//The AddressByte of the EEPROM on the LJTick-DAC is 0xA0 or decimal 160.
AddRequest(lngHandle, LJ_ioPUT_CONFIG, LJ_chI2C_ADDRESS_BYTE,160,0,0);

//SCL is FIO0
AddRequest(lngHandle, LJ_ioPUT_CONFIG, LJ_chI2C_SCL_PIN_NUM,0,0,0);

//SDA is FIO1
AddRequest(lngHandle, LJ_ioPUT_CONFIG, LJ_chI2C_SDA_PIN_NUM,1,0,0);

//See description of low-level I2C function.
AddRequest(lngHandle, LJ_ioPUT_CONFIG, LJ_chI2C_OPTIONS,0,0,0);

//See description of low-level I2C function.  0 is max speed of about 150 kHz.
AddRequest(lngHandle, LJ_ioPUT_CONFIG, LJ_chI2C_SPEED_ADJUST,0,0,0);

//Execute the configuration requests.
GoOne(lngHandle);

Following is pseudocode to read 4 bytes from the EEPROM:


//Initial read of EEPROM bytes 0-3 in the user memory area.
//We need a single I2C transmission that writes the address and then reads
//the data.  That is, there needs to be an ack after writing the address,
//not a stop condition.  To accomplish this, we use Add/Go/Get to combine
//the write and read into a single low-level call.
numWrite = 1;
array[0] = 0;  //Memory address.  User area is 0-63.
AddRequestPtr(lngHandle, LJ_ioI2C_COMMUNICATION, LJ_chI2C_WRITE, numWrite, array, 0);

numRead = 4;
AddRequestPtr(lngHandle, LJ_ioI2C_COMMUNICATION, LJ_chI2C_READ, numRead, array, 0);

//Execute the requests.
GoOne(lngHandle);

For more example code, see the I2C.cpp example in the VC6_LJUD archive.