700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > linux下i2c与pca9555通信 pca9555(i2c-gpio扩展)应用层测试代码

linux下i2c与pca9555通信 pca9555(i2c-gpio扩展)应用层测试代码

时间:2019-04-02 10:33:56

相关推荐

linux下i2c与pca9555通信 pca9555(i2c-gpio扩展)应用层测试代码

/aaronLinux/p/6896573.html

注意点:

如果在设置I2C_SLAVE的时候,提示device_busy,可以使用I2C_SLAVE_FORCE, 在驱动里面二者对应同一个case语句

应用层可以调用接口:i2c_smbus_write_word_data(fd, __, __);和i2c_smbus_read_word_data(fd,__);

分享:

问题如下:

1. 应用程序中直接fd句柄是整个I2C0总线的文件句柄,而只是在set地址的时候,将I2C address设置下去,后面操作该芯片还是操作全局I2C0总线上这个文件,并没有指定去操作该芯片,这其中是怎么做到的?这样的话,如果在一个main程序中, 操作同一总线上不同i2c设备,而文件句柄是同一个,这要如何操作?

--------------------------------------------------------------------------------------------

驱动方面:

首先配置I2C内核驱动,将pca9555的源码built-in进入(这里根据需要可能要配thermal的驱动),然后在devicetree中根据pca9555硬件I2C地址配置节点。

测试源码:

//I2C test program for a PCA9555

#include

#include

#include

#include

#include

#include

#include

#include

#include

//I2C Linux device handle

int g_i2cFile;

//open the Linux device

void i2cOpen()

{

g_i2cFile = open("/dev/i2c-0", O_RDWR);

if (g_i2cFile < 0) {

perror("i2cOpen");

exit(1);

}

}

//close the Linux device

void i2cClose()

{

close(g_i2cFile);

}

//set the I2C slave address for all subsequent I2C device transfers

void i2cSetAddress(int address)

{

if (ioctl(g_i2cFile, I2C_SLAVE, address) < 0) {

perror("i2cSetAddress");

exit(1);

}

}

//write a 16 bit value to a register pair//write low byte of value to register reg,//and high byte of value to register reg+1

void pca9555WriteRegisterPair(uint8_t reg, uint16_t value)

{

uint8_t data[3];

data[0] = reg;

data[1] = value & 0xff;

data[2] = (value >> 8) & 0xff;

if (write(g_i2cFile, data, 3) != 3) {

perror("pca9555SetRegisterPair");

}

}

//read a 16 bit value from a register pair

uint16_t pca9555ReadRegisterPair(uint8_t reg)

{

uint8_t data[3];

data[0] = reg;

if (write(g_i2cFile, data, 1) != 1) {

perror("pca9555ReadRegisterPair set register");

}

if (read(g_i2cFile, data, 2) != 2) {

perror("pca9555ReadRegisterPair read value");

}

return data[0] | (data[1] << 8);

}

//set IO ports to input, if the corresponding direction bit is 1,//otherwise set it to output

void pca9555SetInputDirection(uint16_t direction)

{

pca9555WriteRegisterPair(6, direction);

}

//set the IO port outputs

void pca9555SetOutput(uint16_t value)

{

pca9555WriteRegisterPair(2, value);

}

//read the IO port inputs

uint16_t pca9555GetInput()

{

return pca9555ReadRegisterPair(0);

}

int main(int argc, char** argv)

{

//test output value

int v = 3;

//direction of the LED animation

int directionLeft = 1;

//open Linux I2C device

i2cOpen();

//set address of the PCA9555

i2cSetAddress(0x20);

//set input for IO pin 15, rest output

pca9555SetInputDirection(1 << 15);

//LED animation loop

while (1) {

//if button is pressed, invert output

int xor;

if (pca9555GetInput() & 0x8000) {

xor = 0;

} else {

xor = 0xffff;

}

//set current output

pca9555SetOutput(v ^ xor);

//animate LED position

if (directionLeft) {

v <<= 1;

} else {

v >>= 1;

}

if (v == 0x6000) {

directionLeft = 0;

}

if (v == 3) {

directionLeft = 1;

}

//wait 100 ms for next animation step

usleep(100000);

}

//close Linux I2C device

i2cClose();

return 0;

}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。