二十三、IIC协议介绍
IIC 协议介绍
什么是 IIC 协议
IIC(Inter-Integrated Circuit)协议也称为 I2C 总线,是一种串行通信协议,通常用于连接低速外设。它由 Philips(现在的 NXP Semiconductors)公司于 1980 年代初开发,现在已经成为一个标准。IIC 总线只需要两条数据线,分别是串行数据线(SDA)和串行时钟线(SCL),这使得它成为一种非常简单的接口。它适用基于芯片的通信,例如连接传感器、存储器或数字信号处理器等。
在 IIC 协议中,总线上有一个主设备和多个从设备。主设备掌控着总线上的通信过程,负责发起、控制、停止通信。而从设备则需要等待主设备的请求,接收或发送数据。主设备和从设备之间的数据交换采用帧格式,每个帧通常包含地址、数据和控制信息。主设备根据从设备的地址来选中要通信的设备,从设备则根据控制信息进行相应的操作。IIC 协议可以支持多个从设备连接到同一个主设备,为系统设计提供了更大的灵活性。
IIC 的硬件实现
I2C 总线通常使用两种电压电平,即高电平(VH)和低电平(VL)。高电平为 2.5V 至 5.5V,低电平为 0V 至 0.3V;这些电压电平范围是根据 I2C 规范确定的。I2C 总线有不同的传输速率可选,包括标准模式(100 kbps)、快速模式(400 kbps)以及高速模式。传输速率的选择取决于应用的需求和设备的支持能力。为避免信号冲突,微处理器(MCU)必须只能驱动 SDA 和 SCL 在低电平,即开漏输出。设置为开漏模式主要是为了保护器件和防止干扰。
- 防止干扰:多个器件共享同一条数据线(SDA)和同一条时钟线(SCL),如果采用推挽输出模式,多个器件的输出将会叠加在数据线上,造成信号干扰,严重时会损坏器件或导致通信错误。而采用开漏输出模式,则各个器件的输出只有拉低数据线的部分,不会干扰彼此,从而提高了总线的可靠性和抗干扰能力。
- 防止短路:在开漏输出模式下,由于器件的输出只有拉低数据线的部分,如果两个或多个器件同时输出,也不会造成短路。而如果采用推挽输出模式,两个或多个器件同时输出时,可能会形成短路。比如主设备输出高电平,从设备输出低电平。
因设置为开漏模式,需要连接一个外部的上拉电阻(例如:10k)将信号提拉至高电平。故 I2C 总线中的 SDA(数据线)和 SCL(时钟线)通常都连接了上拉电阻,以确保逻辑高电平的稳定性。上拉电阻的阻值通常在 2.2kΩ 至 10kΩ 之间,具体取决于总线的电容负载和通信距离。
I2C 总线的最大线缆长度和传输容量受到一定限制。在标准模式下,最大线缆长度大约在 1 米左右,而在快速模式下,最大线缆长度约为 0.3 米。此外,线缆上的总线容量也会对传输速率产生影响。
IIC 数据传输
IIC 只有两根通信线,因此它数据传输是基于时钟信号的。各个设备在时钟信号的控制下进行数据的收发操作。下面是 IIC 总线的几个重要的时序:
起始信号:SCL 在高电平的状态下,SDA 的电平由高转低,表示开始一次通信。
void IIC_Start(void)
{
SDA_OUT();//设置SDA为输出模式
SDA(1);
SCL(1);
delay_us(5);
SDA(0);
delay_us(5);
SCL(0);
delay_us(5);
}
2
3
4
5
6
7
8
9
10
11
停止信号:SCL 在高电平的状态下,SDA 的电平由低转高,表示结束这次通信。主设备在发送停止信号后不能再向从设备发送任何数据,除非再次发送起始信号。
void IIC_Stop(void)
{
SDA_OUT();
SCL(0);
SDA(0);
SCL(1);
delay_us(5);
SDA(1);
delay_us(5);
}
2
3
4
5
6
7
8
9
10
数据传输:主设备和从设备进行数据的传输,可以是一个或多个字节的数据,发送和接收都是基于地址选择的。
//发送一个字节
void IIC_Send_Byte(uint8_t dat)
{
int i = 0;
SDA_OUT();
SCL(0);
for( i = 0; i < 8; i++ )
{
SDA( (dat & 0x80) >> 7 );
delay_us(1);
SCL(1);
delay_us(5);
SCL(0);
delay_us(5);
dat<<=1;
}
}
//接收一个字节
unsigned char IIC_Read_Byte(void)
{
unsigned char i,receive=0;
SDA_IN();//SDA设置为输入
for(i=0;i<8;i++ )
{
SCL(0);
delay_us(5);
SCL(1);
delay_us(5);
receive<<=1;
if( SDA_GET() )
{
receive |= 1;
}
}
SCL(0);
return receive;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
I2C 还提供了一种称为“ACK/NACK”(应答/非应答)的确认机制。如果一个设备接收到数据,它将通过在 SDA 线上拉低电平来发送一个应答信号以通知发送方数据已被接收。相反,如果数据被损坏或未接收,接收设备将发送非应答信号。(在 SDA 上保持高电平)。
void IIC_Send_Ack(void)
{
SDA_OUT();
SCL(0);
SDA(1);
SDA(0);
SCL(1);
delay_us(5);
SCL(0);
SDA(1);
}
2
3
4
5
6
7
8
9
10
11
在 IIC 总线中,时钟线由主设备控制,每个数据位在时钟边沿更新,传输的最高速率取决于总线上最慢的设备。一般来讲,IIC 总线的通信速率比较慢,通常在几百 kbps 的范围内。如果需要更高的传输速率,可以采用其他通信协议,如 SPI 协议、CAN 协议等。
通信流程
I2C 通信流程按照以下步骤进行:
- 主控向总线发送开始信号。
- 主控将要通信的设备地址和读写位(R/W)发送到总线上。
- 设备接收到地址后发送应答信号,主控接收到应答信号后发送数据或继续发送地址。
- 设备接收到数据后发送应答信号,主控接收到应答信号后可以继续发送数据或者停止通信。
- 主控向总线发送停止信号。
发送数据流程
1.5. IIC 基本参数
速率: I2C 总线有标准模式(100 kbit/s)和快速模式(400 kbit/s)两种传输模式,还有更快的扩展模式和高速模式可供选择。
器件地址: 每个设备都有唯一的 7 位或 10 位地址,可以通过地址选择来确定与谁进行通信。
总线状态: I2C 总线有五种状态,分别是空闲状态、起始信号、结束信号、响应信号、数据传输。
数据格式: I2C 总线有两种数据格式,标准格式和快速格式。标准格式是 8 位数据字节加上 1 位 ack/nack(应答/非应答)位,快速格式允许两个字节同时传输。
由于 SCL 和 SDA 线是双向的,它们也可能会由于外部原因(比如线路中的电容等)出现电平误差,而从而导致通信出错。因此,在 IIC 总线中,通常使用上拉电阻来保证信号线在空闲状态下的电平为高电平。
STM32 硬件 I2C 介绍
STM32F407VET6 上带有 3 个硬件 I2C 外设,它是一个内部电路,允许与外部 I2C 接口进行通信。STM32F4 芯片上的硬件 I2C 模块使用特定的引脚复用来进行数据和时钟信号传输。
硬件 I2C 模块的时序控制是由硬件电路和寄存器控制来实现的,这些电路和寄存器负责生成时钟和控制数据线的电平变化,使其符合 I2C 通信协议的时序要求,能够自动处理 I2C 通信所需的时序信号,确保数据的传输在正确的时间轴上进行。通过硬件 I2C 模块的自动控制,时序控制可以更加准确和可靠,从而提高通信的成功率。
硬件 I2C 还可以支持中断和 DMA。它可以通过中断或 DMA 方式与处理器进行通信。这使得处理器可以在数据传输期间进行其他任务,提高了系统的效率和性能。
STM32F407VET6 的硬件 I2C 模块上只支持标准模式(100 kHz)和快速模式(400 kHz),以满足不同应用场景下的通信需求。
硬件 I2C 发送流程
(1)软件初始化
需要配置 I2C 控制器的相关参数,以确保适合所连接设备的通信需求。这包括设置 I2C 速率、地址模式、设备地址等。
(2)设置 START
发送一个起始信号至 I2C 总线,通过设置 I2C 控制器的开始位来启动发送过程。可以通过标志位 SBSEND 判断起始信号是否发送完毕,发送完毕时 SBSEND 标志位会由硬件置一。
(3)清除 SBSEND
SBSEND 为起始信号发送完成标志位,当起始信号发送完成时,会由硬件置一。图中为 10 位地址模式,需要清除起始信号标志位才可进行下一步,但是如果是 7 位地址模式,该标志位不可清除,否则无法进行下一步。
(4) 清除 ADDSEND 位
如果地址为 10 位地址模式,则需要发送两次地址,分别是地址高位和地址低位,先发送高位再发送低位。发送完成 ADD10SEND 和 ADDSEND 会由硬件置一,需要我们分别清除地址发送完成标志位 ADD10SEND 和 ADDSEND。
如果地址为 7 位地址模式,则只需要发送一次地址,并等待标志位 ADDSEND 由硬件置一后,清除 ADDSEND 标志位。
(5) 写入字节数据
写入数据之前,为了防止数据冲突,需要确保发送寄存器里的数据为空。可以通过判断标志位 TBE 判断寄存器中的数据是否为空,为空时 TBE 标志位由硬件置一。发送数据之后需要判断从机是否产生应答,通过 BTC 标志位判断是否发送成功,当发送成功时,BTC 由硬件置一。
(6) 设置 STOP
设置 STOP 即发送停止信号。
以下为具体发送流程图:
硬件 I2C 接收流程
根据图 2-2-1 所示,第一步至第四步的清除 ADDSEND 与硬件 I2C 发送流程一致,这里不再说明,我们从图 2-2-1 第四步中的再次设置 START 开始。
(1)再次设置 START
重新发送起始信号,需要注意的是重新发送之前,必须要先发送停止信号释放总线,让硬件 I2C 成为空闲状态后,才可重新发送起始信号。否则无法进行下一步。
(2)清除 SBSEND
SBSEND 为起始信号发送完成标志位,当起始信号发送完成时,会由硬件置一。图中为 10 位地址模式,需要清除起始信号标志位才可进行下一步,但是如果是 7 位地址模式,该标志位不可清除,否则无法进行下一步。
(3) 清除 ADDSEND 位
如果地址为 10 位地址模式,在清除 ADDSEND 位之前,需要发送两次地址,分别是地址高位和地址低位,先发送高位再发送低位。发送完成 ADD10SEND 和 ADDSEND 会由硬件置一,需要我们分别清除地址发送完成标志位 ADD10SEND 和 ADDSEND。如果地址为 7 位地址模式,则只需要发送一次地址,并等待标志位 ADDSEND 由硬件置一后,清除 ADDSEND 标志位。
(4) 读取字节数据
接收数据可以通过判断标志位 RBNE 确定当前寄存器中是否有数据。RBNE 标志位为数据寄存器为空标志位,当数据寄存器中有接收到数据时,会由硬件将 RBNE 标志位置一,之后我们可以将数据寄存器里的数据取出。读取数据完成之后,我们需要发送应答给从机,从机才会发送下一个数据。通过使能 ACK 应答位,硬件 I2C 会自动通过硬件方式发送应答。
(5)清除 ACKEN,设置 STOP
当最后一个数据需要发送非应答信号时,通过将 ACK 应答位失能,即可发送非应答位。非应答位发送完成之后,紧跟着发送停止信号。
软件 I2C 与硬件 I2C
I2C 协议可以通过软件实现或者硬件实现。这两种方式的区别在于实现的方法和所需的硬件资源。
软件 I2C
软件 I2C 是指通过在程序中编写代码来实现 I2C 通信协议。它利用通用输入输出(GPIO)引脚来模拟 I2C 的数据线(SDA)和时钟线(SCL),通过软件控制引脚的电平变化来传输数据和生成时序信号。与硬件 I2C 相比,软件 I2C 的优势在于不需要特定的硬件支持,可以在任何支持 GPIO 功能的微控制器上实现。它利用了微控制器的通用 IO 引脚来实现 I2C 通信协议。
软件 I2C 的实现通过编程方式来模拟 I2C 的主机和从机设备。通过逐位地读取和写入 GPIO 引脚的状态,并根据 I2C 协议的时序要求进行相应的操作,实现数据的传输和通信。软件 I2C 的灵活性较高,可以根据应用需求进行定制和扩展。它可以处理多个从机设备,并支持多主机环境。因此,软件 I2C 广泛应用于资源受限的 MCU 系统,特别是那些需要与多个外部设备进行通信的应用。
尽管软件 I2C 的性能相对于硬件 I2C 较低,但在一些低速通信和简单通信需求的场景下,软件 I2C 是一种经济实用的解决方案。
硬件 I2C
硬件 I2C 是指通过专门的硬件模块来处理 I2C 通信协议。大多数现代微控制器和一些外部设备已经集成了硬件 I2C 模块,这些硬件模块负责处理 I2C 通信的细节,包括生成正确的时序信号、自动处理信号冲突、数据传输和错误检测等。可以直接使用硬件引脚连接,无需编写时序的代码。
使用硬件 I2C 通常相对简单,开发者无需编写复杂的代码来处理通信协议的细节。硬件模块可以直接与外部设备连接,通过专用的引脚进行数据和时钟传输,从而实现高效且可靠的通信。
在选择软件 I2C 还是硬件 I2C 时,需要考虑应用需求和硬件资源。软件 I2C 适用于资源受限的系统,可以在任何支持 GPIO 的微控制器上实现,但相对性能较低。硬件 I2C 通常性能更好,但需要硬件支持,并且可能占据一些特定的引脚资源。
IIC 优缺点
优点
双向传输: I2C 总线支持双向传输,可以通过 SDA 线同时传输主设备和从设备之间的数据,节约了总线的资源。
系统集成: I2C 总线可以快速集成到芯片中,减少系统实现的逻辑复杂性,提高了设计效率。
多设备共享: I2C 总线可以通过地址传输实现多个设备与主控器的通信,使得多个设备可以共享总线,并直接交互。
高可靠性: I2C 总线使用逻辑层次的代替电气信号来表示数据传输,具有更高的传输可靠性。
缺点
带宽不高: I2C 总线的传输速度限制在 400 kbps,相比较于 SPI 总线和 CAN 总线,带宽相对较低。
时序要求严格: I2C 总线传输数据需要严格遵循时序要求,特别是在高速传输过程,时序容易受到干扰,造成通信失败。
最长电缆长度有限: 虽然 I2C 总线可以通过中继器扩展总线长度,但是由于信号线受到干扰,信号衰减和时序要求等问题,电缆最长长度一般限制在 1~2 米之间。
总之,I2C 总线具有双向传输、系统集成、多设备共享等优点,但传输速度相对较低,时序要求严格且最长电缆长度有限等缺点。
IIC 应用
I2C 总线是应用最广泛的通信接口之一,以下是几个常见的应用例子:
- 温度计传感器:常见的温度计传感器,如 SHT31、LM75 等,都采用 I2C 接口,其通过 I2C 总线将温度数据传输到主控器进行处理。
- LED 驱动器:LED 驱动器,如 PCA9685,常用于控制 LED 灯的亮度和颜色,其通过 I2C 总线和主控器通信,可实现快速和精确定时。
- OLED 显示屏:OLED 显示屏通过 I2C 总线与主控器通信,可实现高清晰度的图形显示,应用于像表盘、智能手表、电子血压计等低功耗设备之中。
- 触摸屏控制器:常见的 15 寸及以下触摸屏控制器,如 STMPE610,都采用 I2C 接口,这些控制器可提供触摸检测和 X/Y 坐标的读取等功能。
- 电流电压采集:电流或电压采集芯片,如 INA219,可通过 I2C 总线和主控器通信,实现精确高速的电流电压数据采集,应用于电源管理和工业自动化等领域。
上述只是常见的应用例子之一,I2C 总线在许多领域都有广泛的应用,具有性价比高、易于移植等优点。