目录
文章目录
前言
目标
内容
I2C通讯规则
I2C写操作
I2C读流程
通讯信号
开始
结束
发送数据
bit发送
Byte发送
等待响应
接收数据
bit接收
Byte接收
发送响应
总结
前言
在现代消费电子和工业电子领域,各种类型的芯片如微控制器、传感器和存储器等,需要快速且可靠地进行数据交互。为了满足这一需求,I2C(Inter-Integrated Circuit)协议应运而生。I2C协议由飞利浦(现恩智浦半导体)公司开发,它利用两根线(时钟线和数据线)在多个设备之间传输数据,并且支持设备间的地址识别,从而实现设备间的互联互通。
本文将深入探讨I2C通讯的原理、信号传输过程以及软件和硬件实现方法。首先,我们将详细介绍I2C通讯的基本规则和流程,包括数据传输的开始、停止和等待响应的过程。其次,将详述如何在软件中实现I2C通讯,包括数据的发送和接收过程。最后,我们将探讨硬件I2C的工作原理和具体实现内容,以帮助读者深入理解这一通用的总线协议。
目标
- 理解I2C通讯原理
- 理解I2C通讯过程中的信号
- 理解软件I2C实现过程
- 理解硬件I2C的工作内容
内容
在消费电子、工业电子等领域,会使用各种类型的芯片,如微控制器、电源管理、显示驱动、传感器、存储器、转换器等,它们有着不同的功能。有时需要快速地进行数据交互。为了使用最简单的方式使这些芯片互联互通,I2C(Inter-Integrated Circuit)协议应运而生。
I2C协议(或称IIC)是由飞利浦(现在的恩智浦半导体)公司开发的一种通用的总线协议。它使用两根线(时钟线和数据线)来传输数据,支持多个设备共享同一条总线。 I2C协议通常用于连接微控制器、传感器、存储器和其他外围设备。
I2C通讯规则
I2C总线包括两根信号线:SDA(串行数据线)和SCL(串行时钟线)。这两根信号线共用一个总线,因此在总线上可以连接多个设备。在I2C总线上,每个设备都有一个唯一的地址,用于标识设备。
SCL线是时钟线,用于控制数据传输的速度和时序;SDA线是数据线,用于传输实际的数据.
I2C写操作
流程如下:
- 开始。
- 发送设备地址,等待从设备响应
- 发送寄存器地址,等待从设备响应
- 发送一个字节,等待从设备响应。这个操作是循环执行,直到没有数据。
- 停止。
I2C读流程
流程如下:
- 开始。
- 发送设备地址(写地址),等待从设备响应
- 发送寄存器地址,等待从设备响应。
- 开始
- 发送设备地址(读地址),等待从设备响应
- 接收一个字节,发送响应给从设备。这个操作是循环执行,直到没有数据。当是最后一个数据时,发送空响应。
- 停止。
通讯信号
开始
static void start() {
SDA_OUT();
SDA(1);
delay_1us(5);
SCL(1);
delay_1us(5);
SDA(0);
delay_1us(5);
SCL(0);
delay_1us(5);
}
结束
static void stop() {
SDA_OUT();
SCL(0);
SDA(0);
SCL(1);
delay_1us(5);
SDA(1);
delay_1us(5);
}
发送数据
bit发送
数据有效性:
- SCL上升沿到下降沿这个阶段,SDA电平的高低,表示数据bit的1和0
- 如果SDA电平在这个阶段发生变化,则无效,参考start和stop信号。
Byte发送
基于数据有效性,将byte按bit位变化为高低电平,发送出去。
static void send(uint8_t data) {
uint8_t i;
SDA_OUT();
for(i = 0; i < 8; i++) {
if(data & 0x80) {
SDA(1);
} else {
SDA(0);
}
SCL(1);
delay_1us(5);
SCL(0);
delay_1us(5);
data <<= 1;
}
}
等待响应
wait ack:Acknowledge character。表示等待响应,每发送一个数据,需要确认对方是否收到,就需要等待对方响应。
static uint8_t wait_ack() {
int8_t retry = 10;
SCL(0);
SDA(1);
SDA_IN();
delay_1us(5);
SCL(1);
delay_1us(5);
while(SDA_STATE() == 1 && retry > 0) {
retry --;
delay_1us(5);
}
if(retry <= 0) {
stop();
return 1;
} else {
SCL(0);
SDA_OUT();
}
return 0;
}
接收数据
bit接收
Byte接收
static uint8_t recv() {
uint8_t i, data;
SDA_IN();
data = 0;
for(i = 0; i < 8; i++) {
SCL(0);
delay_1us(5);
SCL(1);
delay_1us(5);
data <<= 1;
data |= SDA_STATE();
delay_1us(5);
}
SCL(0);
return data;
}
发送响应
static void send_ack(){
// 主机发送ACK响应
// 主机获取SDA控制权,进入输出模式
SDA_OUT();
// 拉低SDA
SDA(0);
DELAY();
// 拉高SCL
SCL(1);
DELAY();
// 拉低SCL
SCL(0);
DELAY();
}
static void send_nack(){
// 主机发送NACK响应
// 主机获取SDA控制权,进入输出模式
SDA_OUT();
// 拉高SDA
SDA(1);
DELAY();
// 拉高SCL
SCL(1);
DELAY();
// 拉低SCL
SCL(0);
DELAY();
}
总结
I2C协议作为一种高效的通信协议,广泛应用于微控制器、传感器和其他外围设备之间的数据交互。通过本文的学习,我们深入理解了I2C通讯的关键概念和步骤:
-
通讯原理和信号: I2C协议使用时钟线(SCL)和数据线(SDA)在多个设备之间传输数据,每个设备通过唯一的地址进行识别。
-
通讯过程: 包括数据的发送(写操作)和接收(读操作)流程,以及等待响应(ACK/NACK)的处理方式。
-
软件实现: 展示了如何在软件中实现I2C通讯,包括发送数据、接收数据以及等待和发送响应的方法。
-
硬件实现: 解释了硬件I2C的工作原理,包括控制信号的生成和处理,以及如何在电路中实现I2C接口。
通过对这些内容的学习,读者可以全面掌握I2C协议的运作机制,为在实际应用中使用I2C进行设备间通讯提供了坚实的理论基础和实践指导。