二十三、 IIC协议介绍
1. IIC协议介绍
1.1 什么是IIC协议
IIC(Inter-Integrated Circuit)协议也称为I2C总线,是一种串行通信协议,通常用于连接低速外设。它由Philips(现在的NXP Semiconductors)公司于1980年代初开发,现在已经成为一个标准。IIC总线只需要两条数据线,分别是串行数据线(SDA)和串行时钟线(SCL),这使得它成为一种非常简单的接口。它适用基于芯片的通信,例如连接传感器、存储器或数字信号处理器等。
在IIC协议中,总线上有一个主设备和多个从设备。主设备掌控着总线上的通信过程,负责发起、控制、停止通信。而从设备则需要等待主设备的请求,接收或发送数据。主设备和从设备之间的数据交换采用帧格式,每个帧通常包含地址、数据和控制信息。主设备根据从设备的地址来选中要通信的设备,从设备则根据控制信息进行相应的操作。IIC协议可以支持多个从设备连接到同一个主设备,为系统设计提供了更大的灵活性。
1.2 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米。此外,线缆上的总线容量也会对传输速率产生影响。
1.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;
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//接收一个字节
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
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
void IIC_Send_Nack(void)
{
SDA_OUT();
SCL(0);
SDA(0);
SDA(1);
SCL(1);
delay_us(5);
SCL(0);
SDA(0);
}
2
3
4
5
6
7
8
9
10
11
在IIC总线中,时钟线由主设备控制,每个数据位在时钟边沿更新,传输的最高速率取决于总线上最慢的设备。一般来讲,IIC总线的通信速率比较慢,通常在几百kbps的范围内。如果需要更高的传输速率,可以采用其他通信协议,如SPI协议、CAN协议等。
1.4 通信流程
I2C通信流程按照以下步骤进行:
- 主控向总线发送开始信号。
- 主控将要通信的设备地址和读写位(R/W)发送到总线上。
- 设备接收到地址后发送应答信号,主控接收到应答信号后发送数据或继续发送地址。
- 设备接收到数据后发送应答信号,主控接收到应答信号后可以继续发送数据或者停止通信。
- 主控向总线发送停止信号。
1.5. IIC基本参数
速率 :I2C总线有标准模式(100 kbit/s)和快速模式(400 kbit/s)两种传输模式,还有更快的扩展模式和高速模式可供选择。
器件地址 :每个设备都有唯一的7位或10位地址,可以通过地址选择来确定与谁进行通信。
总线状态 :I2C总线有五种状态,分别是空闲状态、起始信号、结束信号、响应信号、数据传输。
数据格式 :I2C总线有两种数据格式,标准格式和快速格式。标准格式是8位数据字节加上1位ack/nack(应答/非应答)位,快速格式允许两个字节同时传输。
由于SCL和SDA线是双向的,它们也可能会由于外部原因(比如线路中的电容等)出现电平误差,而从而导致通信出错。因此,在IIC总线中,通常使用上拉电阻来保证信号线在空闲状态下的电平为高电平。
2. HC32硬件I2C介绍
HC32F4A0PITB上带有6个硬件I2C外设,它是一个内部电路,允许与外部I2C接口进行通信。HC32F4A0芯片上的硬件I2C模块使用特定的引脚复用来进行数据和时钟信号传输。
硬件I2C模块的时序控制是由硬件电路和寄存器控制来实现的,这些电路和寄存器负责生成时钟和控制数据线的电平变化,使其符合I2C通信协议的时序要求,能够自动处理I2C通信所需的时序信号,确保数据的传输在正确的时间轴上进行。通过硬件I2C模块的自动控制,时序控制可以更加准确和可靠,从而提高通信的成功率。
硬件I2C还可以支持中断和DMA。它可以通过中断或DMA方式与处理器进行通信。这使得处理器可以在数据传输期间进行其他任务,提高了系统的效率和性能。
HC32F4A0PITB的硬件I2C模块上只支持标准模式(100 kHz)和快速模式(400 kHz),以满足不同应用场景下的通信需求。
2.1 硬件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即发送停止信号。
以下为具体发送流程图:
2.2 硬件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应答位失能,即可发送非应答位。非应答位发送完成之后,紧跟着发送停止信号。
3. 软件I2C与硬件I2C
I2C协议可以通过软件实现或者硬件实现。这两种方式的区别在于实现的方法和所需的硬件资源。
3.1 软件I2C
软件I2C是指通过在程序中编写代码来实现I2C通信协议。它利用通用输入输出(GPIO)引脚来模拟I2C的数据线(SDA)和时钟线(SCL),通过软件控制引脚的电平变化来传输数据和生成时序信号。与硬件I2C相比,软件I2C的优势在于不需要特定的硬件支持,可以在任何支持GPIO功能的微控制器上实现。它利用了微控制器的通用IO引脚来实现I2C通信协议。
软件I2C的实现通过编程方式来模拟I2C的主机和从机设备。通过逐位地读取和写入GPIO引脚的状态,并根据I2C协议的时序要求进行相应的操作,实现数据的传输和通信。软件I2C的灵活性较高,可以根据应用需求进行定制和扩展。它可以处理多个从机设备,并支持多主机环境。因此,软件I2C广泛应用于资源受限的MCU系统,特别是那些需要与多个外部设备进行通信的应用。
尽管软件I2C的性能相对于硬件I2C较低,但在一些低速通信和简单通信需求的场景下,软件I2C是一种经济实用的解决方案。
3.2 硬件I2C
硬件I2C是指通过专门的硬件模块来处理I2C通信协议。大多数现代微控制器和一些外部设备已经集成了硬件I2C模块,这些硬件模块负责处理I2C通信的细节,包括生成正确的时序信号、自动处理信号冲突、数据传输和错误检测等。可以直接使用硬件引脚连接,无需编写时序的代码。
使用硬件I2C通常相对简单,开发者无需编写复杂的代码来处理通信协议的细节。硬件模块可以直接与外部设备连接,通过专用的引脚进行数据和时钟传输,从而实现高效且可靠的通信。 在选择软件I2C还是硬件I2C时,需要考虑应用需求和硬件资源。软件I2C适用于资源受限的系统,可以在任何支持GPIO的微控制器上实现,但相对性能较低。硬件I2C通常性能更好,但需要硬件支持,并且可能占据一些特定的引脚资源。
4. IIC优缺点
4.1 优点
双向传输:I2C总线支持双向传输,可以通过SDA线同时传输主设备和从设备之间的数据,节约了总线的资源。
系统集成:I2C总线可以快速集成到芯片中,减少系统实现的逻辑复杂性,提高了设计效率。
多设备共享:I2C总线可以通过地址传输实现多个设备与主控器的通信,使得多个设备可以共享总线,并直接交互。
高可靠性:I2C总线使用逻辑层次的代替电气信号来表示数据传输,具有更高的传输可靠性。
4.2 缺点
带宽不高:I2C总线的传输速度限制在400 kbps,相比较于SPI总线和CAN总线,带宽相对较低。
时序要求严格:I2C总线传输数据需要严格遵循时序要求,特别是在高速传输过程,时序容易受到干扰,造成通信失败。
最长电缆长度有限:虽然I2C总线可以通过中继器扩展总线长度,但是由于信号线受到干扰,信号衰减和时序要求等问题,电缆最长长度一般限制在1~2米之间。
总之,I2C总线具有双向传输、系统集成、多设备共享等优点,但传输速度相对较低,时序要求严格且最长电缆长度有限等缺点。
5. IIC应用
I2C总线是应用最广泛的通信接口之一,以下是几个常见的应用例子:
- 温度计传感器:常见的温度计传感器,如SHT31、LM75等,都采用I2C接口,其通过I2C总线将温度数据传输到主控器进行处理。
- LED驱动器:LED驱动器,如PCA9685,常用于控制LED灯的亮度和颜色,其通过I2C总线和主控器通信,可实现快速和精确定时。
- OLED显示屏:OLED显示屏通过I2C总线与主控器通信,可实现高清晰度的图形显示,应用于像表盘、智能手表、电子血压计等低功耗设备之中。
- 触摸屏控制器:常见的15寸及以下触摸屏控制器,如STMPE610,都采用I2C接口,这些控制器可提供触摸检测和X/Y坐标的读取等功能。
- 电流电压采集:电流或电压采集芯片,如INA219,可通过I2C总线和主控器通信,实现精确高速的电流电压数据采集,应用于电源管理和工业自动化等领域。
上述只是常见的应用例子之一,I2C总线在许多领域都有广泛的应用,具有性价比高、易于移植等优点。