我是靠谱客的博主 拉长大炮,最近开发中收集的这篇文章主要介绍I2C通信协议,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

一、物理结构

I2C是一种同步半双工的通信协议,同一时刻只能向一个方向传送数据。I2C总线由SCL时钟线和SDA数据线组成,时钟线控制收发数据的频率。

Fig1.I2C 系统结构

1、每个I2C设备都有一个独立的地址,主机可以利用这个地址和不同设备通信,地址共有7bits和10bits两种。

2、总线通过上拉电阻接到电源,当I2C设备空闲时,MOSFET关断,输出高阻态。

3、Cbus电容(总线负载电容)决定了外接设备的数量,原因见Fig2。Cbus电容并非实实在在的一个电容,而是连接到I2C总线上设备的等效容性负载。

 Fig2.容抗对I2C电平的影响

I2C在高电平时读取数据,当总线上的电容过大时,影响SDA总线的充电时间,造成bit位的错误读取。

4、标准协议中I2C共有标准、快速、快速+、高速、超高速5种工作速率。

                Fig3.五种传输速率比较

 二、传输协议

 Fig4.协议传输格式

1、开始位/重复开始位(S-Start/Sr-Repeated Start):当SCL为高电平时,SDA由高电平切换为低电平,此时通信开始。

 Fig5.开始位和停止位

 总线空闲状态:SDA和SCL均为高电平。

2、数据传输:主机(Master)或从机(Slaver)在SCL高电平(上升沿)时读取SDA上的信号,在SCL低电平是,SDA完成传输位信号的改变。数据传输时,高位先进行传输(MSB),一次传输的最大传输Byte位数无限制。

 Fig6.数据变化均发生在时钟低电平,有些可能需要数据建立时间,在时钟变成高电平前完成数据位的变化

3、应答位/非应答为(ACK/NACK):每8个bit位后会跟随一个ACK位。

ACK:发送设备释放SDA,接收设备控制SDA低电平。

NACK:发送设备释放SDA,接收设备控制SDA高电平。

NACK发生的情况:

①无:没有主机访问地址的slave

②忙:slave忙碌,无法开始数据传输

③错:接收到错误的数据

④停:通知Slave-Transmitter停止发送数据

4、时钟拉伸(clock Stretching):①ACK和NACK的时间拉长,增加Receiver的处理时间②如果收发设备处理数据性能有差异,传输每个bit位的时钟低电平时间可拉长,但传输频率会降低。

5、停止位:当SCL为高电平时,SDA由低电平向高电平切换,表示通信停止。

6、时钟同步:同一总线上有多个主机同时访问从机时发生,采用SCL时钟(OC/OD)线与的结构,只有当CLK1和CLK2均为高电平时,SCL才表现为高电平,通信开始。超快速模式采用推挽式结构,不支持时钟同步。

Fig7.时钟同步

 7、总线仲裁:同一总线上有多个主机同时访问从机时发生。从机不参与仲裁,由主机完成。仲裁按每个SDA数据bit位逐步进行。

 Fig8.总线仲裁

利用时钟同步的SCL上升沿对SDA采样,如果DATA1和DATA2全程和SDA上一致,则双主机都能同时访问同一个从机;如果DATA1先和SDA不一致,则DATA2的Master获取主动权,继续完成相关操作,DATA1的主机丢失总线SDA的控制权,并关闭DATA1的输出。

三、从设备的地址

同一I2C总线上的多个Slave地址必须具有唯一性,不能相同。从设备的地址分为7bit位和10bit为两种。

Fig9. 7位从机地址+1位读写控制位

 Fig10. 10位从机地址+1位读写控制位+11110固定编码,组成2个字节

 四、I2C总线典型问题

 Fig11.I2C总线常见问题

解决方案:

 

 

 

五、EEPROM AT24C02读写操作

在这里插入图片描述

 Fig12. 芯片引脚定义

1、SCL时钟总线:SCL输入用于将正边缘时钟数据输入到每个EEPROM设备,并将负边缘时钟数据输出到每个设备。
2、SDA数据总线:SDA引脚是双向的,用于串行数据传输。
3、设备地址A2, A1, A0:A2、A1和AO引脚是硬接线AT24C02的设备地址输入,共有8种组合,即I2C总线最多接8个AT24C02。
4、写保护WP:AT24C02有一个写保护引脚,提供硬件数据保护。当连接到地(GND)时,写保护引脚允许正常读/写操作。当引脚连接到Vcc时,就会启用Write protection特性,不允许读写。
 

Fig13.读写时序(混合模式)

六、OLED屏显示


尺寸:0.96寸
分辨率:128*64
通信方式:I2C
显存芯片:SSD1315
管脚定义:GND、VCC、SCK、SDA

显示原理:SSD1315的SRAM,也称为GDDRAM(Graphic Display Data RAM),含128 × 64 个bit位,被分为8个 PAGE,每个page由8行×128列个bit位组成。当我们往这个RAM写入数据,就会显示特定内容。

/**
  * @brief  I2C开始
  * @param  无
  * @retval 无
  */
void OLED_I2C_Start(void)
{
	OLED_W_SDA(1);
	OLED_W_SCL(1);
	OLED_W_SDA(0);
	OLED_W_SCL(0);
}

/**
  * @brief  I2C停止
  * @param  无
  * @retval 无
  */
void OLED_I2C_Stop(void)
{
	OLED_W_SDA(0);
	OLED_W_SCL(1);
	OLED_W_SDA(1);
}

/**
  * @brief  I2C发送一个字节
  * @param  Byte 要发送的一个字节
  * @retval 无
  */
void OLED_I2C_SendByte(uint8_t Byte)
{
	uint8_t i;
	for (i = 0; i < 8; i++)
	{
		OLED_W_SDA(Byte & (0x80 >> i));
		OLED_W_SCL(1);
		OLED_W_SCL(0);
	}
	OLED_W_SCL(1);	//额外的一个时钟,不处理应答信号
	OLED_W_SCL(0);
}

/**
  * @brief  OLED写命令
  * @param  Command 要写入的命令
  * @retval 无
  */
void OLED_WriteCommand(uint8_t Command)
{
	OLED_I2C_Start();
	OLED_I2C_SendByte(0x78);		//从机地址
	OLED_I2C_SendByte(0x00);		//写命令
	OLED_I2C_SendByte(Command); 
	OLED_I2C_Stop();
}

/**
  * @brief  OLED写数据
  * @param  Data 要写入的数据
  * @retval 无
  */
void OLED_WriteData(uint8_t Data)
{
	OLED_I2C_Start();
	OLED_I2C_SendByte(0x78);		//从机地址
	OLED_I2C_SendByte(0x40);		//写数据
	OLED_I2C_SendByte(Data);
	OLED_I2C_Stop();
}

七、STM32的I2C外设

STM32的I2C外设可用作通信的主机以及从机,支持100kbps和400kbps的速率,支持7位、10位设备地址,支持DMA数据传输,并且具有数据校验功能。

 STM32的外设都挂载在APB1总线上,使用APB1的时钟源PCLK1。

其定义的结构体如下:

typedef struct
{
  uint32_t I2C_ClockSpeed;          /*!< Specifies the clock frequency.This parameter must 
                                          be set to a value lower than 400kHz */

  uint16_t I2C_Mode;                /*!< Specifies the I2C mode.
                                         This parameter can be a value of @ref I2C_mode */

  uint16_t I2C_DutyCycle;           /*!< Specifies the I2C fast mode duty cycle.This 
                                    parameter can be a value of @ref 
                                    I2C_duty_cycle_in_fast_mode */

  uint16_t I2C_OwnAddress1;         /*!< Specifies the first device own address.
                                         This parameter can be a 7-bit or 10-bit address. 
                                    */

  uint16_t I2C_Ack;                 /*!< Enables or disables the acknowledgement.
                                         This parameter can be a value of @ref 
                                     I2C_acknowledgement */

  uint16_t I2C_AcknowledgedAddress; /*!< Specifies if 7-bit or 10-bit address is 
                                      acknowledged.This parameter can be a value of @ref 
                                     I2C_acknowledged_address */
}I2C_InitTypeDef;

1、I2C_ClockSpeed:设置I2C的传输速率。写入的参数不得高于400kHz。

2、I2C_Mode:选择I2C的使用方式。有I2C_Mode_I2C和I2C_Mode_SMBusHost、I2C_Mode_SMBusDevice,三种模式。直接设置I2C_Mode_I2C模式即可。

3、I2C_DutyCycle:是指SCL时钟的占空比。可选为(低电平:高电平=2:1)I2C_DutyCycle_2模式和16:9模式的I2C_DutyCycle_16_9,对要求不高的场合,可随便选。

4、I2C_OwnAddress1:配置STM32的I2C设备自己的地址。

5、I2C_ACK:配置应答信号,设置为I2C_ACK_Enable即可。

6、I2C_AcknowledgedAddress:选择I2C的寻址模式是7位还是10位。

最后

以上就是拉长大炮为你收集整理的I2C通信协议的全部内容,希望文章能够帮你解决I2C通信协议所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(44)

评论列表共有 0 条评论

立即
投稿
返回
顶部