嵌入式 Linux 学习笔记(07):I2C 应用编程

I2C 协议回顾、I2C-Tools 操作 AP3216C 传感器、编写 APP 直接访问 EEPROM。

📚 本文是《嵌入式 Linux 应用开发学习笔记》系列第 07 / 7 篇:I2C 应用编程。返回系列目录。

第10章 串口UART编程

第11章 I2C应用编程

11.1 I2C硬件

SCL,SDA,一条I2C总线可接很多设备,SCL,SDA放上拉电阻

image-20250828205720777

11.2 传输数据类比

如何通过IIC传数据,

主设备:一主多从,可把数据从主设备发到从设备,也可从设备发到主设备

  • 发送

主设备:开始(start)

主设备:A,我把数据发你(地址/方向)

A:收到(回应)

主设备:发送数据(传输)

A:收到后,告诉主设备(回应)

主设备:结束(停止)

  • 接收

主设备:开始(start)

主设备:B,把数据发我(地址/方向)

B:收到(回应)

B:把数据发给主设备(传输)

主设备:收到数据后,告诉A(回应)

主设备:结束(停止)

11.3 IIC传输数据格式

11.3.1写操作

  • 主设备发出start信号
  • 发出设备地址,方向(读1/写0)
  • 从设备发出应答信号
  • 主设备发送一字节数据,等待回应
  • 每传输一字节,接收方回应一次,在传输下一个数据
  • 数据发送完成,主设备发送stop信号

image-20250828211121367

11.3.2读操作

image-20250828212451496

11.3.3 IIC信号

IIC协议栈数据传输单位是字节,但是要用到9个时钟,前面8个时钟用来传输8数据,第9个始终用来传输回应信号,先传输最高位

  • 开始信号(S):SCL为高时,SDA由高跳低,开始传输数据
  • 结束信号(P):SCL为高时,SDA由低跳高,结束传输数据
  • 响应信号(ACK):接收到8位数据,第九个时钟周期,拉低SDA
  • SDA数据必须在SCL高时稳定,只能在SCL为低时变化

image-20250828213228809

11.3.4 协议细节

1.SDA引脚必须双向IO,因为有发有收

image-20250828214833582 image-20250828214855838 image-20250828215155892

11.4 SMBus协议

11.4.1 SMBus是IIC协议子集

SMBus: System Management Bus,系统管理总线

11.5无需编写驱动直接访问设备(I2C-Tools)

通过I2Ctool的程序,使用自带的驱动程序,来操作内核的i2c操作程序来访问硬件

image-20250829193204176

image-20250829193317507

首先确定:使用哪个IIC控制器,使用哪个IIC设备,读还是写数据

11.5.1用法

  • i2cdetect:I2C检测
// 列出当前的I2C Adapter(或称为I2C Bus、I2C Controller)
i2cdetect -l

// 打印某个I2C Adapter的Functionalities, I2CBUS为0、1、2等整数
i2cdetect -F I2CBUS

// 看看有哪些I2C设备, I2CBUS为0、1、2等整数
i2cdetect -y -a I2CBUS

image-20250829194206209

11.5.2操作传感器AP3216C

image-20250829194657273

AP3216C是红外、光强、距离三合一的传感器,以读出光强、距离值为例

  • 复位:往寄存器0写入0x4
  • 使能:往寄存器0写入0x3
  • 读光强:读寄存器0xC、0xD得到2字节的光强
  • 读距离:读寄存器0xE、0xF得到2字节的距离值

使用SMBus协议

//i2cset查看用法
i2cset
//写数据
i2cset -f -y 0(0号线) 0x1e(芯片地址) 0(写入地址) 0x4
i2cset -f -y 0 0x1e 0 0x3
//读数据
i2cget -f -y 0 0x1e 0xc w  	//0xc光照
i2cget -f -y 0 0x1e 0xe w	//0xe距离

使用I2C协议

i2ctransfer -f -y 0 w2@0x1e 0 0x4
i2ctransfer -f -y 0 w2@0x1e 0 0x3
i2ctransfer -f -y 0 w1@0x1e 0xc r2
i2ctransfer -f -y 0 w1@0x1e 0xe r2

11.5.3 I2CTools访问I2C设备的方式

APP通过I2C Controller与I2C Device传输数据

指定i2c控制器:

  • i2c-dev.c提供为每个I2C控制器(I2C Bus、I2C Adapter)都生成一个设备节点:/dev/i2c-0、/dev/i2c-1等待
  • open某个/dev/i2c-X节点,就是去访问该I2C控制器下的设备

指定i2c设备:

  • ioctl(file, I2C_SLAVE, address)
    • 如果该设备已经有了对应的设备驱动程序,则返回失败
  • ioctl(file, I2C_SLAVE_FORCE, address)
    • 如果该设备已经有了对应的设备驱动程序
    • 但是还是想通过i2c-dev驱动来访问它
    • 则使用这个ioctl来指定I2C设备地址

传输方式:I2C或SMBus

11.6编写APP直接访问EEPRPM

I2C控制器地址0x50

image-20250829203128562

I2C设备地址0x50

从芯片手册上可以知道,AT24C02的设备地址跟它的A2、A1、A0引脚有关:

高4位为1010,A2A1A0都是0,所以AT24C02的设备地址是:0b1010000,即0x50

11.6.1写数据

image-20250830153423926

11.6.2读数据

image-20250830153452117

使用 Hugo 构建
主题 Stack 由 Jimmy 设计