I2C :1、是什么 2、特点3、协议 4、使用方法

    • I2C是什么

1、I2C总线是由Philips公司开发的一种简单、双向二线制同步串行总线。它只需要两根线即可在连接于总线上的设备之间传送信息。

2、主设备用于启动总线传送数据,并产生时钟以开放传送的设备,此时任何被寻址的设备均被认为是从设备.总线上主设备和从设备、发数据设备和收数据设备的关系不是恒定的,而取决于此时数据传送方向。

3、如果主设备要发送数据给从设备,则主设备首先要寻址从设备,然后主动发送数据至从设备,最后由主设备终止数据传送;如果主设备要接收从设备的数据,首先由主设备寻址从设备.然后主设备接收从设备发送的数据,最后由主设备终止接收过程。在这种情况下.主机负责产生定时时钟和终止数据传送。

    • I2C特点

1、只要求两条总线线路:一条串行数据线SDA,一条串行时钟线SCL;

2、每个连接到总线的器件都可以通过唯一的地址和一直存在的简单的主机/从机关系软件设定地址,主机可以作为主机发送器或主机接收器;

3、它是一个真正的多主机总线,如果两个或更多主机同时初始化,数据传输可以通过冲突检测和仲裁防止数据被破坏;

4、串行的8位双向数据传输位速率在标准模式下可达100kbit/s,快速模式下可达400kbit/s,高速模式下可达3.4Mbit/s;

5、连接到相同总线的IC数量只受到总线的最大电容400pF限制

    • I2C协议

I2C Bus(IIC,inter-intergrated Circuit Bus),是一种在电子通信控制领域常用的通信协议。

由时钟线(SCL)和数据线(SDA)两根线构成通信线路,利用上拉电阻将他们拉成高电平,表示总线空闲,其典型的电压准位为+3.3V或+5V,具有电路简单,连接线少,控制简单,通信速率高等优点。

I2C总线是一个主从结构(Master/Slave)总线,I2C总线上的每一个设备都可以作为主设备或者从设备,但一个总线上一般只有一个从设备,可以带多个从设备,其中主设备用来产生允许传输的时钟信号,并初始化总线的传输数据,所以主设备通常是CPU;而从设备只能被动响应主设备发起的通信请求,所以各种I2C接口芯片将作为设备使用。

I2C从设备地址

因为一个I2C总线上可以有多个从设备,这样从设备需要通过地址来确定与哪个器件进行通信。I2C总线上每个从设备都有一个唯一的7bit地址物理识别,这个地址固话在芯片内部,并可以从芯片datasheet上找到。因为I2C地址全0为广播地址,所以I2C总线理论上做多能2^7-1=127个设备。

有些时候一个总线上可能需要挂多个同一芯片,这样有芯片还需要引出一个或几个引脚,由开发板设计电路决定其具体地址,从而让不同芯片具有不同的7bit物理地址。

I2C通信时序

在I2C总线上传送的每一位数据都由一个同步时钟脉冲相对应,既在SCL串行配合下,数据在SDA上从高位向低位依次串行传送每一位的数据。

I2C通信时序图如下

起始位

I2C总线在空闲时SDA和SCL都处于高点平状态(由上拉电阻拉成高电平),当主从设备要开始依次I2C通信时就发送一个START(S)信号,这个起始位就可以告诉所有的I2C从机,"我"要开始I2C通信了;当要结束一次I2C通信时,就发送一个STOP(P)信号结束本次通信。

I2C协议起始位:当SCL保持高电平时,SDA出现一个下降沿,产生一个起始位;

I2C协议停止位:当SCL保持高电平时,SDA出现一个上升沿,产生一个停止位;

I2C读写地址

主机在发送START信号之后,第2个时序应该立即给出要通信的目标从机物理地址。此外,I2C总线是一种能够实现半双工通信的同步串行通信协议,站在主设备的角度来看应该具有读/写从设备的功能。

这时候I2C的读写地址除了7bit物理地之外,还有1bit用来标识读/写方向。这样I2C的从设备读写地址通常是一个字节,其中高7bit是上面描述的物理地址,最低位用来读写方向(0为写操作,1为读操作)

I2C应道信号

主机往I2C总线上传输器件地址,所有的从机接收到这个地址后与自己的地址相比较若相同则发出一个应答ACK信号,主机收到这个应答信号后通讯连接建立成功,若未收到应答信号则表示寻址失败。

此外,主/从机在之后的数据通信中,数据接收方(可能是主机也可能是从机)收到传输的一个字节数据后,需要给出响应,此时处在第九个时钟,发送端释放SDA线控制权,将SDA电平拉低,由接收方控制。

若希望继续,则给出“应答”信号,即SDA为低电平。

若不希望继续,则给出“非应答”信号,即为SDA高电平。

数据位收发

主机在收到从机的应答信号之后,开始从机发送数据。SDA数据线上的每个字节必须是8位,每次传输的字节数量没有限制,每个字节发送完成之后,从机必须跟一个应答信号。

I2C总线通信时数据位传输采用MSB(最高位优先)方式发送,其中高电平表示数据位1,低电平表示数据位0。当传输的数据位需要改变时(如上一个位发送的是1,下一个位要发送0),必须发生在SCL为低电平期间。另外在传输过程中,SDA上的数据位在SCL高电平期间必须保持稳定不变。

总线速率

I2C总线是一种同步,半双工,采用高电平信号收发的串行总线,其速率支持:

标准模式(Standard-mode):速率高达100kbit/s

快速模式(Fast-mode):速率高达400kbit/s

快速模式+(Fast-mode Plus):速率高达1Mbit/s

高速模式(High-speed mode):速率高达3.4bit/s

超快速模式(Ultra Fast-mode):速率高到5Mbit/s 单向传输时支持

主机发送数据流程

1.主机检测到总线为空闲,发送一个启动信号"S",开始一次通信的开始。

2.主机接着发送一个从设备地址,它由7bit物理地址和1bit读写位控制R/W组成(此时R/W=0)

3.相对应的从机收到命令字节后向主机回馈应答信号ACK(ACK=0)

4.主机收到从机的应道信号后开始发送第一个字节的数据

5.从机收到数据后返回一个应道信号ACK

6.主机收到应答信号后再发送下一个数据字节

7.主机发完最后一个字节并收到ACK后向从机发送一个停止信号P结束本次通信并释放总线

8.从机收到P信号后也退出与主机之间的通信

主机接收数据流程

1.主机发送启动信号,接着发送地址字节(其中R/W=1)

2.对应的从机收到地址字节后

3.主机收到数据后向从机反馈一个应答信号ACK

4.从机收到应答信号后再向主机发送下一个数据;

5.当主机完成接收数据后,向从机发送一个NAK,从机收到应答信号后便停止发送

6.主机发送非应答信号后,再发送一个停止信号,释放总线结束通信

    • I2C使用方法

I2C总线是一种简单、双向二线制同步串行总线。所有主机在 SCL 线上产生它们自己的时钟来传输总线上的报文,SDA 线传输每个字节必须为 8 位,每次传输可以发送的字节数量不受限制,每个字节后必须跟一个响应位。在空闲状态时,SCL 与 SDA 均为高电平。

通常一些低功耗I2C设备,芯片引脚使用上拉输出即可满足与其正常数据交互,还有一些I2C设备,则需要在总线上外加一个上拉电阻,此时相应的 I/O 配置成开漏输

1.1. 主机模式#

  • 创建 I2C(软件模拟或硬件) 对象

from machine import I2C
from fpioa_manager import fm
# i2c = I2C(I2C.I2C0, freq=100000, scl=28, sda=29) # hardware i2c
i2c = I2C(I2C.I2C4, freq=100000, scl=28, sda=29,gscl=fm.fpioa.GPIOHS3,gsda=fm.fpioa.GPIOHS2)
#software i2c
  • 扫描从机, 返回所有从机地址

devices = i2c.scan()
  • 对从机读写数据

for device in devices:
    i2c.writeto(device,b'123')
    i2c.readfrom(device,3)

1.2. 从机模式#

  • 创建从机回调函数

count =0defon_receive(data):print("on_receive:",data)defon_transmit():
    count = count+1print("on_transmit, send:",count)return count

defon_event(event):print("on_event:",event)
  • 创建 I2C 对象

from machine import I2C
i2c = I2C(I2C.I2C0, mode=I2C.MODE_SLAVE, scl=28, sda=29, addr=0x24, addr_size=7, on_receive=on_receive, on_transmit=on_transmit, on_event=on_event)

二、示例#

  • 读取所有从机地址并分别收发数据

from machine import I2C

i2c = I2C(I2C.I2C0, freq=100000, scl=28, sda=29)# software i2c

devices = i2c.scan()print(devices)for device in devices:
    i2c.writeto(device,b'123')
    i2c.readfrom(device,3)
  • 从机模式示例

from machine import I2C

count = 0

def on_receive(data):
    print("on_receive:",data)

def on_transmit():
    count = count+1
    print("on_transmit, send:",count)
    return count

def on_event(event):
    print("on_event:",event)

i2c = I2C(I2C.I2C0, mode=I2C.MODE_SLAVE, scl=28, sda=29, addr=0x24, addr_size=7, on_receive=on_receive, on_transmit=on_transmit, on_event=on_event)

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值