当前位置: 首页 > news >正文

【知识分享】IIC协议详解

一、简介

    I²C(Inter-Integrated Circuit,集成电路总线,也可以写成IIC)是一种由飞利浦公司开发的双向二线制串行通信总线,只通过一根串行数据线(SDA)和一根串行时钟线(SCL),就能让主板、外围设备(如传感器、存储器)等芯片之间实现数据传输,具有硬件结构简单、占用引脚少、支持多设备挂载和热插拔等特点,在嵌入式系统中应用广泛。

二、发展历史

起源与专利阶段(1982 年)
由荷兰飞利浦(Philips)公司于 1982 年开发,最初用于连接主板与外围芯片(如 EEPROM、传感器),解决多设备通信时引脚占用问题。
1980 年代至 2000 年,I²C 作为飞利浦专利技术,广泛应用于消费电子(如电视机、音响)和嵌入式系统。
标准化与开放(2000 年后)
2006 年,飞利浦将 I²C 技术贡献给 JEDEC(固态技术协会),成为开放式标准(JESD42-B),推动其在物联网、穿戴设备等领域普及。
技术迭代:从最初的标准模式(100kbps)发展出快速模式(400kbps)、高速模式(3.4Mbps)及超高速模式(5Mbps),满足不同场景需求。

三、内容详解

3.1 物理层特性

双线结构:
SDA(串行数据线):传输数据,双向通信。
SCL(串行时钟线):主机提供时钟信号,同步数据传输。
电气特性:
采用开漏输出,需外接上拉电阻(通常 4.7kΩ),默认高电平。
工作电压兼容 3.3V/5V 系统,传输距离通常 < 1 米(受电容负载限制)。

3.2 数据链路层协议

3.2.1 空闲状态

    SCL与SDA均为高电平。

3.2.2 起始与结束

起始与结束
起始:SCL为高电平时,SDA由高变低,表示开始传输;
结束:SCL为高电平时,SDA由低变高,表示结束传输。

3.2.3 收发数据

收发数据

    从上文也可得知,正常收发数据时,SDA要翻只能在SCL为低的时候进行。当需要发送一个字节的数据时,先拉低SCL,根据要发送的第一位数据(高位优先)拉高/拉低SDA,然后拉高SCL,保持一段时间,完成第一位的发送,以此循环8次。

3.2.4 应答

应答

    在主机发送完一个字节的数据后,需要等待从机回复一个应答信号,正常做法是在第8个SCL高电平拉低后,释放SDA信号线(由外部上拉自行拉成高电平),然后拉高SCL,等待从机控制SDA线,如果在第9个SCL高电平保持期间,读取到SDA线为低电平,则认为接收到从机的应答;否则为无应答。

四、应用及对比

    常见的串行通信有IIC、UART、SPI、CAN等,下面直接用一张表来展示各种串口的区别。

对比维度I²CUART(串口)SPICAN
引脚数量2 根(SDA+SCL)2 根(TX+RX)4-5 根(MOSI+MISO+SCK+CS)2 根(CAN_H+CAN_L)
传输模式半双工(同一时刻单向传输)全双工(收发独立)全双工(同步收发)半双工(差分信号)
最高速度超高速模式 5Mbps通常 115.2kbps-4Mbps可达数十 Mbps(如 30Mbps)最高 1Mbps(高速 CAN)
拓扑结构多主多从(需仲裁机制)点对点一主多从(需 CS 片选)总线型(多节点共享总线)
地址寻址7/10 位地址,自动寻址无地址(需软件协议定义)靠 CS 片选指定从机靠 ID 号仲裁(非地址寻址)
典型应用传感器、EEPROM、低速外设互联串口通信、调试接口、Modem高速存储(SD 卡)、LCD 驱动汽车总线、工业控制网络
优势引脚少、多设备挂载简单协议简单、传输距离较远(RS-485)速度快、全双工、时序灵活抗干扰性强、支持长距离和多节点
劣势速度受限、仲裁机制复杂无硬件寻址、多设备需软件管理引脚多、多从机需多 CS 线协议复杂、成本高

核心差异总结

I²C 的独特价值:以最少引脚实现多设备互联,适合 “轻量级” 数据交互(如传感器配置、少量参数读写),在低功耗、小数据量场景中不可替代。
与 SPI 的对比:SPI 速度更快但引脚多,适合高速批量数据传输(如 LCD 图像数据);I²C 适合低速、多设备的 “碎片化” 通信。
与 UART 的对比:UART 无硬件寻址,多设备通信需额外协议设计,而 I²C 原生支持多从机自动寻址,硬件层面更简洁。

五、代码实现

    用IO口模拟IIC协议,这里就不单独写,直接贴一份github上的代码,这里也不全贴,只贴出模拟IIC几个阶段的IO口翻转方式,想看完整的主从机模拟,可以去原路径观摩,原路径https://github.com/daimaCoder/IIC_MS。

#define  IIC_SCL_H       HAL_GPIO_WritePin(GPIOB, IIC_SCL_Pin, GPIO_PIN_SET)
#define  IIC_SCL_L       HAL_GPIO_WritePin(GPIOB, IIC_SCL_Pin, GPIO_PIN_RESET)
#define  IIC_SDA_H       HAL_GPIO_WritePin(GPIOB, IIC_SDA_Pin, GPIO_PIN_SET)
#define  IIC_SDA_L       HAL_GPIO_WritePin(GPIOB, IIC_SDA_Pin, GPIO_PIN_RESET) 
#define  READ_SDA        HAL_GPIO_ReadPin(GPIOB, IIC_SDA_Pin)
#define  READ_SCL        HAL_GPIO_ReadPin(GPIOB, IIC_SCL_Pin)
#define  IIC_Delay       delay_us(4)    //IIC使用的延时,可通过改变延时,改变IIC传输速率
#define  Time_Count      250           //while等待超时计数,不可小于某个值,	最小值根据单片机时钟变化void IIC_Start(void)				//发送IIC开始信号
{IIC_SCL_H;IIC_SDA_H;IIC_Delay;IIC_SDA_L;IIC_Delay;IIC_SCL_L;
}void IIC_Stop(void)	  			//发送IIC停止信号	
{IIC_SCL_L;IIC_SDA_L;IIC_Delay;IIC_SCL_H;IIC_Delay;IIC_SDA_H;	
}void IIC_Ack(void)					//IIC发送ACK信号
{IIC_SCL_L;IIC_SDA_L;IIC_Delay;IIC_SCL_H;IIC_Delay;IIC_SCL_L;IIC_SDA_H; //添加释放总线}void IIC_NAck(void)				//IIC不产生ACK信号
{IIC_SCL_L;IIC_SDA_H;IIC_Delay;IIC_SCL_H;IIC_Delay;IIC_SCL_L;
}uint8_t IIC_Wait_Ack(void)				//IIC等待ACK信号	
{int time = 0;IIC_SDA_H;IIC_Delay;IIC_SCL_H;IIC_Delay;while(READ_SDA)     //等待应答信号{time++;if(time>Time_Count) //等待时间过长,产生停止信号,返回1,表示接收应答失败{//IIC_Stop();return 1;}}	IIC_SCL_L;   //应答成功,则SCL变低return 0;
}	void IIC_Send_Byte(uint8_t data)	 //IIC发送一个字节
{IIC_SCL_L;IIC_Delay;for(int i=0;i<8;i++)         //从高位开始一位一位地传送{		                        //发数据放到数据线上if((data & 0x80)>0)      //当前最高位为1IIC_SDA_H;            //拉高数据线elseIIC_SDA_L;data<<=1;             //数据左移一位IIC_Delay;IIC_SCL_H;IIC_Delay;IIC_SCL_L;          //上一个数据发送完毕,为下一个数据发送准备IIC_Delay;}
}	uint8_t IIC_Read_Byte(unsigned char ack)       //IIC读取一个字节	
{uint8_t read_Data = 0;
//	IIC_SDA_H;	                   //释放总线,此处不释放,另处释放for(int i=0;i<8;i++){IIC_SCL_L;IIC_Delay;IIC_Delay;IIC_SCL_H;        //主机开始读数据,从机不能再改变数据了,即改变SDA的电平read_Data<<=1;if(READ_SDA)read_Data++;IIC_Delay;}if(ack==0) //说明主机不需要给从机应答IIC_NAck();elseIIC_Ack();return read_Data;
}

六、注意事项

1、因为IIC协议本身是不具备任何校验的,所以如果想要保证通信数据的准确性,可以主从机协定好每传输一段数据后带一个校验,以此来验证数据有效性。
2、IIC协议本身很简单,没有太多的约束,所以在跟各种设备通信时,需要注意各自的协议及时序要求。另外因为IIC本身并没有让同一总线上多个设备同步的机制,如果出现主机与从机两个设备通信过程中,因某种异常导致主机复位重启,此时从机还处于接收或发送的状态中,此时可以通过发送 9 个时钟脉冲(SCL高 - 低循环),强制从机释放总线;另外检测SDA线状态,若为低电平则判定总线被占用,继续发送脉冲直至释放。

七、相关链接

【工具使用】STM32CubeMX-硬件IIC配置-实现EEPROM读写功能

http://www.lryc.cn/news/578030.html

相关文章:

  • Flutter视频压缩插件video_compressffmpeg_kit_flutter_new
  • ffmpeg 安装 windows ubuntu
  • Prompt Enginering
  • vue-33(实践练习:使用 Nuxt.js 和 SSR 构建一个简单的博客)
  • 如何通过python脚本向redis和mongoDB传点位数据
  • 十大排序算法汇总
  • (5)pytest-yield操作
  • vscode一个文件夹有残余的git仓库文件,已经失效了,怎样进行清空仓库残余文件并重新初始化git--ubuntu
  • 灌区信息化渠道水位流量监测
  • 设计模式之享元模式深度解析
  • 如何在 iOS 上线前做好安全防护?IPA 混淆与逆向防护实践详解
  • 什么是集装箱残损识别系统?它如何提升港口效率?
  • AI 重塑开发范式:从工具进化到行业重构的深度实践​
  • mysql运维语句
  • 【Unity】MiniGame编辑器小游戏(七)贪吃蛇【Snake】
  • 链表题解——设计链表【LeetCode】
  • C#的datagridview使用总结
  • 复合电流检测方法:原理、技术与应用演进
  • 华为云Flexus+DeepSeek征文 | ​​华为云ModelArts Studio大模型与企业AI会议纪要场景的对接方案
  • GeoTools 结合 OpenLayers 实现属性查询(二)
  • Windows Excel文档办公工作数据整理小工具
  • Day2 音频基础知识
  • API接口安全-2:签名、时间戳与Token如何联手抵御攻击
  • starocks的be参数调优
  • 智能办公与科研革命:ChatGPT+DeepSeek大模型在论文撰写、数据分析与AI建模中的实践指南
  • vue常见问题:
  • 【解析】 微服务测试工具Parasoft SOAtest如何为响应式架构助力?
  • 阿里云计算巢私有化MCP市场:企业级AI工具的安全部署新选择
  • RK3568平台开发系列讲解:HDMI显示驱动
  • 大语言模型 API 进阶指南:DeepSeek 与 Qwen 的深度应用与封装实践