I2C基础知识
#
I2C基础知识#
1.I2C软件框架APP 它知道读写什么数据 app
I2C Device Driver 它知道怎么读写数据 some driver(I2C 设备自己的驱动程序) / i2c-dev.c(内核自带的i2c-dev.c驱动程序,它是i2c控制器驱动 程序暴露给用户空间的驱动程序)
I2C Controller Driver 它负责传输数据 adapter driver(芯片 I2C 控制器的驱动程序,称为 adapter) / i2c-gpio.c(使用GPIO模拟的 I2C 控制 器驱动程序)
i2c Device I2C设备
#
2.I2C传输数据格式之前学习I2C都是先介绍各种信号,再组合起来看。但是感觉还是先看读写操作再学信号电平变化细节比较好。
写操作:(白色块为主设备,灰色块为从设备,图片来自《嵌入式Linux应用开发完全手册 – 韦东山》)
读操作:
在第一个数据中分为了7bit的地址和1bit的方向。
电平信号
start信号:SCL 为高电平时,SDA 山高电平向低电平跳变
stop信号:SCL 为高电平时,SDA 由低电平向高电平跳变
回应信号:接收器在接收到 8 位数据后,在第 9 个时钟周期,拉低 SDA
高低电平:
在低电平期间变化电平,高电平期间读取电平值。
#
3.I2C设备硬件当1设备的SDA线为高电平,MOS管导通,SDA为0;当1设备的SDA线为低电平,MOS管截止,SDA由外部电路决定。
当2设备的SDA线为高电平,MOS管导通,SDA为0;当2设备的SDA线为低电平,MOS管截止,SDA由外部电路决定。
Aout | Bout | SDA |
---|---|---|
0 | 0 | 上拉电阻,1 |
0 | 1 | 接地,0 |
1 | 0 | 接地,0 |
1 | 1 | 接地,0 |
有一个设备的out为1,mos管导通,拉低SDA;所有设备的out为0,所有mos管截止,外部电路拉高SDA。这样的设计防止了一高一低时短路的问题。
SCL也是这样设计的,因为主从设备也都会操作SCL
#
SMBus协议SMBus(System Management Bus,系统管理总线)是I2C协议的一个子集,
I2C | SMBus | |
---|---|---|
VDD极限值 | 范围很广,甚至高达12V | 1.8V-5V |
最小时钟频率,最大clock stretching (可以把SCL拉低占住的最长时间) | 都无限制 | 最小值为10KHz,最大值也有限制 |
地址回应 | 没有强制要求 | 强制要求发出回应信号 |
数据传输格式 | 只定义了怎么传输数据,但没有定义数据的格式 | 定义了几种数据格式(在《嵌入式Linux应用开发完全手册 – 韦东山》10.3.2 SMBus 协议分析 有介绍) |
Repeated start Condition重复发出开始信号 | - | 在读和写之间,可以不发出P信号,直接发出两次S信号 |
SMBus Low Power Version | - | 低功耗版本 |
一个I2C控制器(adaptor)是否支持某一个I2C,SMBus功能,可以从 Functionality flag中得到。比如 Functionality flag: I2C_FUNC_SMBUS_QUICK,表示需
要 I2C 控制器支持 SMBus Quick Command。
#
I2C系统中的重要结构体1.i2c_adapter:
2.i2c_client:
3.i2c_msg
从传输函数原型可以看到,有adapter,msgs,但是没有client,因为i2c_msg里面含有client的信息。
4.i2c_transfer
统一的传输函数,用这个函数就不需要调用i2c_adapter里面的
示例:
#
I2Ctools无需编写驱动程序即可访问I2C设备
AP3216C是红外、光强、距离三合一的传感器,以读出光强、距离值为例。步骤如下:
- 复位:往寄存器0写入0x4
- 使能:往寄存器0写入0x3
- 读光强:读寄存器0xC、0xD得到2字节的光强
- 读距离:读寄存器0xE、0xF得到2字节的距离
AP3216C设备地址为0x1E,假设设备在I2C—BUS0上,操作如下:
- 使用SMBus协议
- 使用I2C协议
1.扫描和检测I2C总线上的设备
参数说明:
-y
:使用自动模式,不需要用户确认。-r
:以绑定引脚模式运行,适用于特定的硬件配置。BUS-NUMBER
:指定要扫描的 I2C 总线号,如果没有指定,默认为 0。
调用 i2cdetect 命令后,它会扫描指定的 I2C 总线上的所有设备,并将它们显示在一个表格中。表格中的每个单元格表示一个设备地址,如果该地址上找到了设备,就会显示地址值,否则显示 “–”。
3.i2cget
在APP里,有这几个问题:
怎么指定I2C控制器? i2c-dev.c提供为每个I2C控制器(I2CBus、I2C Adapter)都生成个设备节点:/dev/i2c-0、/dev/i2c-1等等 open某个/dev/i2c-X节点,就是去访问该l2C控制器下的设备
怎么指定I2C设备?
通过ioctl指定I2C设备的地址
ioctl(file,12C_SLAVE,address)
如果该设备已经有了对应的设备驱动程序,则返回失败
ioctl(file,12C_SLAVE_FORCE,address)
如果该设备已经有了对应的设备驱动程序,但是还是想通过i2c-dev驱动来访问它,则使用这个ioctl来指定I2C设备地址
怎么传输数据? 两种方式: 一般的I2C方式:ioctl(file,I2C_RDWR,&rdwr) SMBus方式:ioctl(file,I2C_SMBUS,&args)
#
编写APP直接访问EEPROM确定I2C控制器:插上EEPROM后,i2c_detect -y 0
IMX6ull:i2c-0总线
直接使用i2c_tools里面的函数,参考驱动大全-编写APP直接访问EEPROM与完全开发手册
请点击左侧菜单(移动端为右下角)选择要查看的所有笔记吧。