• [I2C]pca9555(i2c-gpio扩展)应用层测试代码


    注意点:

    • 如果在设置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 <stdint.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <unistd.h>
    #include <linux/i2c-dev.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <sys/ioctl.h>
    #include <fcntl.h>
    
    // 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;
    }
  • 相关阅读:
    net下开发COM+组件(一)
    C#中自定义属性的例子
    textBox的readonly=true
    关于ADO.Net的数据库连接池
    CYQ.Data 轻量数据层之路 使用篇三曲 MAction 取值赋值(十四)
    CYQ.Data 轻量数据层之路 SQLHelper 回头太难(八)
    CYQ.Data 轻量数据层之路 MDataTable 绑定性能优化之章(十一)
    C# 浅拷贝与深拷贝区别 解惑篇
    C#中的 ref 传进出的到底是什么 解惑篇
    CYQ.Data 轻量数据层之路 使用篇五曲 MProc 存储过程与SQL(十六)
  • 原文地址:https://www.cnblogs.com/aaronLinux/p/6896573.html
Copyright © 2020-2023  润新知