I2C简述

    IIC全称Inter Integrated Circuit,即集成电路总线。是由Philips半导体公司于八十年代初设计出的一种两线式串行总线协议,主要应用于传输数据量不大且通信距离短的主从机通信,主设备起控制作用,从设备只能被动进行读写操作。

    I2C是半双工双向通讯的,需要两根总线,一根SCL(串行时钟总线),用作数据同步,一根SDA(串行数据总线),用于数据的传输,与UART不同的是,IIC上支持挂载多个从设备,主设备通过每个从设备唯一的地址来进行通信,并且IIC的数据接口是双向IO,即可做输出亦可做输入。

SDA与SCL都外接了上拉电阻(4.7K~10K),所以当SDA空闲时刻输出的永远是高电平,它对外设也有一定要求,要求外设的输出模式也是开漏输出线与操作,任一设备低电平,线上就是低电平

其中I2C里的上拉电阻也不是随便用的,因为电阻值越高意味着信号拉高周期越长,那么通讯周期时间就越高,速率就下来了。

数据传输时高比特位(MSB)先传输,低比特位(LSB)后传输。

IIC协议有三种传输速度,即标准模式、快速模式以及高速模式。标准模式速度可达100kb/s,快速模式可达400kb/s,而高速模式可达到3.4Mb/s。

IIC协议通讯

    IIC在进行通信时,会先发送一个起始信号,然后发送7比特的地址位和1比特的读写控制位,这8比特组成1个字节,主机发送完这一个字节后会释放总线来接收接收方的应答位,为1比特,接收到应答位后开始发送1个字节的寄存器地址(有的IIC设备是不需要寄存器地址的,这种就可以不用发送寄存器地址,发完设备地址和读写控制位后可直接发送数据),当发完寄存器地址收到应答后,就可以接着发送数据了,数据同样以字节为单位发送。

空闲状态:在空闲状态下,SCL和SDA均为高电平。

起始信号:在SCL为高电平时,SDA由高到低的跳变即为起始信号。

地址位:任何IIC设备都有7比特或10比特的地址位。

读写控制位:一般是高读低写,即SDA高电平为读操作1,低电平为写操作0。

应答位:在发送完读写控制位后释放总线,在下一个SCL的高电平器件检测到SDA的低电平即为应答位,表示接收方已收到数据,否则为非应答位(NACK),一般表示未成功收到数据,每发送完1字节的数据后均会产生一个应答位。

停止信号:在SCL的高电平时,SDA由低到高的跳变即为停止信号,之后终止一次数据的传输,要再进行数据的传输则需要重新发起始位,地址以及读写控制位。

如下图:

总括:SCL高电平才进行采样,SCL低电平时SDA随意变化。SCL高电平时SDA向下的跳变为起始位,SDA向上的跳变为结束位。传输时SCL为高电平,SDA不能跳变。

有不明白的地方可参考下面博客

详解I2C原理-CSDN博客

写时序

    主设备向从设备写入数据的过程即为写操作,读写操作均以主设备为参考。

    第一步:主设备先向产生一个起始信号,表示要进行数据传输了,然后发送第一个字节的数据(由7bit的从设备地址+1bit的读写控制位组成,写操作时,读写控制位置0表示写),然后释放SDA总线,等待从设备的ACK确认。

    第二步:发送寄存器地址,寄存器地址为1byte,等待从设备的ACK确认,不需要寄存器地址的从设备直接跳过这一步。

    第三步:发送需要写入从设备的数据,数据同样以字节为单位发送,每发送完一个字节,从设备都会回一个ACK表示是否正常收到数据。

    第四步:所有数据均发送完成后,主设备发送停止位,以此暂停该次写操作,至此,一次写操作完成。

其大致时序如下图:

读时序

    主设备读取从设备数据的过程即为读操作,读流程大致和写流程差不多,但要复杂一点,要读取从设备数据,首先得知道是从那个从设备的哪个寄存器读取数据,因此读之前会先有一个写操作,写入从设备地址和寄存器地址,以此明确操作的对象,读操作大致分为以下几步:

    第一步:发送起始位,然后发送第一个字节(同样由7bit从设备地址+1bit读写控制位组成,此时读写控制位为0,表示写操作),然后等待Ack。

    第二步:发送第二个字节,即写寄存器地址,然后等待Ack。注意:此时由IIC的读操作没有字节指定读寄存器地址的操作,而其寄存器地址指针在每一次读写后均会加1

第三步:重新发送起始位,开始第二次的数据交互。

    第四步:发送从设备地址字节(同样7bit+1bit,但此时的读写控制位置1,表示读),然后等待应答位。

    第五步:接收读取的数据,从设备地址应答位后跟着的就是读到的数据了,此时主设备作为接收方,收完1byte的数据会发送Ack到从设备,若发送的是ACK,则继续读取设备,若是NACK,则接着会发送停止位,表示本次读取数据完成,终止数据交互。

大致时序如下图:

读操作时,若要读取的寄存器为该设备的第一个寄存器或者该设备只有一个寄存器,则可直接跳过第一步和第二步的写操作,从而简化时序。

应用

由于IIC协议比较简单,所以应用流派分为两类:软件模拟和硬件收发。软件模拟更适合于学习和练手,因为在多任务的操作系统里不大适合。现在大多芯片都集成IIC直接使用很方便。

STM32提供的函数:(IIC的时钟配置可以由STM32CubeMX生成)

HAL_StatusTypeDef HAL_I2C_IsDeviceReady(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint32_t Trials, uint32_t Timeout)   查看从设备是否就绪

HAL_StatusTypeDef HAL_I2C_Mem_Write(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout)

向从设备的某寄存器地址写入一定数量的数据

HAL_StatusTypeDef HAL_I2C_Mem_Read(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout)

向从设备的某寄存器地址读取一定数量的数据

HAL_StatusTypeDef HAL_I2C_Master_Transmit(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout)

向从设备的已设定的地址写入一定数量的数据

HAL_StatusTypeDef HAL_I2C_Master_Receive(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size, uint32_t Timeout)

向从设备的已设定的地址读取一定数量的数据

bq28z610电量读取

德州仪器 (TI) bq28z610 器件是一款高度集成且精密的1-2 节串联电池电量监测计和保护解决方案,具备自主充电器控制和电量均衡功能。

bq28z610提供IIC接口来读取和配置,7位设备地址为0x55(8位0xAA来读取,0xAB来写入)。每个寄存器保存2字节的数据,寄存器地址见下表:

24C02 EEPROM

通过IIC可以读取和写入数据,注意点为一页为8字节,即一次最多写入8字节。如果超过8字节的数据传送给了EEPROM,字地址将回转到该页的首字节,先前的字节将会被覆盖。

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐