标签搜索

在Linux上使用I2c

Toanle
2023-06-19 / 0 评论 / 68 阅读 / 正在检测是否收录...
温馨提示:
本文最后更新于2023年06月19日,已超过644天没有更新,若内容或图片失效,请留言反馈。
  1. 什么是I2c?
    在“Inter-Integrated Circuit” 中,“Inter-” 表示“在……之间,相互”的意思;“Integrated Circuit” 简称“IC”,表示“集成电路”的意思。 “Inter-Integrated Circuit”,直接翻译过来就是内部集成电路(DeepL翻译为互联电路,微软翻译为内部集成电路,百度翻译为内置集成电路)。德力威尔王术平认为,应该把“Inter-Integrated Circuit”翻译为集成电路互连或者芯片互连,更符合国人习惯,更为贴切。

在中国正式的书面场合,全称写作Inter-Integrated Circuit,简写Inter-IC或者I2C(数字“2”书写为上标,,英文读作“I squared C”,中文读作“I平方C”)。

在非正式场合或者数字“2”无法书写为上标时,有人就书写为“IIC”或者“I2C”,把“IIC”读作“I-I-C”,把“I2C”读作“I-two-C”或“I二C”。这些书写方式或叫法,其实没有对错,只是不同习惯而已,就像普通话和地方话一样。但是,我们在严谨的正式场合,还是要统一标准,规范书写为“I2C”(数字“2”书写为上标),规范读作“I平方C”。
在本文中,德力威尔王术平对相关术语的中文解释做出如下约定:
I2C:读作“I平方C”(尽量不读作“I方C”,避免和I3C混淆)。
I2C:集成电路互连。
I2C Bus:I2C总线或集成电路互连总线。
I2C Specification:I2C规范或集成电路互连规范。
I2C Communication Interface:I2C通信接口或集成电路互连通信接口。
I2C Communication Protocol:I2C通信协议或集成电路互连通信协议。
I2C:在无法书写上标数字“2”时,可书写为“IIC”或“I2C”。
lj29276f.png

  1. 计算机中Bus术语的定义
    在计算体系结构中, 总线(Bus)是计算机内部组件之间或计算机之间传送信息的公共通信干线,它是由导线组成的传输路径。

总线(Bus)是一种电路,它是cpu、RAM、ROM、输入、输出等设备传递信息的公用通道,充当数据在计算机内传输的高速公路
lj294x9z.png
按照计算机所传输的信息种类,计算机的总线可以划分为数据总线、地址总线和控制总线,分别用来传输数据信息、地址信息和控制信号。
lj2905ko.png

首先,我们需要安装工具包。

sudo apt install i2c-tools

i2c-tools是一个用于 Linux 与 软件/硬件 I2C 总线通信的实用工具集,其中包括了查看和修改 I2C 总线设备信息的工具。以下是一些常见的使用示例:

  1. 列出I2C总线上的设备:
sudo i2cdetect -y 1

lj28ywzy.png
这将会显示以16进制格式列出I2C总线地址范围内所有已经探测到的设备。其中,第一个参数-y表示以非交互模式运行,第二个参数1表示使用1号I2C总线(对于一些系统可能是2号I2C总线)。这个命令可以帮助我们快速看到哪些设备设备与I2C总线通信连接,以及它们的I2C地址。

  1. 读写设备寄存器:
sudo i2cget -y 1 0x48 0x00

这个命令表示从I2C地址为0x48的设备中读取寄存器地址为0x00的寄存器的值。如果想要写入一个新的值,我们可以用i2cset命令,例 如:

sudo i2cset -y 1 0x48 0x00 0x10

这个命令表示往I2C地址为0x48的设备中写入寄存器地址为0x00的寄存器的值为0x10。

  1. 使用i2cdump命令读取设备的寄存器:
sudo i2cdump -y 1 0x48

如果我们想要快速查看一个设备的所有寄存器的值,我们可以使用i2cdump命令。这个命令表示从I2C地址为0x48的设备中读取所有的寄存器的值(通常有16个)。

  1. 编写自定义的I2C工具:

除了常用的i2cget和i2cset命令之外,我们还可以使用i2c-tools提供的APIs创建自定义的I2C工具。例如,下面是一个简单的C程序,通 过I2C通信从 EEPROM (I2C地址为0x57) 中读取两个字节的数据:

#include <fcntl.h>
#include <unistd.h>
#include <linux/i2c-dev.h> // for I2C_SLAVE macro
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char** argv){
    int fd;
    if ((fd = open("/dev/i2c-1", O_RDWR)) < 0){ // open I2C bus
        perror("open");
        exit(1);
    }
    if (ioctl(fd, I2C_SLAVE, 0x57) < 0){ // select EEPROM device
        perror("ioctl");
        exit(1);
    }
    char buffer[2];
    int ret;
    if ((ret = read(fd, buffer, 2)) != 2){ // read 2 bytes from memory address 0x00
        perror("read");
        exit(1);
    }
    printf("Read: %#02x %#02x\n", buffer[0], buffer[1]);
    close(fd);
    return 0;
}

以上就是i2c-tools常用的几个使用示例,我们可以根据自己的需求修改。

package main

import (
    "fmt"
    "log"
    "time"
    "golang.org/x/exp/io/i2c"
)

func main() {
    // 打开I2C总线
    bus, err := i2c.Open(&i2c.Devfs{Dev: "/dev/i2c-1"}, 0x57)
    if err != nil {
        log.Fatal(err)
    }
    defer bus.Close()

    // 模拟I2C设备地址为0x00,读取2字节数据
    buffer := make([]byte, 2)
    if err := bus.ReadRegBytes(0x00, buffer); err != nil {
        log.Fatal(err)
    }
    fmt.Printf("Read: %#02x %#02x\n", buffer[0], buffer[1])

    time.Sleep(time.Second)
}

这个程序使用了golang.org/x/exp/io/i2c包来打开I2C总线并创建I2C设备。我们可以通过调整0x57参数来改变设备的I2C地址。代码中的ReadRegBytes()方法可以使我们直接从指定设备的指定寄存器中读取数据。这个程序会读取从0x00寄存器中读取2字节的数据并在控制台 中输出。最后,代码中的time.Sleep()函数用于防止Go程序在数据读取完成后立刻退出。

0

评论

博主关闭了当前页面的评论