如今,协议在嵌入式系统设计中起着至关重要的作用。没有协议,如果要扩展单片机的外围功能,复杂度和功耗都会增加。目前有不同类型的总线协议可用,例如USART、SPI、CAN、I2C总线协议等,它们用于在两个系统之间传输数据。
在这其中,I2C总线协议应用最为广泛,它是一种用于连接芯片的串行通信协议。它允许多个芯片在同一个总线上进行通信,因此被称为多主机总线,如今在很多现代数字电路中得到了广泛的应用。
1、什么是I2C(I2C Bus)总线?
I2C(Inter-Integrated Circuit,简写为I²C)总线是在两个或两个以上的设备之间传输和接收信息需要一条称为总线系统的通信路径。I2C总线是一种双向双线串行总线,用于在集成电路之间传输数据。目前大多数电子芯片都支持I2C总线协议。
I2C 代表“内部集成电路”,由飞利浦半导体公司于1982年率先推出。I2C总线由标准、快速模式和高速模式三种数据传输速度组成。I2C总线支持7位和10位地址空间设备,其操作因低电压而异。
2、I2C信号线(I2C Signal Lines)
I2C是一种串行总线协议,它由两条信号线组成,例如用于与设备通信的SCL和SDL线。SCL代表“串行时钟线”,该信号始终由“主设备”驱动。SDL代表“串行数据线”,该信号由主设备或I2C外设驱动。当I2C外设之间没有传输时,SCL和SDL线都处于漏极开路状态。
3、开漏输出
开漏输出是FET晶体管的概念,其中晶体管的漏极端子处于开路状态。主设备的SDL和SCL引脚设计为晶体管处于开路状态,因此只有在这些晶体管导通时才能进行数据传输。所以,这些总线或漏极端子通过上拉电阻连接到VCC以实现导通模式。
4、I2C接口(I2C Interfaces)
许多从设备在I2C总线的帮助下通过I2C电平转换器IC连接到微控制器,以在它们之间传输信息。I2C协议用于连接最多128个设备,这些设备全部连接以与主单元以及从设备的SCL和SDL线进行通信。它支持多主机通信,即使用两个主机与外部设备进行通信。
5、I2C数据传输速率
I2C协议运行三种模式,分别是快速模式、高速模式和标准模式,其中标准模式数据速率范围为0Hz至100Hz,快速模式数据可以以0Hz至400KHz的速度传输,高速模式为10千赫兹到100赫兹。每次传输都发送9位数据,其中8位由发送器MSB发送到LSB,第9位是接收器发送的确认位。
I2C总线协议最常用于主从通信,其中主设备称为“微控制器”,从设备称为嵌入式系统中的ADC、EEPROM、DAC等其他设备。多个从设备借助I2C总线连接到主设备,其中每个从设备都包含一个唯一的地址以进行通信。以下步骤用于主设备与从设备通信:
相对于时钟脉冲逐级串行发送和接收信息称为I2C协议,它是一种系统间和短距离协议,这意味着它用于电路板内的主从设备通信。
1、I2C协议基础知识
一般来说,I2C总线系统由两根线组成,可以方便地扩展输入输出外设功能,如ADC、EEROM和RTC等基本元器件,使系统复杂度非常低。
典型示例:由于8051微控制器没有内置ADC——因此,如果想将任何模拟传感器连接到8051微控制器——必须使用ADC设备,例如ADC0804-1通道 ADC、ADC0808-8通道ADC等。通过使用这些ADC,可以将模拟传感器连接到微控制器。
在不使用协议扩展任何微控制器或处理器的I/O功能的情况下,可以转到8255 8引脚设备。8051单片机是40脚单片机,通过使用8255 IC,可以扩展3个I/O端口,每个端口有8个引脚。通过使用RTC、ADC、EEPROM、定时器等所有设备来扩展外围电路,复杂性、成本、功耗和产品尺寸也会增加。
为了克服这个问题,协议概念出现了,以降低硬件复杂性和功耗。通过使用此I2C协议,可以扩展更多功能,例如个I/O外设、ADC、T/C和内存设备,最多可扩展到128个设备。
2、I2C协议中使用的术语
3、I2C基本命令序列
当主机(微控制器)希望与从设备(例如ADC)通信时,它通过在I2C总线上发出开始条件开始通信,然后发出停止条件。I2C启动和停止逻辑电平如下图所示。
I2C启动条件定义为SCL线为高时SDA线从高到低的转换。当SCL线为高电平时SDA线从低电平切换到高电平时,会出现I2C停止条件。I2C主机始终生成S和P条件。一旦I2C主机启动START条件,I2C总线就被认为处于忙碌状态。
启动条件代码如下:
sbit SDA=P1^7; // initialize the SDA and SCL pins of the microcontroller//
sbit SCL=P1^6;
void delay(unsigned int);
void main ()
{
SDA=1; //processing the data//
SCL=1; //clock is high//
delay();
SDA=0; //sent the data//
delay();
SCL=0; //clock signal is low//
}
Void delay(int p)
{
unsignedinta,b;
For(a=0;a<255;a++); //delay function//
For(b=0;b<p;b++);
}
停止条件代码如下:
void main ()
{
SDA=0; // Stop processing the data//
SCL=1; //clock is high//
delay();
SDA=1; //Stopped//
delay();
SCL=0; //clock signal is low//
}
Void delay(int p)
{
unsignedinta,b;
For(a=0;a<255;a++); //delay function//
For(b=0;b<p;b++);
}
通过I2C总线传输的每个字节后面都跟着来自接收器的确认条件,这意味着在主机将SCL拉低以完成8位的传输后,SDA将被接收器拉低到主机。如果,在接收端没有拉高传输后,SDA线为LOW,则认为是NCK条件。

确认代码如下:
Acknowledgement
void main()
{
SDA=0; //SDA line goes to low//
SCL=1; //clock is high to low//
delay(100);
SCL=0;
}
无确认代码如下:void main()
{
SDA=1; //SDA line goes to high//
SCL=1; //clock is high to low//
delay(100);
SCL=0;
}
I2C协议以数据包或字节的形式传输数据,每个字节后跟一个确认位,数据传输格式如下图所示:
写操作代码如下:
voidwrite (unsigned char d)
{
Unsigned char k, j=0x80;
For(k=0;k<8;k++)
{
SDA=(d&j);
J=j>>1;
SCL=1;
delay(4);
SCL=0;
}
SDA=1;
SCL=1;
delay(2);
c=SDA;
delay(2);
SCL=0;
}
数据以位或字节的形式从从设备读回——首先读取最高有效位,最后读取最低有效位,其数据读取格式如下:
读操作代码如下:
Void read ()
{
Unsigned char j, z=0x00, q=0x80;
SDA=1;
for(j=0;j<8;j++)
{
SCL=1;
delay(100);
flag=SDA;
if(flag==1)
{
z=(z|q);
q=q>>1;
delay(100);
SCL=0;
}
ADC是一种用于将模拟数据转换为数字形式和数字到模拟的设备。8051单片机没有内置ADC,只能通过I2C协议外加。PCF8591是基于I2C的数模和数模转换器。该设备最多可支持4个模拟输入通道以及2.5至6V电压。
模拟输出
模拟输出以电压的形式出现。例如,5V模拟传感器给出0.01V至5V的输出逻辑。5V的最大数字值为=256。2.5V的值根据最大电压值=123。
模拟量输出公式为:

数字输出公式为:
此外,下图显示了使用I2C协议从ADC设备到8051微控制器的数据传输。SCL和SDA的ADC引脚连接到单片机的1.7和1.6引脚,用于建立它们之间的通信。当传感器将模拟值提供给 ADC时,它会转换为数字值并通过I2C协议将数据传输到微控制器。
I2C总线协议通常由两个线路组成:串行数据线(SDA)和串行时钟线(SCL)。SDA和SCL线被连接到每个使用I2C协议的芯片上。总线上的设备可以充当主机或从机,主机发起I2C传输并控制总线上的所有其他设备。从机只能在主机的请求下发送或接收数据。
在I2C总线上,每个设备都有一个唯一的7位或10位地址,主机向设备发送数据时需要指定地址。数据传输由主机发起,它向总线上的一个设备发送一个起始位,然后向这个设备传输它的地址和指示传输类型(读或写)的一个位。从机接收到数据后向主机发送一个应答(ACK)或非应答(NACK)位。主机可以在传输中向从机发送一个或多个数据字节,并在传输结束时发送停止位。
I2C总线协议支持多种传输速率,通常在100kHz或400kHz。此外,I2C总线还支持一种叫做“快速模式”的高速传输,速率可以达到1MHz。I2C总线协议在嵌入式系统、传感器网络、存储器、显示器等领域得到广泛的应用。