Linux嵌入式I2C协议笔记

硬件:

1.I2C结构

在一个SOC中有一个或者多个I2C控制器,一个I2C控制器可以连接一个或多个I2C设备。

I2C总线需要两条线,时钟线SCL和数据线SDA

2.I2C传输数据格式

  • 开始信号(S):SCL为高电平时,SDA山高电平向低电平跳变,开始传送数据。
  • 结束信号(P):SCL为高电平时,SDA由低电平向高电平跳变,结束传送数据。
  • 响应信号(ACK):接收器在接收到8位数据后,在第9个时钟周期,拉低SDA
  • SDA上传输的数据必须在SCL为高电平期间保持稳定,SDA上的数据只能在SCL为低电平期间变化

读操作

写操作

软件:

上层APP通过具体的I2C设备驱动(eg.ap3216)对芯片进行读写操作。而i2c设备驱动需要使用linux内核提供的数据结构对i2c设备进行读写操作,其中最重要的就是i2c_adapter,和i2c_algorithm结构体,I2C adapter表示一条I2C总线,也就是I2C Controller,i2c_adapter里面有两个重要的成员,nr表示第几个i2c总线(i2c controller),i2c_algorithm(用来收发I2C数据,里面有master_xfer函数)

通过这两个数据结构,我们可以访问到具体的I2C物理设备,Linux内核是如何表示I2C Device的?

Linux内核使用i2c_client数据结构来表示一个具体的I2C物理设备,其中最重要的是这个设备的地址addr和这个设备属于哪一条总线下(I2C Controller或者I2C adapter)。

我们知道i2c_algorithm 里面提供了master_xfer函数和i2c_client 进行数据读写,那么我们就必须要知道master_xfer参数的意义,其中最重要的是i2c_msg。flags用来表示数据传输方向,bit 0等于I2C_M_RD表示读,bit 0等于0表示写。

举例:设备地址为0x50的EEPROM,要读取它里面存储地址为0x10的一个字节,应该构造几个i2c_msg?

  • 要构造2个i2c_msg

  • 第一个i2c_msg表示写操作,把要访问的存储地址0x10发给设备

  • 第二个i2c_msg表示读操作

  • 代码如下

c 复制代码
u8 data_addr = 0x10;
i8 data;
struct i2c_msg msgs[2];

msgs[0].addr   = 0x50;
msgs[0].flags  = 0;
msgs[0].len    = 1;
msgs[0].buf    = &data_addr;

msgs[1].addr   = 0x50;
msgs[1].flags  = I2C_M_RD;
msgs[1].len    = 1;
msgs[1].buf    = &data;
相关推荐
IMPYLH9 分钟前
Linux 的时间为什么会被拨回去
linux·运维·服务器
2601_963282771 小时前
寒地窄带通信工程实践:黑龙江哈尔滨对讲机选型、组网与合规运维总结
运维·服务器·网络
蒸蒸yyyyzwd1 小时前
AI应用相关可能的面试问题
笔记
叼烟扛炮2 小时前
[Git 实战] 学习笔记:从生成 SSH 密钥到解决 TortoiseGit 推送报错全指南
linux·运维·笔记·git·学习
xbzb2 小时前
OpenStack 网络管理(理论):Linux 网络虚拟化是 Neutron 的地基
linux·服务器·网络·openstack·network·neutron
蒸蒸yyyyzwd3 小时前
学习笔记 八股手撕
笔记·学习
我要见SA姐13 小时前
GitHub Actions 自动化:5 个真实运维提效案例
运维·数据库·机器学习·oracle·回归
起个网名真难~3 小时前
STM32F103_Bootloader_从零到UART升级成功_博客原稿
stm32·单片机·嵌入式硬件
Android系统攻城狮4 小时前
Linux FFmpeg深度解析之avcodec_flush_buffers调用流程与实战(十九)
linux·运维·服务器·ffmpeg·车载音视频·ffmpeg音视频进阶
揣一尾游鱼yu4 小时前
Spring上(IOC)笔记
java·笔记·spring·ioc