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

Linux用户空间无需寄存器地址读取BH1750 2字节I2C数据的实现方法

Linux用户空间无寄存器地址I2C多字节读取方案

实现思路

Linux内核提供了i2c-dev字符设备驱动,允许用户空间直接发起自定义I2C传输序列,无需编写内核驱动即可实现你需要的S Adr Rd (A) Data A Data NA P读取时序。核心使用I2C_RDWR类型的ioctl调用,该调用支持完全自定义传输结构,不需要强制附带寄存器地址前缀。

操作步骤

  • 首先确认BeagleBone上BH1750挂载的I2C总线编号,执行i2cdetect -l可以列出所有可用I2C总线,常用编号为i2c-1
  • 加载i2c-dev内核模块:modprobe i2c-dev,加载成功后会生成/dev/i2c-X(X为总线编号)设备节点
  • 编写C代码调用ioctl完成读取,示例代码如下:
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdint.h>
#include <sys/ioctl.h>
#include <linux/i2c.h>
#include <linux/i2c-dev.h>

// 根据BH1750的ADDR引脚电平调整地址,接GND为0x23,接VCC为0x5C
#define BH1750_ADDR 0x23

int main() {
    int fd = open("/dev/i2c-1", O_RDWR);
    if (fd < 0) {
        perror("打开I2C设备失败");
        return 1;
    }

    uint8_t recv_buf[2];
    struct i2c_msg msgs[] = {
        {
            .addr = BH1750_ADDR,
            .flags = I2C_M_RD, // 标记为I2C读操作
            .len = 2, // 连续读取2字节
            .buf = recv_buf,
        }
    };

    struct i2c_rdwr_ioctl_data ioctl_data = {
        .msgs = msgs,
        .nmsgs = 1,
    };

    if (ioctl(fd, I2C_RDWR, &ioctl_data) < 0) {
        perror("I2C读取失败");
        close(fd);
        return 1;
    }

    // 换算光照强度,单位lux
    float lux = ((recv_buf[0] << 8) | recv_buf[1]) / 1.2;
    printf("当前光照强度:%.2f lux\n", lux);

    close(fd);
    return 0;
}

注意事项

  • 运行程序需要root权限,或者通过udev规则配置普通用户对/dev/i2c-X节点的访问权限
  • 如果需要先发送测量启动指令,只需要在msgs数组中新增一个写类型的i2c_msg放在读消息之前,ioctl会自动按顺序完成连续传输
  • 编译时不需要额外链接第三方库,直接用gcc编译即可:gcc bh1750_read.c -o bh1750_read

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 22:36:00