The problem about I2C communication
Ann
Posts: 9
I want to realize to read three axis data of gyro by using Activity Board. The Example is shown as following.
Example: The I2C address of gyro is 105. The I2C addresses of gyro register which send data is 0x20 and the data is 0x1f. The address of register which receive data from I2C bus is 0X2B and the data would be saved in MSB. However, I cant read any data. Is there any mistakes in my program? Hope sb could slove it.
The following is completed code.
Example: The I2C address of gyro is 105. The I2C addresses of gyro register which send data is 0x20 and the data is 0x1f. The address of register which receive data from I2C bus is 0X2B and the data would be saved in MSB. However, I cant read any data. Is there any mistakes in my program? Hope sb could slove it.
The following is completed code.
#include "simpletools.h" // Include simpletools header
#include "simplei2c.h"
#define CTRL_REG1 0x20
#define CTRL_REG2 0x21
#define CTRL_REG3 0x22
#define CTRL_REG4 0x23
int main() // Main function
{
int x, y, z; // Declare x, y, & z axis variables
pause(1000);
int Addr = 105; // I2C address of gyro
i2c *bus = i2c_newbus(3, 2, 0); // New I2C bus SCL=P3, SDA=P2
i2c_out(bus,Addr,CTRL_REG1,16,0x1f,16); //open all axis
i2c_out(bus,Addr,CTRL_REG3,16,0x08,16); //Enable control ready signal
i2c_out(bus,Addr,CTRL_REG4,16,0x80,16); //Set scale (500 deg/sec)
pause(100);
while(1) // Repeat indefinitely
{
print("%c", HOME);
int MSB;
int LSB;
i2c_in(bus,Addr,0x29,8,MSB,8);
i2c_in(bus,Addr,0x28,8,LSB,8);
x = ((MSB << 8) | LSB);
i2c_in(bus,Addr,0x2B,8,MSB,8);
i2c_in(bus,Addr,0x2A,8,LSB,8);
y = ((MSB << 8) | LSB);
i2c_in(bus,Addr,0x2D,8,MSB,8);
i2c_in(bus,Addr,0x2C,8,LSB,8);
z = ((MSB << 8) | LSB);
print("\nx=%d, y=%d, z=%d%c\n", x, y, z, CLREOL); //Display raw compass values
waitcnt(CLKFREQ/2+CNT);
}
}
#include "simplei2c.h"
#define CTRL_REG1 0x20
#define CTRL_REG2 0x21
#define CTRL_REG3 0x22
#define CTRL_REG4 0x23
int main() // Main function
{
int x, y, z; // Declare x, y, & z axis variables
pause(1000);
int Addr = 105; // I2C address of gyro
i2c *bus = i2c_newbus(3, 2, 0); // New I2C bus SCL=P3, SDA=P2
i2c_out(bus,Addr,CTRL_REG1,16,0x1f,16); //open all axis
i2c_out(bus,Addr,CTRL_REG3,16,0x08,16); //Enable control ready signal
i2c_out(bus,Addr,CTRL_REG4,16,0x80,16); //Set scale (500 deg/sec)
pause(100);
while(1) // Repeat indefinitely
{
print("%c", HOME);
int MSB;
int LSB;
i2c_in(bus,Addr,0x29,8,MSB,8);
i2c_in(bus,Addr,0x28,8,LSB,8);
x = ((MSB << 8) | LSB);
i2c_in(bus,Addr,0x2B,8,MSB,8);
i2c_in(bus,Addr,0x2A,8,LSB,8);
y = ((MSB << 8) | LSB);
i2c_in(bus,Addr,0x2D,8,MSB,8);
i2c_in(bus,Addr,0x2C,8,LSB,8);
z = ((MSB << 8) | LSB);
print("\nx=%d, y=%d, z=%d%c\n", x, y, z, CLREOL); //Display raw compass values
waitcnt(CLKFREQ/2+CNT);
}
}
Comments
Normally, address is the upper 7 bits of the byte, and the last bit is reserved for read/write. 105d is 1101001b, so it looks like might want to shift that left one place and add in a r/w bit.
On a slightly related note I have a L3GD20 driver here that can serve as inspiration (it uses C++ and a different I2C system, but the higher level protocol is the same).
byte MSB, LSB;
MSB = readI2C(0x29);
LSB = readI2C(0x28);
x = ((MSB << 8) | LSB);
MSB = readI2C(0x2B);
LSB = readI2C(0x2A);
y = ((MSB << 8) | LSB);
MSB = readI2C(0x2D);
LSB = readI2C(0x2C);
z = ((MSB << 8) | LSB);
How to port this program to used on Activity Board?And the gyro is L3G4200D.
The documentation function descriptions say this about the I2C address:
i2cAddr 8 bit device address. This is the 7-bit I2C address and read/write bit.
To me, this is an opportunity for improvement and should say:
i2cAddr 8 bit device address. This is the 7-bit I2C address on bits 7..1 and the read/write bit on bit 0.
What it means is the I2C address used in the functions is a left shift by 1 address. Other systems use the address as stated in the data sheet. For example an EEPROM address is 0x50. In the Parallax world that address gets translated by the programmer to 0xA0 (0x50 left shift by 1).
The top level documentation is the key to understanding simple libraries. It provides a navigation point to find all library docs.
In my installation, the documentation starts at Documents\SimpleIDE\Learn\Simple Libraries Index.html
For example: file:///C:/Users/Steve/Documents/SimpleIDE/Learn/Simple Libraries Index.html
Simple Libraries
https://propsideworkspace.googlecode.com/hg/Learn/Simple Libraries Index.html
i2c_in
https://propsideworkspace.googlecode.com/hg/Learn/Simple Libraries/Utility/libsimpletools/html/simpletools_8h.html#a3716fa497e2d94ab9ab80c30b3109480
i2c_out
https://propsideworkspace.googlecode.com/hg/Learn/Simple Libraries/Utility/libsimpletools/html/simpletools_8h.html#a8e388b4d227694772970f0ee51ad2c31
The ee_writeBuffer and ee_readBuffer functions show how to write basic read/write code.
There are simpler ways to do this, but I wanted it to be complete, useful, and non-destructive.
--Steve
Alright, we'll use i2c_in and i2c_out. First step would be to make sure the device can reply with its own ID with i2c_in. Please run this and let me know if you get the "Device ID confirmed..." message.