I2C 学习笔记

I2C(Inter-Integrated Circuit)总线是一种简单、双向、二线制的同步串行通信总线,广泛应用于电子设备中,主要用于连接微控制器(如单片机)和各种外围设备(如传感器、存储器、显示器等)。

1. I2C总线的起源和特点

  • 起源:I2C总线由飞利浦公司(现NXP)在1982年开发,最初用于电视内部的芯片间通信。由于其简单、成本低、易于扩展等优点,逐渐被广泛应用。
  • 特点
    • 简单:仅需要两根线(数据线SDA和时钟线SCL)即可实现通信。
    • 多主多从:支持多个主设备和多个从设备连接在同一总线上。
    • 低速率:标准速率可达100kbps,快速模式可达400kbps,高速模式可达3.4Mbps。
    • 低功耗:通信信号为电平信号,功耗较低。
    • 易于扩展:可以方便地连接多个设备,且设备地址可以通过硬件引脚或软件配置来区分。

2. I2C总线的硬件连接

  • 总线结构
    • SDA(Serial Data Line):数据线,用于传输数据和地址信息。
    • SCL(Serial Clock Line):时钟线,由主设备提供,用于同步数据传输。
    • 上拉电阻:I2C总线是开漏(Open-Drain)结构,SDA和SCL线需要通过上拉电阻连接到电源,以保证信号的稳定。
  • 设备连接
    • 每个设备通过SDA和SCL连接到总线上。
    • 每个从设备都有一个唯一的7位或10位地址,用于区分不同的设备。
    • 主设备通过地址选择特定的从设备进行通信。

3. I2C总线的通信协议

  • 起始条件:SCL为高电平时,SDA从高电平跳变为低电平,表示通信开始。
  • 停止条件:SCL为高电平时,SDA从低电平跳变为高电平,表示通信结束。
  • 数据传输
    • 数据以字节为单位传输,每个字节包含8位数据。
    • 数据在SCL的上升沿被采样,在下降沿被改变。
    • 每个字节传输完成后,接收方需要发送一个应答信号(ACK)或非应答信号(NACK)。
  • 地址传输
    • 主设备首先发送一个7位或10位的从设备地址,加上一个读/写位(R/W)。
    • 从设备通过地址匹配来确定是否响应通信。
  • 应答信号
    • 当主设备发送数据时,从设备在每个字节后发送ACK信号。
    • 当主设备读取数据时,从设备发送数据,主设备在每个字节后发送ACK或NACK信号。

4. I2C总线的工作模式

  • 主设备模式:负责发起通信,控制时钟信号SCL,并通过SDA发送地址和数据。
  • 从设备模式:根据主设备发送的地址和指令,接收或发送数据。
  • 多主设备模式:多个主设备可以共享同一总线,通过仲裁机制避免冲突。

5. I2C总线的应用场景

  • 传感器通信:如温度传感器、湿度传感器、加速度传感器等,通过I2C总线将数据传输到主控制器。
  • 存储器通信:如EEPROM、Flash存储器等,用于存储配置信息或数据。
  • 显示设备通信:如I2C接口的LCD或OLED显示屏,用于显示信息。
  • 音频设备通信:如I2C接口的音频编解码器,用于音频信号处理。

6. I2C总线的优缺点

  • 优点
    • 硬件接口简单,仅需两根线。
    • 支持多主多从通信,易于扩展。
    • 低功耗,适合低功耗设备。
    • 协议简单,易于实现。
  • 缺点
    • 速率较低,不适合高速数据传输。
    • 总线负载能力有限,设备过多可能导致通信不稳定。
    • 通信距离较短,通常不超过几米。

I2C总线因其简单、灵活和低功耗的特点,广泛应用于各种嵌入式系统和物联网设备中,是现代电子系统中不可或缺的通信接口之一。
这段代码是基于51单片机的I2C通信协议实现的代码。它包含了I2C通信的基本操作,如启动信号、发送数据、接收数据、应答信号和停止信号等。以下是对代码的详细解释:

1. I2C_Start()

void I2C_Start(){
	SDA=1;
	SCL=1;
	Delay_xms(5);
	SDA=0;
	Delay_xms(5);
	SCL=0;
}
  • 功能:生成I2C通信的启动信号。
  • 过程
    1. 将数据线(SDA)和时钟线(SCL)都拉高(SDA=1; SCL=1;)。
    2. 延时5ms(Delay_xms(5);),确保信号稳定。
    3. 将数据线拉低(SDA=0;),保持时钟线为高电平,生成一个下降沿信号,表示通信开始。
    4. 再次延时5ms,确保信号稳定。
    5. 将时钟线拉低(SCL=0;),完成启动信号的生成。

2. I2C_DalaSend(unsigned char date)

void I2C_DalaSend(unsigned char date){
	unsigned char bita=date;
	unsigned char i;
	for(i=0;i<8;i++){
		SCL=0;
		if(bita & 0x80){
			SDA=1;
		}
		else{
			SDA=0;
		}
		Delay_xms(5);
		SCL=1;
		Delay_xms(5);			
		bita<<=1;	
	}
	SCL = 0;
}
  • 功能:发送一个字节的数据。
  • 过程
    1. 将要发送的数据存储到变量bita中。
    2. 通过一个循环发送8位数据:
      • 先将时钟线拉低(SCL=0;)。
      • 检查当前位是否为1(if(bita & 0x80))。如果是1,则将数据线拉高(SDA=1;),否则拉低(SDA=0;)。
      • 延时5ms,确保信号稳定。
      • 将时钟线拉高(SCL=1;),完成一位数据的发送。
      • 再次延时5ms,确保信号稳定。
      • bita左移一位(bita<<=1;),准备发送下一位。
    3. 最后将时钟线拉低(SCL = 0;),结束数据发送。

3. I2C_Sectchar()

bit I2C_Sectchar(){
	bit byte=0;
	SDA=1;
	SCL=1;
	bite=SDA;
	SCL=0;
	return bite;
}
  • 功能:接收从设备的应答信号。
  • 过程
    1. 将数据线和时钟线都拉高(SDA=1; SCL=1;)。
    2. 读取数据线的状态(bite=SDA;),判断从设备是否发送了应答信号。
    3. 将时钟线拉低(SCL=0;),完成应答信号的接收。
    4. 返回应答信号的状态(return bite;)。

4. I2C_DalaReceive()

unsigned char I2C_DalaReceive(){
	unsigned char acm=0;
	unsigned char i;
	SDA=1;
	for(i=0;i<8;i++){
		SCL=0;
		Delay_xms(5);
		SCL=1;
		Delay_xms(5);	
		acm=(acm<<1)|SDA;
	}
	SCL = 0;
	return acm;
}
  • 功能:接收一个字节的数据。
  • 过程
    1. 将数据线拉高(SDA=1;)。
    2. 通过一个循环接收8位数据:
      • 先将时钟线拉低(SCL=0;)。
      • 延时5ms,确保信号稳定。
      • 将时钟线拉高(SCL=1;),让从设备发送一位数据。
      • 再次延时5ms,确保信号稳定。
      • 读取数据线的状态(SDA),并将接收到的位左移后与之前接收的位组合(acm=(acm<<1)|SDA;)。
    3. 最后将时钟线拉低(SCL = 0;),完成数据接收。
    4. 返回接收到的数据(return acm;)。

5. I2C_Ack(bit nmc)

void I2C_Ack(bit nmc){
	SCL=1;
	SDA=nmc;
	SCL=0;
}
  • 功能:发送应答信号。
  • 过程
    1. 将时钟线拉高(SCL=1;)。
    2. 根据参数nmc的值,将数据线设置为高或低(SDA=nmc;)。如果nmc=0,表示发送应答信号;如果nmc=1,表示发送非应答信号。
    3. 将时钟线拉低(SCL=0;),完成应答信号的发送。

6. I2C_Stop()

void I2C_Stop(){
	SDA=0;
	SCL=1;
	SDA=1;
}
  • 功能:生成I2C通信的停止信号。
  • 过程
    1. 将数据线拉低(SDA=0;)。
    2. 将时钟线拉高(SCL=1;)。
    3. 将数据线拉高(SDA=1;),生成一个上升沿信号,表示通信结束。

总结

这段代码实现了一个完整的I2C通信流程,包括启动信号、数据发送、数据接收、应答信号和停止信号。通过这些函数,可以与支持I2C协议的设备进行通信。

posted @ 2025-04-24 21:48  aiALMIRA  阅读(39)  评论(0)    收藏  举报