You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在C++程序中直接实现i2cset式的I2C设备通信?

直接在C++中实现i2cset功能的I2C通信方案

当然有,你可以直接通过Linux内核提供的I2C设备接口实现,完全替代system("i2cset ...")的调用,避免启动子进程带来的7-10ms延迟,还能灵活指定I2C总线(你提到的“端口号”实际是I2C总线编号)。

核心原理

Linux会把每个I2C总线暴露为/dev/i2c-N格式的设备文件(N为总线编号,比如你的命令里的0对应/dev/i2c-0)。通过直接操作这个设备文件,结合ioctl和I2C SMBus函数,就能实现和i2cset完全一致的功能。

C++实现代码示例

以下代码完全对应你给出的i2cset -f -y 0 0x74 2 0x00命令逻辑:

#include <fcntl.h>
#include <unistd.h>
#include <linux/i2c-dev.h>
#include <i2c/smbus.h>
#include <cerrno>
#include <cstring>
#include <iostream>

bool i2c_write_byte(int bus_num, uint8_t dev_addr, uint8_t reg_addr, uint8_t value) {
    // 拼接I2C总线设备路径
    char dev_path[20];
    snprintf(dev_path, sizeof(dev_path), "/dev/i2c-%d", bus_num);
    // 打开设备文件
    int fd = open(dev_path, O_RDWR);
    if (fd < 0) {
        std::cerr << "打开I2C总线失败: " << strerror(errno) << std::endl;
        return false;
    }

    // 设置目标设备的I2C地址(对应命令中的0x74)
    // 用I2C_SLAVE_FORCE模拟-f参数的强制访问
    if (ioctl(fd, I2C_SLAVE_FORCE, dev_addr) < 0) {
        std::cerr << "设置设备地址失败: " << strerror(errno) << std::endl;
        close(fd);
        return false;
    }

    // 向指定寄存器写入字节(对应命令中的2和0x00)
    int ret = i2c_smbus_write_byte_data(fd, reg_addr, value);
    if (ret < 0) {
        std::cerr << "写入数据失败: " << strerror(errno) << std::endl;
        close(fd);
        return false;
    }

    close(fd);
    return true;
}

int main() {
    // 对应命令参数:总线0,设备地址0x74,寄存器2,值0x00
    bool success = i2c_write_byte(0, 0x74, 2, 0x00);
    if (success) {
        std::cout << "I2C写入成功" << std::endl;
    }
    return success ? 0 : 1;
}

编译与注意事项

  • 编译时需链接i2c库:g++ your_code.cpp -o i2c_write -li2c
  • 确保程序拥有/dev/i2c-N设备的访问权限(可将用户加入i2c组,或用sudo运行)
  • 这种直接调用内核接口的方式耗时通常在微秒级,远低于system调用的延迟
  • I2C_SLAVE_FORCE对应i2cset的-f参数,若不需要强制访问,替换为I2C_SLAVE即可

内容的提问来源于stack exchange,提问作者MDkman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 14:15:34