news 2026/4/16 18:12:45

简单理解:软件 I2C 和硬件 I2C 的区别

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
简单理解:软件 I2C 和硬件 I2C 的区别

通过代码直观看到软件 I2C 和硬件 I2C 的区别,这个思路特别好!我以 STM32F103 为例,分别给出驱动同一个 I2C 设备(比如温湿度传感器)的核心代码,你对比着看就能立刻明白差异。

一、软件 I2C 核心代码(模拟时序)

软件 I2C 完全用 GPIO 口模拟 SCL/SDA 的高低电平变化,所有时序都靠代码手动控制:

#include "stm32f10x.h" // 定义软件I2C引脚(可任意选GPIO) #define I2C_SCL_PIN GPIO_Pin_0 #define I2C_SDA_PIN GPIO_Pin_1 #define I2C_GPIO_PORT GPIOB #define I2C_GPIO_CLK RCC_APB2Periph_GPIOB // 引脚电平控制(核心:手动改电平) #define SCL_HIGH() GPIO_SetBits(I2C_GPIO_PORT, I2C_SCL_PIN) #define SCL_LOW() GPIO_ResetBits(I2C_GPIO_PORT, I2C_SCL_PIN) #define SDA_HIGH() GPIO_SetBits(I2C_GPIO_PORT, I2C_SDA_PIN) #define SDA_LOW() GPIO_ResetBits(I2C_GPIO_PORT, I2C_SDA_PIN) #define SDA_READ() GPIO_ReadInputDataBit(I2C_GPIO_PORT, I2C_SDA_PIN) // 软件I2C初始化(就是配置GPIO为推挽输出) void Soft_I2C_Init(void) { GPIO_InitTypeDef GPIO_InitStruct; RCC_APB2PeriphClockCmd(I2C_GPIO_CLK, ENABLE); // SCL引脚配置 GPIO_InitStruct.GPIO_Pin = I2C_SCL_PIN; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(I2C_GPIO_PORT, &GPIO_InitStruct); // SDA引脚配置 GPIO_InitStruct.GPIO_Pin = I2C_SDA_PIN; GPIO_Init(I2C_GPIO_PORT, &GPIO_InitStruct); // 初始电平拉高 SCL_HIGH(); SDA_HIGH(); } // 软件I2C起始信号(手动模拟时序) void Soft_I2C_Start(void) { SDA_HIGH(); SCL_HIGH(); delay_us(2); // 必须加延时保证时序,否则通信失败 SDA_LOW(); delay_us(2); SCL_LOW(); } // 软件I2C发送一个字节(每一位都要手动控制时钟) uint8_t Soft_I2C_Send_Byte(uint8_t data) { uint8_t i; for(i=0; i<8; i++) // 逐位发送 { if(data & 0x80) SDA_HIGH(); // 最高位先发送 else SDA_LOW(); data <<= 1; SCL_HIGH(); // 时钟拉高,从机读取数据 delay_us(2); SCL_LOW(); // 时钟拉低,准备下一位 delay_us(2); } // 等待从机应答 SDA_HIGH(); SCL_HIGH(); delay_us(2); uint8_t ack = SDA_READ(); SCL_LOW(); return ack; } // 其他停止、接收字节等函数都是类似的手动时序控制...

二、硬件 I2C 核心代码(外设自动处理)

硬件 I2C 只需要配置寄存器,剩下的时序由硬件自动完成:

#include "stm32f10x.h" #define I2Cx I2C1 #define I2C_CLK RCC_APB1Periph_I2C1 #define I2C_GPIO_CLK RCC_APB2Periph_GPIOB #define I2C_SCL_PIN GPIO_Pin_6 #define I2C_SDA_PIN GPIO_Pin_7 // 硬件I2C初始化(配置外设参数,引脚是固定的) void Hard_I2C_Init(void) { GPIO_InitTypeDef GPIO_InitStruct; I2C_InitTypeDef I2C_InitStruct; // 1. 使能时钟 RCC_APB1PeriphClockCmd(I2C_CLK, ENABLE); RCC_APB2PeriphClockCmd(I2C_GPIO_CLK, ENABLE); // 2. 配置引脚为复用开漏输出(硬件I2C必须用固定引脚+复用模式) GPIO_InitStruct.GPIO_Pin = I2C_SCL_PIN | I2C_SDA_PIN; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_OD; // 复用开漏 GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStruct); // 3. 配置I2C外设参数 I2C_DeInit(I2Cx); I2C_InitStruct.I2C_Mode = I2C_Mode_I2C; I2C_InitStruct.I2C_DutyCycle = I2C_DutyCycle_2; I2C_InitStruct.I2C_OwnAddress1 = 0x00; // 主机模式,自己的地址随便设 I2C_InitStruct.I2C_Ack = I2C_Ack_Enable; I2C_InitStruct.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; I2C_InitStruct.I2C_ClockSpeed = 400000; // 400KHz高速模式 I2C_Cmd(I2Cx, ENABLE); I2C_Init(I2Cx, &I2C_InitStruct); } // 硬件I2C发送一个字节(调用外设函数,不用管时序) void Hard_I2C_Send_Byte(uint8_t addr, uint8_t data) { // 1. 等待I2C总线空闲 while(I2C_GetFlagStatus(I2Cx, I2C_FLAG_BUSY)); // 2. 发送起始信号(硬件自动生成时序) I2C_GenerateSTART(I2Cx, ENABLE); while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_MODE_SELECT)); // 3. 发送设备地址(硬件自动处理时钟和应答) I2C_Send7bitAddress(I2Cx, addr, I2C_Direction_Transmitter); while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)); // 4. 发送数据(硬件自动移位,不用逐位控制) I2C_SendData(I2Cx, data); while(!I2C_CheckEvent(I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED)); // 5. 发送停止信号 I2C_GenerateSTOP(I2Cx, ENABLE); }

三、核心区别一眼看明白

对比项软件 I2C硬件 I2C
引脚控制任意 GPIO,手动改高低电平固定引脚,复用模式,硬件自动控制
时序实现靠 delay_us () 和循环逐位模拟硬件逻辑自动生成,无需手动延时
CPU 占用高(全程要 CPU 盯着)低(配置完 CPU 可干别的)
代码复杂度简单(直接操作 GPIO)稍复杂(配置外设寄存器)
灵活性极高(可自定义时序)低(引脚 / 时序固定)

总结

  1. 软件 I2C:像你手动掰开关控制电路,代码直观、引脚随便选,但要自己控制每一步时序,CPU 不能干别的;
  2. 硬件 I2C:像你给机器人下指令,只需要告诉它 “发什么数据”,剩下的由硬件自动完成,CPU 解放出来,但必须用固定引脚;
  3. 新手做简单项目(比如读单个传感器)选软件 I2C 更易上手,需要高频通信 / 多设备时选硬件 I2C 更稳定。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/16 10:32:50

英文文献检索网站有哪些:常用平台及资源指南

一、WisPaper&#xff1a;智能学术搜索激发科研灵感 科研创新的关键是了解前沿&#xff0c;找到突破口。但传统查文献方式往往效率低&#xff1a; Google Scholar 或 arXiv 搜索结果太多&#xff0c;难以筛选公众号推送滞后&#xff0c;容易错过最新研究文献阅读时间长&#…

作者头像 李华
网站建设 2026/4/16 14:29:59

基于MATLAB R2025a的图像分类与检索系统设计与实现

基于MATLAB R2025a的图像分类与检索系统设计与实现 摘要 本文详细介绍了基于MATLAB R2025a开发的图像分类与检索系统。该系统实现了图像资源的高效组织与储存、自动识别并归类图像内容、多种属性识别、相似度检索以及图形用户界面整合等核心功能。系统还扩展了人工干预提升搜…

作者头像 李华
网站建设 2026/4/16 12:29:07

AI科研转化平台:让实验室技术“走出论文”变产品

高校实验室里的AI算法准确率高达95%&#xff0c;却只能躺在论文里&#xff1b;企业急需解决生产痛点&#xff0c;却找不到能直接用的技术&#xff1b;科研人员熬夜研发的模型&#xff0c;因缺产业数据和落地场景被束之高阁——这是AI领域最突出的“转化困境”。而AI科研转化一体…

作者头像 李华
网站建设 2026/4/16 12:25:56

Stable Diffusion 3.0:开启企业专属品牌视觉模型新时代

一、引言 在当今 AI 绘画领域,Stable Diffusion 3.0 凭借其强大的性能和广泛的应用,已然成为了众多开发者和企业关注的焦点。它基于先进的深度学习算法,能够根据用户输入的文本描述,生成高质量、多样化的图像,在艺术创作、设计、影视等诸多行业展现出巨大的价值。从艺术创…

作者头像 李华
网站建设 2026/4/16 14:01:43

全栈式智慧园区管理系统:技术架构、场景落地与效能革新

当传统园区还困于 “人工巡检效率低、设备故障响应慢、空间资源调度乱” 的痛点时&#xff0c;以物联网、数字孪生、边缘计算为核心的智慧园区管理系统&#xff0c;正成为城市产业载体升级的核心引擎。YUNMELL 云迈科技推出的全栈式智慧园区管理系统&#xff0c;通过 “项目空间…

作者头像 李华