本节简要介绍I²C总线协议,并以一个简单的例程介绍如何在通过 Python
使用 OpenHarmony
的 I²C 接口
I²C最少只需要两根线,和异步串口类似,但可以支持多个从(slave)设备,和SPI不同的是,I²C可以支持多主机(mul-master)系统,允许有多个master并且每个master都可以与所有的slaves通信(master之间不可通过I²C通信,并且每个master只能轮流使用I²C总线)。master是指启动数据传输的设备并在总线上生成时钟信号以驱动该传输,而被寻址的通信设备都作为slaves。
I²C通讯只需要2条双向总线:
功能编号 | 含义 |
---|---|
SDA(serial data:串行数据线) | 传输数据,SDA线传输数据是大端传输,每次传输一个字节 |
SCL(serial clock:串行时钟线) | 同步数据收发 |
一个主设备和两个从设备的连接示意图如下图所示:
I²C总线上的每一个设备都可以作为主设备或者从设备,而且每一个设备都会对应一个唯一的地址,当主设备需要和某一个从设备通信时,通过广播的方式,将从设备地址写到总线上,如果某个从设备符合此地址,将会发出应答信号,建立传输。
SDA 线上的数据必须在时钟的高电平周期保持稳定,数据线的高或低电平状态只有在 SCL 线的时钟信号是低电平时才能改变。
换言之,SCL为高电平时表示有效数据,SDA为高电平表示“1”,低电平表示“0”;SCL为低电平时表示无效数据,此时SDA会进行电平切换,为下次数据表示做准备。如图为数据有效性的时序图。
起始条件S:当SCL高电平时,SDA由高电平向低电平转换;
停止条件P:当SCL高电平时,SDA由低电平向高电平转换。
起始和停止条件一般由主机产生。总线在起始条件后处于busy的状态,在停止条件的某段时间后,总线才再次处于空闲状态。如下图为起始和停止条件的信号产生时序图。
I²C数据的传输必须以一个起始信号作为开始条件,以一个结束信号作为传输的停止条件。
I²C传输的数据以字节为单位,每个字节必须为8位,可以传输任意多个字节,上图中以一个字节的数据为例进行分析,I2C的数据格式具有以下特点:
数据接收方收到传输的一个字节数据后,需要给出响应,此时处在第九个时钟,发送端释放SDA线控制权 ,将SDA电平拉高,由接收方控制。
接收方表示成功的接收到了8位一个字节的数据,便将SDA拉低为低电平,即ACK信号,表示应答
I²C的PDU(Protocol Data Unit:协议数据单元,即数据格式):
waffle nano 共有7个引脚可以用作 I²C 的通讯引脚。拥有 2 个 I²C 总线端口,根据用户的配置,总线端口可以用作 I²C 主机。
其中板载内置传感器连接到引脚:
Pin9,Pin10
。所以在操作板载传感器时需配置0
号端口 I²C 总线对象,比如i2c = I2C(0, sda=Pin(9), scl=Pin(10)
。
I²C 端口号 | SDA | SCL |
---|---|---|
I2C 1 | pin 0 | pin 1 |
I2C 0 | pin 9 | pin 10 |
I2C 0 | pin 13 | pin 14 |
使用from machine import I2C
导入machine
模块的I2C总线接口类I2C
再使用TAB
按键来查看I2C
中所包含的内容:
>>>from machine import I2C
>>>I2C.
read write readfrom_mem scan
writeto_mem
id
— I²C设备组号,可以为0或1scl
— I²C设备时钟引脚对象sda
— I²C设备数据线引脚对象freq
— SCL时钟频率 0 <freq
≤ 500000(Hz)用I2C对象的构造器函数
示例:
>>> from machine import I2C, Pin
>>> i2c = I2C(0, sda=Pin(9), scl=Pin(10),freq=100000)#构建I2C0,时钟频率100000(时钟屏幕根据具体传感器而定,一般使用100000或400000)
>>> i2c = I2C(1, sda=Pin(0), scl=Pin(1),freq=100000)##用pin1引脚当I2C1的scl功能成功
使用ID直接构造
I2C的id只能取0
或1
,可以通过id来直接构造这两组接口。无法直接使用第1组I2C资源,默认I2C的SCL功能是由pin4引脚实现,会报invalid scl pin(4)
错误,因为IO3
、IO4
被编程串口所占用。
示例:
>>> from machine import I2C, Pin
>>> i2c0=I2C(0)#构建I2C0
>>> i2c0
I2C(0, scl=10, sda=9, freq=400000)
>>> i2c1=I2C(1)#构建I2C1会报ValueError
Traceback (most recent call last):
File "<stdin>", in <module>
ValueError: invalid scl pin(4)
>>> i2c1
I2C(1, scl=4, sda=3, freq=400000)
在接下来的示例中, 构造id=0
的I2C
对象来列举I2C对象的函数。
>>>from machine import I2C
>>>i2c = I2C(0)#构建I2C0
i2c.scan()
函数说明:扫描I²C地址,并返回设备列表
>>>from machine import I2C
>>>i2c = I2C(0)#构建I2C0
>>> i2c.scan()#扫描I²C地址
[104, 118]
waffle nano本身有104和118两个地址的I²C总线,104是陀螺仪传感器,118是温湿度传感器。
I²C读写数据需要先扫描I²C地址,在相应的地址上读写数据
i2c.write(addr,data)
函数说明:向I2C写入(发送)数据,返回True或False表示是否写入成功.
addr
I²C设备地址,可由scan函数读取出来
data
: 需要写入(发送)的数据
示例:
>>>from machine import I2C
>>>i2c = I2C(0)#构建I2C0
>>>i2c.write(104,b'\x01\x00\x09\x08')#向I2C0的104地址写入数据`\x01\x00\x09\x08`
True
注意:
一般的IIC传感器都有寄存器的概念。视不同传感器而言,一般发送的数据前一位为寄存器地址,也就是\x01\x00\x09\x08
中0x01
为其寄存器地址,向0x01
寄存器(含)往后将x00\x09\x08
数据依次写入寄存器中去。也有些传感器使用的寄存器比较多,需要用两个字节表示寄存器地址,那么此时\x01\x00\x09\x08
中\x01\x00
表示其寄存器地址。向0x01\x00
寄存器(含)往后将x09\x08
数据依次写入寄存器中去。
i2c.read(addr,length)
函数说明:从指定地址设备读取数据,返回读取对象,这个对象与I²C设备有关
addr
: I²C设备地址,可由scan函数读取出来
length
: 读入的字节数
from machine import I2C
i2c = I2C(0)#构建I2C0
i2c.write(118,b'\x08')#从第0x08寄存器开始读取
print(i2c.read(118,10))#读取118地址上0x08寄存器往后的10个字节的数据
b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
i2c.readfrom_mem(addr,register,length)
函数说明:从指定地址设备的指定寄存器开始往后连续读取各寄存器数据。
addr
:从机设备IIC地址。register
:操作的起始寄存器地址。length
: 读入的字节数。
注意:此方法仅仅适用于寄存器用一个字节描述的IIC元器件
i2c.writeto_mem(addr,register,data)
函数说明:向指定地址设备的指定寄存器开始往后连续将数据写入各寄存器中。
addr
:从机设备IIC地址。register
:操作的起始寄存器地址,data
: 需要写入(发送)的数据。
注意:此方法仅仅适用于寄存器用一个字节描述的IIC元器件
将waffle nano的一些GPIO引脚构造成I2C总线,读写相应数据(需要连接相应的传感器)。
from machine import I2C, Pin
i2c = I2C(1, sda=Pin(0), scl=Pin(1),freq=100000) #构造IIC对象,将1号引脚设置为scl,将0号引脚设置为sda
print(i2c.scan()) #扫描IIC总线上的传感器,返回传感器ID
i2c.write(74,b'\x03') #向74号ID的传感器发送0x03数据
print(i2c.read(74,10)) #从74号ID的传感器读取10个字节数据
i2c.writeto_mem(105,0x03,b'\x01\x02') #向105号ID的传感器的0x03寄存器(含)以及其往后的寄存器中依次填入数据`0x01`、`0x02,每个寄存器分到1个字节。
print(i2c.readfrom_mem(105,0x80,128)) #从105号ID的传感器的0x80寄存器开始(含)依次读取128个寄存器的数据,并返回。
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Комментарий ( 0 )