什么是IIC通信协议?

IIC(Inter-Integrated Circuit)通信协议,又称为I2C(Inter-Integrated Circuit 2)协议,是一种广泛使用的串行通信协议。它由飞利浦半导体公司(现NXP Semiconductors)开发,用于连接微控制器和其他设备,实现数据的串行传输。

IIC协议的基本原理

I2C协议使用两条线进行通信:数据线(SDA)和时钟线(SCL)。这两条线通过上拉电阻连接到电源,确保在空闲状态下保持高电平。I2C协议支持多主设备和多个从设备,通过每个设备的地址来区分通信目标。

IIC协议的关键特性

  1. 双向通信:I2C协议支持双向数据传输,即主设备可以发送数据给从设备,也可以从从设备接收数据。
  2. 多主模式:允许多个主设备连接到同一条总线上,通过仲裁机制来选择唯一的主设备进行通信。
  3. 多从模式:I2C总线可以连接多个从设备,每个从设备都有唯一的地址,主设备通过地址来选择要通信的从设备。
  4. 速率灵活:I2C总线的速率可以根据应用需求进行调整,常见的速率有100 kHz(标准模式)、400 kHz(快速模式)和3.4 MHz(高速模式)。
  5. 低成本:I2C总线只需要两根线进行通信,降低了硬件成本和复杂性。

IIC协议的应用场景

I2C协议被广泛应用于各种数字芯片间的通信,例如:

  • 传感器与微控制器之间的通信:如温度传感器、湿度传感器、加速度计等。
  • 存储器芯片:如EEPROM和RTC芯片,用于数据的读写和时钟管理。
  • 控制外设设备:如LED驱动器、LCD控制器、扩展IO芯片等。
  • 显示器控制器:如OLED显示屏、液晶显示模块等。
  • 工业自动化领域:如工业传感器、PLC等。

IIC协议的通信过程

I2C通信过程包括以下几个步骤:

  1. 起始信号:主设备发送一个起始信号,表示开始通信。
  2. 发送从设备地址:主设备发送从设备的地址和读/写位。
  3. 应答信号:从设备确认收到地址并发送应答信号。
  4. 数据传输:主设备和从设备之间进行数据的发送和接收。
  5. 停止信号:通信完成后,主设备发送停止信号,表示通信结束。

IIC协议的代码示例

以下是一个简单的I2C通信的代码示例,展示了如何使用STM32微控制器通过软件模拟I2C协议来读取AT24C02 EEPROM的数据。

#include "stm32f10x.h"
#include "delay.h"

#define I2C_SCL_PIN GPIO_Pin_6 // 定义SCL引脚
#define I2C_SDA_PIN GPIO_Pin_7 // 定义SDA引脚
#define I2C_SCL_PORT GPIOB // 定义SCL引脚所在的端口
#define I2C_SDA_PORT GPIOB // 定义SDA引脚所在的端口

// I2C延时函数
void I2C_Delay(void) {
    delay_us(5);
}

// I2C初始化函数
void I2C_Init(void) {
    GPIO_InitTypeDef GPIO_InitStructure;
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
    GPIO_InitStructure.GPIO_Pin = I2C_SCL_PIN | I2C_SDA_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(I2C_SCL_PORT, &GPIO_InitStructure);
    
    // 释放总线
    I2C_SCL_PORT->BSRR = I2C_SCL_PIN;
    I2C_SDA_PORT->BSRR = I2C_SDA_PIN;
}

// I2C起始信号
void I2C_Start(void) {
    I2C_SDA_PORT->BSRR = I2C_SDA_PIN; // SDA高电平
    I2C_Delay();
    I2C_SCL_PORT->BSRR = I2C_SCL_PIN; // SCL高电平
    I2C_Delay();
    I2C_SDA_PORT->BRR = I2C_SDA_PIN; // SDA低电平,开始信号
    I2C_Delay();
    I2C_SCL_PORT->BRR = I2C_SCL_PIN; // SCL低电平
}

// I2C停止信号
void I2C_Stop(void) {
    I2C_SDA_PORT->BRR = I2C_SDA_PIN; // SDA低电平
    I2C_Delay();
    I2C_SCL_PORT->BSRR = I2C_SCL_PIN; // SCL高电平
    I2C_Delay();
    I2C_SDA_PORT->BSRR = I2C_SDA_PIN; // SDA高电平,停止信号
}

// I2C发送一个字节
void I2C_SendByte(uint8_t byte) {
    uint8_t i;
    for (i = 0; i < 8; i++) {
        I2C_SDA_PORT->BRR = I2C_SDA_PIN; // SDA低电平
        if (byte & 0x80) {
            I2C_SDA_PORT->BSRR = I2C_SDA_PIN; // SDA高电平
        }
        I2C_Delay();
        I2C_SCL_PORT->BSRR = I2C_SCL_PIN; // SCL高电平
        I2C_Delay();
        I2C_SCL_PORT->BRR = I2C_SCL_PIN; // SCL低电平
        byte <<= 1;
    }
    I2C_SDA_PORT->BSRR = I2C_SDA_PIN; // SDA释放,准备接收应答
    I2C_Delay();
    I2C_SCL_PORT->BSRR = I2C_SCL_PIN; // SCL高电平
    I2C_Delay();
    I2C_SCL_PORT->BRR = I2C_SCL_PIN; // SCL低电平
}

// I2C读取一个字节
uint8_t I2C_ReadByte() {
    uint8_t i, byte = 0;
    I2C_SDA_PORT->ODR &= ~I2C_SDA_PIN; // SDA输入模式
    for (i = 0; i < 8; i++) {
        byte <<= 1;
        I2C_SCL_PORT->BSRR = I2C_SCL_PIN; // SCL高电平
        I2C_Delay();
        if (I2C_SDA_PORT->IDR & I2C_SDA_PIN) {
            byte |= 0x01;
        }
        I2C_SCL_PORT->BRR = I2C_SCL_PIN; // SCL低电平
        I2C_Delay();
    }
    return byte;
}

// 从AT24C02读取一个字节数据
uint8_t AT24C02_ReadByte(uint16_t addr) {
    uint8_t data;
    I2C_Start();
    I2C_SendByte(0xA0 << 1); // 发送设备地址和写命令
    I2C_WaitAck();
    I2C_SendByte(addr >> 8); // 发送高地址字节
    I2C_WaitAck();
    I2C_SendByte(addr & 0xFF); // 发送低地址字节
    I2C_WaitAck();
    I2C_Start();
    I2C_SendByte(0xA1 << 1); // 发送设备地址和读命令
    I2C_WaitAck();
    data = I2C_ReadByte();
    I2C_Stop();
    return data;
}

int main(void) {
    I2C_Init();
    uint8_t data = AT24C02_ReadByte(0x00); // 从地址0x00读取数据
    // ... 其他操作
    while (1) {
        // ... 主循环
    }
}

以上代码展示了如何初始化I2C接口,发送起始和停止信号,以及如何发送和接收数据。在实际应用中,可能需要根据具体的硬件连接和设备地址进行适当的调整。通过理解和掌握I2C协议的原理和编程方法,可以实现微控制器与其他设备的高效通信。

✅作者简介:热爱科研的嵌入式开发者,修心和技术同步精进

❤欢迎关注我的知乎:对error视而不见

代码获取、问题探讨及文章转载可私信。

☁ 愿你的生命中有够多的云翳,来造就一个美丽的黄昏。

🍎获取更多嵌入式资料可点击链接进群领取,谢谢支持!👇

点击领取更多详细资料

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AI_Guru人工智能

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值