软件IIC和硬件IIC的引脚配置有什么区别?

STM32的硬件IIC和软件模拟IIC在引脚配置上有根本性的区别

下面是两者的核心区别对比:

特性 硬件IIC 软件模拟IIC (Software IIC)
引脚要求 必须 使用芯片指定的、具有I2C外设功能复用的特定引脚 几乎任意通用输入输出(GPIO)引脚都可以。
配置模式 将GPIO模式设置为 GPIO_Mode_AF_OD (复用开漏输出)。 将GPIO模式设置为 GPIO_Mode_Out_OD (通用开漏输出)或使用推挽输出加外部上拉。
初始化内容 需要初始化两个部分 : 1. GPIO引脚 2. I2C外设本身(如I2C1) 只需要初始化GPIO引脚。所有时序都由软件代码控制。
内部上拉电阻 通常禁用 内部上拉,依赖外部上拉电阻(4.7kΩ),以确保总线兼容性和可靠性。 强烈建议 使用外部上拉电阻(4.7kΩ),禁用内部上拉。
灵活性 。引脚由芯片数据手册(Datasheet)的引脚定义表固定死,不可更改。 极高。可以任意更换到其他GPIO引脚,无需修改硬件电路。
性能 。由硬件处理,占用CPU资源少,速度稳定且快。 。由CPU循环模拟,占用大量CPU资源,速度慢且受其他中断影响。
可靠性 。硬件处理时序精确,抗干扰能力强。 较低。时序由软件延时保证,在复杂中断环境中容易出错。

详细配置代码对比

假设我们使用STM32F103系列芯片,操作I2C1,其硬件I2C引脚通常是PB6(SCL)PB7(SDA)

1. 硬件IIC配置

硬件IIC的配置分为两大步:配置GPIO配置I2C外设

c 复制代码
/* 硬件IIC引脚配置函数 */
void HW_I2C_GPIO_Config(void) {
    GPIO_InitTypeDef GPIO_InitStructure;
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE);
    
    // 配置I2C1 SCL (PB6) 和 SDA (PB7)
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
    // 关键区别:模式必须设置为 **复用开漏输出**
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD; 
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; // 速度建议设置高一些
    GPIO_Init(GPIOB, &GPIO_InitStructure);
}

/* 硬件IIC外设模式配置函数 */
void HW_I2C_Mode_Config(void) {
    I2C_InitTypeDef I2C_InitStructure;
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE); // I2C1时钟位于APB1总线
    
    I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;
    I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;
    I2C_InitStructure.I2C_OwnAddress1 = 0x00; // 作为主设备,此地址可任意,不冲突即可
    I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;
    I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
    I2C_InitStructure.I2C_ClockSpeed = 400000; // 400kHz
    I2C_Init(I2C1, &I2C_InitStructure);
    
    I2C_Cmd(I2C1, ENABLE); // 使能I2C1
}

// 在主函数中,需要调用以上两个函数来完成完整初始化
void main() {
    ...
    HW_I2C_GPIO_Config();
    HW_I2C_Mode_Config();
    ...
}
2. 软件模拟IIC (Software IIC) 配置

软件IIC只需要配置GPIO,非常灵活。这里我们仍然使用PB6和PB7,但你完全可以换成PC0和PC1等其他引脚。

c 复制代码
// 首先进行宏定义,方便后续编程和修改引脚
#define SOFT_I2C_SDA_PORT    GPIOB
#define SOFT_I2C_SDA_PIN     GPIO_Pin_7
#define SOFT_I2C_SCL_PORT    GPIOB
#define SOFT_I2C_SCL_PIN     GPIO_Pin_6

#define SOFT_I2C_SDA_HIGH()  GPIO_SetBits(SOFT_I2C_SDA_PORT, SOFT_I2C_SDA_PIN)
#define SOFT_I2C_SDA_LOW()   GPIO_ResetBits(SOFT_I2C_SDA_PORT, SOFT_I2C_SDA_PIN)
#define SOFT_I2C_SCL_HIGH()  GPIO_SetBits(SOFT_I2C_SCL_PORT, SOFT_I2C_SCL_PIN)
#define SOFT_I2C_SCL_LOW()   GPIO_ResetBits(SOFT_I2C_SCL_PORT, SOFT_I2C_SCL_PIN)
#define SOFT_I2C_SDA_READ()  GPIO_ReadInputDataBit(SOFT_I2C_SDA_PORT, SOFT_I2C_SDA_PIN)

/* 软件IIC GPIO配置函数 */
void SOFT_I2C_GPIO_Config(void) {
    GPIO_InitTypeDef GPIO_InitStructure;
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
    
    // 配置SCL引脚为**通用开漏输出**
    GPIO_InitStructure.GPIO_Pin = SOFT_I2C_SCL_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD; // 关键区别:通用开漏输出
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(SOFT_I2C_SCL_PORT, &GPIO_InitStructure);
    
    // 配置SDA引脚,初始化为开漏输出。在读取时会临时切换为输入模式。
    GPIO_InitStructure.GPIO_Pin = SOFT_I2C_SDA_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD; // 关键区别:通用开漏输出
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(SOFT_I2C_SDA_PORT, &GPIO_InitStructure);
    
    // 将总线置于空闲状态(高电平)
    SOFT_I2C_SCL_HIGH();
    SOFT_I2C_SDA_HIGH();
}

// 之后,你需要用软件代码模拟I2C的时序,例如:
void SOFT_I2C_Start(void) {
    SOFT_I2C_SDA_HIGH();
    SOFT_I2C_SCL_HIGH();
    Delay_us(5);
    SOFT_I2C_SDA_LOW(); // Start condition: SDA falls while SCL is high
    Delay_us(5);
    SOFT_I2C_SCL_LOW();
}
// ... 还需要实现Stop、SendByte、ReceiveByte等函数

总结与选择建议

场景 推荐方案 理由
高速、高可靠性、多从机通信 硬件IIC 硬件处理效率高,不占用CPU,时序精确稳定。
引脚冲突,硬件IIC引脚被占用 软件IIC 可以灵活更换到其他任意引脚。
学习、调试、快速验证 软件IIC 配置简单,便于理解I2C协议本质,调试时可用逻辑分析仪抓波形。
项目初期,硬件设计未定型 软件IIC 即使后期硬件引脚变更,软件也只需修改宏定义,无需大改。
需要同时使用多个I2C总线 组合使用 STM32通常只有1-2个硬件I2C,可用硬件I2C操作主要设备,软件I2C操作次要设备。

核心记住一点:硬件IIC的引脚是芯片固定的,而软件IIC的引脚是你自己任选的。 硬件IIC需要配置外设模式,软件IIC只需要配置GPIO模式并为它们编写模拟时序的函数。无论是软件IIC抑或是硬件IIC都依赖于外部上拉电阻来确保线兼容性和可靠性,这个电阻通常可以取4.7K。

相关推荐
百里东风3 小时前
配置AC5(ARM Compiler 5)编译器
arm开发·stm32·单片机
你好,奋斗者!4 小时前
单片机引脚的高电平和低电平范围值
单片机·嵌入式硬件·嵌入式软件
眰恦ゞLYF5 小时前
嵌入式硬件——IMX6ULL时钟配置
单片机·嵌入式硬件·时钟·imx6ull
小莞尔5 小时前
【51单片机】【protues仿真】基于51单片机秒表系统(LCD1602多功能、可保持30条记录)
c语言·stm32·单片机·嵌入式硬件·51单片机
Tolines6 小时前
PCIe外接卡标准尺寸
嵌入式硬件·硬件工程·设计规范
寅双木6 小时前
常见的九种二极管
笔记·嵌入式硬件·稳压二极管·tvs·肖特基二极管·发光二极管·齐纳击穿
Black doncky prince6 小时前
QR反激电源副边整流二极管电压波形分析
单片机·嵌入式硬件·硬件工程
currycheng66 小时前
开关电源测试及方法
单片机·嵌入式硬件·硬件架构·硬件工程
SundayBear7 小时前
基于MCU的文件系统
linux·服务器·单片机