PCA9698的IIC转接GPIO控制N路灯

PCA9698验证灯的办法和PCA9535验证6路数字继电器,编译成ko直接Insmod,然后查看/dev/节点有了吗?然后用iictool命令往对应iic地址上面写数据,看看灯亮灭或者听继电器开关声响,至于写多少,研究芯片手册上面参数。正式代码就用system("./sh“)或者直接写入数据iictool命令到引号那种来控制。

PCA9698的IIC转接GPIO控制N路灯_第1张图片

PCA9698硬件描述

PCA9698的IIC转接GPIO控制N路灯_第2张图片

通过通过A0   A1   A2三个位控制地址,通过不同地址写入到各个灯

PCA9698的IIC转接GPIO控制N路灯_第3张图片
思路:IIC代码,不加驱动,但是写的话写入了底层那种IIC应用层找到能用

pca9698: gpio@2f{
compatible = "nxp,pca9505";
pinctrl-names = "default";
pinctrl-0 = <&pca9698_int_pins>;
reg = <0x2f>;
reset-gpios = <&gpio3 14 GPIO_ACTIVE_LOW>;
gpio-controller;
#gpio-cells = <2>;
interrupt-parent = <&gpio3>;
interrupts = <15 IRQ_TYPE_LEVEL_LOW>;
interrupt-names = "pca_input";
};

系统启动后,i2c设备可以成功驱动挂载,在/sys/class/gpio/下新增了gpiochip462#,可以export 相应的管脚,管脚配置使用正常配置的中断引脚可以看到

应用程序编写:

#include 
#include 
#include 
#include 
#include 
#include 

#define PCA9698BS_1_I2C_ADDR 0x20
#define PCA9698BS_2_I2C_ADDR 0x21
#define NUM_LEDS 24
#define LED_OFF 0
#define LED_ON 1

int main()
{
    int i2c_fd;
    unsigned char buf[2];
    int led_states[NUM_LEDS] = {LED_OFF};  // 初始化所有LED为关闭状态

    i2c_fd = open("/dev/i2c-0", O_RDWR);
    if (i2c_fd < 0)
    {
        perror("无法打开I2C设备文件");
        return 1;
    }

    // 设置第一个PCA9698BS的I2C地址
    if (ioctl(i2c_fd, I2C_SLAVE, PCA9698BS_1_I2C_ADDR) < 0)
    {
        perror("无法设置第一个PCA9698BS的I2C地址");
        close(i2c_fd);  // 关闭I2C设备文件
        return 1;
    }

    // 配置输出模式
    buf[0] = 0x03;
    buf[1] = 0x00;
    if (write(i2c_fd, buf, 2) != 2)
    {
        perror("无法配置引脚模式");
        close(i2c_fd);
        return 1;
    }

    // 设置第二个PCA9698BS的I2C地址
    if (ioctl(i2c_fd, I2C_SLAVE, PCA9698BS_2_I2C_ADDR) < 0)
    {
        perror("无法设置第二个PCA9698BS的I2C地址");
        close(i2c_fd);
        return 1;
    }

 // 配置输出模式
    buf[0] = 0x03;
    buf[1] = 0x00;
    if (write(i2c_fd, buf, 2) != 2)
    {
        perror("无法配置引脚模式");
        close(i2c_fd);
        return 1;
    }

    // 控制LED灯的开关状态
    buf[0] = 0x01;

    // 根据特定条件设置灯的状态
    for (int i = 0; i < NUM_LEDS; i++)
    {
        // 假设这里有特定的条件来设置LED状态
        led_states[i] = LED_ON;  
        //  led_states[i] = LED_OFF;
    }

    // 根据灯的状态控制引脚输出状态
    for (int i = 0; i < NUM_LEDS; i++)
    {
        int reg_offset = i / 8; // 寄存器偏移量,每个寄存器包含8个LED状态
        int bit_offset = i % 8; // 位偏移量

        // 读取当前寄存器的值
        buf[0] = 0x02 + reg_offset; // 控制寄存器地址
        if (write(i2c_fd, buf, 1) != 1)
        {
            perror("无法设置控制寄存器地址");
            close(i2c_fd);
            return 1;
        }
 if (read(i2c_fd, &buf[1], 1) != 1)
        {
            perror("无法读取寄存器值");
            close(i2c_fd);
            return 1;
        }

        // 根据LED状态设置对应的位
        if (led_states[i] == LED_ON)
        {
            buf[1] |= (1 << bit_offset); // 将对应位设置为1(打开LED)
        }
        else
        {
            buf[1] &= ~(1 << bit_offset); // 将对应位设置为0(关闭LED)
        }

        // 写入更新后的值到寄存器
        buf[0] = 0x02 + reg_offset; // 控制寄存器地址
        if (write(i2c_fd, buf, 2) != 2)
        {
            perror("无法设置控制寄存器地址");
            close(i2c_fd);
            return 1;
        }
    }
   // 控制引脚输出状态
    buf[0] = 0x01; // 输出寄存器地址
    buf[1] = 0x00; // 输出数据,假设全部输出低电平
    if (write(i2c_fd, buf, 2) != 2)
    {
        perror("无法控制引脚输出状态");
        close(i2c_fd);
        return 1;
    }

    sleep(2);

    // 关闭所有输出
    buf[1] = 0x00; // 输出数据,全部输出低电平
    if (write(i2c_fd, buf, 2) != 2)
    {
        perror("无法控制引脚输出状态");
        close(i2c_fd);
        return 1;
    }

    // 关闭I2C设备文件
    close(i2c_fd);

    return 0;
}

你可能感兴趣的:(硬件接口_接口驱动开发,单片机,嵌入式硬件)