I²C协议简介

I²C协议简介

I²C(Inter-Integrated Circuit) 是一种由 Philips 提出的 双线串行通信总线 ,广泛用于 MCU 与各种传感器、存储器、外设之间的短距离通信。 它具有硬件简单、扩展性好、协议轻量等优点,因此是嵌入式领域最常见的通信方式之一。

相比SPI协议,它本身的定义相对复杂一点,可以支持多主多从的半双工通信,但是优点是它仅占用2个单片机引脚就可以实现多从机的通信。

引脚定义

SCL :时钟线,由主机生成
SDL :数据线,主从共享

SCL 与 SDA 都是 开漏(Open-Drain)结构 ,需要使用上拉电阻。

因此总线空闲时两条线都是 高电平

通信时序

主机SDL下降沿产生START信号,从机从机接收到开始监听,SCL拉低并且以实现约好的5种速率模式其一,产生脉冲时钟信号,SCL为高时,SDL保持稳定不变,SCL为低时可变化准备采样,SCL上升沿对SDL进行采样,连续采样8个完成一个字节数据的传输,紧接着SDL交给从机拉低SDA发送ACK,ACK后主机即可发送下一个字节。

START信号后的第一个字节都是"寻址(Address + R/W)字节",由7位的地址码和一位读写位组成,所有从机收到该寻址字节后,对比自身地址,由地址匹配的从机进行ACK。

EEPROM( 24C02)读写时序

EEPROM 的写时序一般分为三步:
START → 寻址 → 内部地址 → 数据 → STOP

具体流程如下:

复制代码
START
→ [0xA0] W   (ACK)
→ [0x10] addr(ACK)
→ [0x11] (ACK)
→ [0x22] (ACK)
→ [0x33] (ACK)
→ [0x44] (ACK)
→ [0x55] (ACK)
STOP

以上是主机对地址0xA0的EEPROM的地址0x10写入5个字节的流程

复制代码
START
→ [0xA0] W (ACK)
→ [0x10] 内部地址 (ACK)
REPEATED START
→ [0xA1] R (ACK)
← [0x11] (主机 ACK)
← [0x22] (ACK)
← [0x33] (ACK)
← [0x44] (ACK)
← [0x55] (主机 NACK)
STOP

以上是主机从地址0xA0的EEPROM的地址0x10读取5个字节的流程

这里要注意2点:

1、一次 START → STOP 的事务内不能同时完成写和读 (至少对于 EEPROM 这类 I²C 设备来说)

因为EEPROM 只有在 STOP 之后才会执行真实的写入操作,如果在写完 5 字节之后立即切换读模式而不发送 STOP,内部写周期还没完成,数据尚未写入 Flash。

2、读取数据时必须重新写一次地址,修改EPROM 的内部地址指针位置,因为写入 5 个字节时,内部地址指针会指向最后写入字节的下一地址,直接读取的话会读到刚才写入的的最后一个字节的后面的内存数据

相关推荐
shylyly_2 小时前
C++中的类型转换
开发语言·c++·匿名对象·隐式类型转换·拷贝优化
cui_ruicheng3 小时前
Python数据分析(一):数据分析概述与环境搭建
开发语言·python·数据分析
心平气和量大福大3 小时前
C#-WPF-UserControl-生命周期(加载 退出)
开发语言·c#·wpf
小龙报3 小时前
【优选算法】1. 水果成蓝 2.找到字符串中所有字母的异位词
java·c语言·数据结构·数据库·c++·redis·算法
sunywz3 小时前
【c#】 Web Deploy一键发布,IIS部署全流程
开发语言·前端·c#
Brilliantwxx4 小时前
【Linux】 软件包管理器(yum)+ Vim使用
linux·运维·服务器·开发语言·编辑器·vim
雪的季节4 小时前
Python 线程同步与异步编程 全解析
java·开发语言
520拼好饭被践踏4 小时前
JAVA+Agent学习day22
java·开发语言·后端·学习
笨蛋不要掉眼泪4 小时前
Java虚拟机:堆的参数配置
java·开发语言·jvm
冰暮流星4 小时前
javascript之date对象
开发语言·javascript·ecmascript