machine.I2C

I2C 总线协议,简单地使用两条线(SCL,SDA)可以控制多个从机(主机模式)。

  • 支持主机模式和从机模式
  • 7 位/10 位寻址模式
  • 标准模式 <=100Kb/s
  • 快速模式 <=400Kb/s
  • 超快速模式 <=1000Kb/s
  • 高速模式 3.4Mb/s

构造函数

class machine.I2C(id, mode=I2C.MODE_MASTER, scl=None, sda=None, gscl=None, gsda=None, freq=400000, timeout=1000, addr=0, addr_size=7, on_recieve=None, on_transmit=None, on_event=None)

通过指定的参数新建一个 I2C 对象

参数

  • id: I2C ID, [0~2] (I2C.I2C0~I2C.I2C2) [3~5] (I2C.I2C3~I2C.I2C5, I2C_SOFT) 是软模拟 I2C 的编号
  • mode: 模式, 主机(I2C.MODE_MASTER)和从机(I2C.MODE_SLAVE)模式
  • scl: SCL 引脚,直接传引脚编号即可,取值范围: [0,47]。 可以不设置,而是使用 fm 统一管理引脚映射。
  • sda: SDA 引脚,直接传引脚编号即可,取值范围: [0,47]。 可以不设置,而是使用 fm 统一管理引脚映射。
  • gscl: SCL 对应的 GPIOHS,使用软件模拟 I2C 时才需要传入,默认与 scl 相同。
  • gsda: SDA 对应的 GPIOHS,使用软件模拟 I2C 时才需要传入,默认与 sda 相同 。
  • freq: I2C通信频率, 支持标准100Kb/s, 快速400Kb/s, 以及更高速率(硬件支持超快速模式1000Kb/s,以及高速模式3.4Mb/s)
  • timeout: 超时时间,目前这个参数保留,设置无效
  • addr: 从机地址,如果是主机模式不用设置, 从机模式则代表从机(本机)地址
  • addr_size: 地址长度, 支持 7 位寻址和 10 位寻址, 取值7或者10
  • on_recieve: 从机模式的接收回调函数
  • on_transmit: 从机模式的发送回调函数
  • on_event: 从机模式的事件函数(开始事件和结束事件)

方法

init

类似构造函数

i2c = I2C.init(id, mode=Timer.MODE_MASTER, scl, sda, gscl, gsda, freq=400000, timeout=1000, addr=0, addr_size=7, on_recieve=None, on_transmit=None, on_event=None)

参数

与构造函数相同

返回值

scan

扫描I2C总线上的从机

i2c.scan()

参数

返回值

list 对象, 包含了所有扫描到的从机地址

readfrom

从总线读取数据

i2c.readfrom(addr, len, stop=True)

参数

  • addr: 从机地址
  • len: 数据长度
  • stop: 是否产生停止信号,保留,目前只能使用默认值Ture

返回值

读取到的数据,bytes 类型

readfrom_into

读取数据并放到制定变量中

i2c.readfrom_into(addr, buf, stop=True)

参数

  • addr: 从机地址
  • bufbytearray类型, 定义了长度,读取到的数据存放在此
  • stop: 是否产生停止信号,保留,目前只能使用默认值Ture

返回值

writeto

发送数据到从机

i2c.writeto(addr, buf, stop=True)

参数

  • addr: 从机地址
  • buf: 需要发送的数据
  • stop: 是否产生停止信号,保留,目前只能使用默认值Ture

返回值

成功发送的字节数

readfrom_mem

读取从机寄存器

i2c.readfrom_mem(addr, memaddr, nbytes, mem_size=8)

参数

  • addr: 从机地址
  • memaddr: 从机寄存器地址
  • nbytes: 需要读取的长度
  • mem_size: 寄存器宽度, 默认为8位

返回值

返回bytes类型的读取到的数据

readfrom_mem_into

读取从机寄存器值到指定变量中

i2c.readfrom_mem_into(addr, memaddr, buf, mem_size=8)

参数

  • addr: 从机地址
  • memaddr: 从机寄存器地址
  • bufbytearray类型, 定义了长度,读取到的数据存放在此
  • mem_size: 寄存器宽度, 默认为8位

返回值

writeto_mem

写数据到从机寄存器

i2c.writeto_mem(addr, memaddr, buf, mem_size=8)

参数

  • addr: 从机地址
  • memaddr: 从机寄存器地址
  • buf: 需要写的数据
  • mem_size: 寄存器宽度, 默认为8位

返回值

deinit/__del__

注销I2C硬件,释放占用的资源,关闭I2C时钟

i2c.deinit()

参数

返回值

例子

i2c.deinit()

或者

del i2c

常量

  • I2C0: I2C 0
  • I2C1: I2C 1
  • I2C2: I2C 2
  • MODE_MASTER: 作为主机模式
  • MODE_SLAVE: 作为从机模式
  • I2C_EV_START: 事件类型,开始信号
  • I2C_EV_RESTART: 事件类型,重新开始信号
  • I2C_EV_STOP: 事件类型,结束信号

例程

例程 1: 扫描从机设备

from machine import I2C

i2c = I2C(I2C.I2C0, freq=100000, scl=28, sda=29)
devices = i2c.scan()
print(devices)

例程 2: 读写

import time
from machine import I2C

i2c = I2C(I2C.I2C0, freq=100000, scl=28, sda=29)
i2c.writeto(0x24,b'123')
i2c.readfrom(0x24,5)

例程 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: OLED(ssd1306 128x64)

import time
from machine import I2C

SSD1306_CMD  = 0
SSD1306_DATA = 1
SSD1306_ADDR = 0x3c

def oled_init(i2c):
    i2c.writeto_mem(SSD1306_ADDR, 0x00, 0xAE, mem_size=8)
    i2c.writeto_mem(SSD1306_ADDR, 0x00, 0x20, mem_size=8)
    i2c.writeto_mem(SSD1306_ADDR, 0x00, 0x10, mem_size=8)
    i2c.writeto_mem(SSD1306_ADDR, 0x00, 0xb0, mem_size=8)
    i2c.writeto_mem(SSD1306_ADDR, 0x00, 0xc8, mem_size=8)
    i2c.writeto_mem(SSD1306_ADDR, 0x00, 0x00, mem_size=8)
    i2c.writeto_mem(SSD1306_ADDR, 0x00, 0x10, mem_size=8)
    i2c.writeto_mem(SSD1306_ADDR, 0x00, 0x40, mem_size=8)
    i2c.writeto_mem(SSD1306_ADDR, 0x00, 0x81, mem_size=8)
    i2c.writeto_mem(SSD1306_ADDR, 0x00, 0xff, mem_size=8)
    i2c.writeto_mem(SSD1306_ADDR, 0x00, 0xa1, mem_size=8)
    i2c.writeto_mem(SSD1306_ADDR, 0x00, 0xa6, mem_size=8)
    i2c.writeto_mem(SSD1306_ADDR, 0x00, 0xa8, mem_size=8)
    i2c.writeto_mem(SSD1306_ADDR, 0x00, 0x3F, mem_size=8)
    i2c.writeto_mem(SSD1306_ADDR, 0x00, 0xa4, mem_size=8)
    i2c.writeto_mem(SSD1306_ADDR, 0x00, 0xd3, mem_size=8)
    i2c.writeto_mem(SSD1306_ADDR, 0x00, 0x00, mem_size=8)
    i2c.writeto_mem(SSD1306_ADDR, 0x00, 0xd5, mem_size=8)
    i2c.writeto_mem(SSD1306_ADDR, 0x00, 0xf0, mem_size=8)
    i2c.writeto_mem(SSD1306_ADDR, 0x00, 0xd9, mem_size=8)
    i2c.writeto_mem(SSD1306_ADDR, 0x00, 0x22, mem_size=8)
    i2c.writeto_mem(SSD1306_ADDR, 0x00, 0xda, mem_size=8)
    i2c.writeto_mem(SSD1306_ADDR, 0x00, 0x12, mem_size=8)
    i2c.writeto_mem(SSD1306_ADDR, 0x00, 0xdb, mem_size=8)
    i2c.writeto_mem(SSD1306_ADDR, 0x00, 0x20, mem_size=8)
    i2c.writeto_mem(SSD1306_ADDR, 0x00, 0x8d, mem_size=8)
    i2c.writeto_mem(SSD1306_ADDR, 0x00, 0x14, mem_size=8)
    i2c.writeto_mem(SSD1306_ADDR, 0x00, 0xaf, mem_size=8)



def oled_on(i2c):
    i2c.writeto_mem(SSD1306_ADDR, 0x00, 0X8D, mem_size=8)
    i2c.writeto_mem(SSD1306_ADDR, 0x00, 0X14, mem_size=8)
    i2c.writeto_mem(SSD1306_ADDR, 0x00, 0XAF, mem_size=8)

def oled_off(i2c):
    i2c.writeto_mem(SSD1306_ADDR, 0x00, 0X8D, mem_size=8)
    i2c.writeto_mem(SSD1306_ADDR, 0x00, 0X10, mem_size=8)
    i2c.writeto_mem(SSD1306_ADDR, 0x00, 0XAE, mem_size=8)

def oled_fill(i2c, data):
    for i in range(0,8):
        i2c.writeto_mem(SSD1306_ADDR, 0x00, 0xb0+i, mem_size=8)
        i2c.writeto_mem(SSD1306_ADDR, 0x00, 0x10, mem_size=8)
        i2c.writeto_mem(SSD1306_ADDR, 0x00, 0x01, mem_size=8)
        for j in range(0,128):
            i2c.writeto_mem(SSD1306_ADDR, 0x40, data, mem_size=8)

i2c = I2C(I2C.I2C0, mode=I2C.MODE_MASTER, freq=400000, scl=28, sda=29, addr_size=7)

time.sleep(1)
oled_init(i2c)
oled_fill(i2c, 0xff)