I2C(Inter-Integrated Circuit)是一种串行通信协议,用于在集成电路(IC)之间进行短距离数据传输。它是由Philips(现在的NXP半导体)在上世纪80年代开发的,并成为一种广泛应用的通信协议。
I2C协议主要用于连接微控制器、传感器、存储器和其他外围设备,以实现简单而可靠的通信。它使用两根信号线:串行数据线(SDA)和串行时钟线(SCL)。通过这两根线,多个设备可以同时连接到同一条总线上。
以下是I2C协议的一些关键特点: 简单和双向:I2C使用主从结构,其中一个设备充当主设备,负责控制通信的时序和协调数据传输,其他设备则充当从设备,按照主设备的指示进行操作。双向通信意味着数据可以在主设备和从设备之间双向传输。 地址寻址:每个从设备在总线上都有一个唯一的7位或10位地址,用于主设备选择要与之通信的从设备。7位地址模式支持最多128个从设备,10位地址模式支持最多1024个从设备。 速度可变:I2C协议支持多种传输速率,通常有标准模式(100 kbit/s)、快速模式(400 kbit/s)和高速模式(3.4 Mbit/s)。速率的选择由主设备决定,所有从设备都必须支持所选择的速率。 起始和停止条件:通信的开始由主设备发出起始条件(Start),而结束由主设备发出停止条件(Stop)。起始条件和停止条件的产生使得每个通信传输都有明确的开始和结束,确保数据的完整性。 硬件传输:I2C协议通过改变SDA和SCL线上的电压来传输数据。SDA线上的数据传输是基于时钟信号的变化,而SCL线上的时钟信号由主设备生成。
I2C协议在许多应用中得到广泛应用,特别是在连接微控制器和外围设备的场景中。它提供了一种简单可靠的通信方式,具有较低的成本和较少的引脚需求。由于其流行和广泛支持,许多芯片和模块都集成了I2C接口,使得设备之间的互联变得更加简单和灵活。 接下来用实例说明实现方式 - /**********************************************
- //IIC Start
- 时钟信号在高电平状态时候在数据线产生一个下降沿
- **********************************************/
- void IIC_Start()
- {
- OLED_SCLK_Set() ;
- OLED_SDIN_Set();
- OLED_SDIN_Clr();
- }
- /**********************************************
- //IIC Stop
- 时钟信号在高电平状态时候在数据线产生一个上升沿
- **********************************************/
- void IIC_Stop()
- {
- OLED_SCLK_Set();
- OLED_SDIN_Clr();
- OLED_SDIN_Set();
- }
- //这里就是跳过这个时钟周期,没有去读数据位有没有回来应答信号。
- void IIC_Wait_Ack()
- {
- OLED_SCLK_Set();
- OLED_SCLK_Clr();
- }
- /**********************************************
- // IIC Write byte
- 在时钟线为低电平的时候在数据线发送数据位,高位在前
- 在完成数据发送后要保持数据线为低电平
- **********************************************/
- void Write_IIC_Byte(unsigned char IIC_Byte)
- {
- unsigned char i;
- unsigned char m,da;
- da=IIC_Byte;
- for(i=0;i<8;i++)
- {
- m=da;
- OLED_SCLK_Clr();
- m=m&0x80;
-
- if(m==0x80)
- OLED_SDIN_Set();
- else
- OLED_SDIN_Clr();
- da=da<<1;
- OLED_SCLK_Set();
- }
- OLED_SCLK_Clr();
- }
- /**********************************************
- // IIC Write Command
- 开始信号
- 前8位为:写7位地址,高位在前,并跟随1个读写位0,表示写入:0111 100 0
- 第9位应答,这里就是跳过一个时钟信号(拉高时钟,拉低时钟)
- 接下已一个字节发送0x00表示后面要写命令
- 接下来应答位,这里就是跳过一个时钟信号(拉高时钟,拉低时钟)
- 后面开始写入的数据作为命令,即将命令字节装载到这个发送字节的函数里发送出去
- 然后又是一个应答位,跳过一个时钟信号
- 之后发送停止指令。
- **********************************************/
- void Write_IIC_Command(unsigned char IIC_Command)
- {
- IIC_Start();
- Write_IIC_Byte(0x78); //Slave address,SA0=0
- IIC_Wait_Ack();
- Write_IIC_Byte(0x00); //write command
- IIC_Wait_Ack();
- Write_IIC_Byte(IIC_Command);
- IIC_Wait_Ack();
- IIC_Stop();
- }
- /**********************************************
- // IIC Write Data
- 开始信号
- 前八位为:写7位地址,高位在前,并跟随1个读写位0,表示写入:0111 100 0
- 第9位应答,这里就是跳过一个时钟信号(拉高时钟,拉低时钟)
- 接下已一个字节发送0x40表示后面要写的是数据
- 接下来应答位,这里就是跳过一个时钟信号(拉高时钟,拉低时钟)
- 后面开始写入的数据作为数据,即将数据字节装载到这个发送字节的函数里发送出去
- 然后又是一个应答位,跳过一个时钟信号
- 之后发送停止指令。
- **********************************************/
- void Write_IIC_Data(unsigned char IIC_Data)
- {
- IIC_Start();
- Write_IIC_Byte(0x78); //D/C#=0; R/W#=0
- IIC_Wait_Ack();
- Write_IIC_Byte(0x40); //write data
- IIC_Wait_Ack();
- Write_IIC_Byte(IIC_Data);
- IIC_Wait_Ack();
- IIC_Stop();
- }
|