classe I2C – um protocolo serial de dois fios

I2C é um protocolo de dois fios para comunicação entre dispositivos. No nível físico, consiste em duas linhas, SCL (clock) e SDA (dados). A OpenMV Cam não fornece pull-ups embarcados em nenhuma das linhas – pull-ups externos são necessários tanto em SCL quanto em SDA para que o barramento funcione.

Objetos I2C são associados a um barramento específico e podem ser inicializados no momento da construção ou posteriormente via init().

Exemplo:

from pyb import I2C

i2c = I2C(2)                              # create on bus 2 (uninitialised)
i2c = I2C(2, I2C.CONTROLLER)              # create and init as a controller
i2c.init(I2C.CONTROLLER, baudrate=20000)  # init as a controller
i2c.init(I2C.PERIPHERAL, addr=0x42)       # init as a peripheral with the given address
i2c.deinit()                              # turn off the peripheral

Imprimir o objeto I2C mostra sua configuração.

Os métodos básicos são send() e recv()

i2c.send("abc")      # send 3 bytes
i2c.send(0x42)       # send a single byte, given by the number
data = i2c.recv(3)   # receive 3 bytes

Para receber no local, primeiro crie um bytearray

data = bytearray(3)  # create a buffer
i2c.recv(data)       # receive 3 bytes, writing them into data

Você pode especificar um timeout (em ms):

i2c.send(b"123", timeout=2000)   # timeout after 2 seconds

Um controlador deve especificar o endereço do destinatário:

i2c.init(I2C.CONTROLLER)
i2c.send("123", 0x42)        # send 3 bytes to peripheral with address 0x42
i2c.send(b"456", addr=0x42)  # keyword for address

Um controlador também tem estes métodos:

# Check if peripheral 0x42 is ready.
i2c.is_ready(0x42)

# Scan the bus and return a list of responding addresses.
i2c.scan()

# Read 3 bytes from peripheral 0x42 starting at memaddr 2.
i2c.mem_read(3, 0x42, 2)

# Write 3 bytes to peripheral 0x42 at memaddr 2.
i2c.mem_write("abc", 0x42, 2, timeout=1000)

Construtores

class pyb.I2C(bus: int | str, *args, **kwargs)

Constrói um objeto I2C no bus fornecido (um índice inteiro de periférico, ex. 2 para I2C2). Sem parâmetros adicionais, o objeto é criado mas não inicializado (ele mantém as configurações anteriores do barramento, se houver); se argumentos extras forem fornecidos, o barramento é inicializado. Veja init() para os parâmetros disponíveis.

I2C(2) está conectado aos mesmos pinos do header em cada OpenMV Cam que expõe pyb.I2C (M4 / M7 / H7 / H7 Plus / Pure Thermal):

Sinal

Pino do header

Notas

SCL

P4

SDA

P5

I2C(4) está adicionalmente disponível na OpenMV Cam M7, H7, H7 Plus e Pure Thermal com SCL no pino do header P7 e SDA no pino do header P8.

A OpenMV Cam N6 não expõe pyb.I2C; use machine.I2C em vez disso.

Métodos

deinit() None

Desliga o barramento I2C.

init(mode: int, *, addr: int = 0x12, baudrate: int = 400000, gencall: bool = False, dma: bool = False) None

Inicializa o barramento I2C com os parâmetros fornecidos:

  • mode deve ser I2C.CONTROLLER ou I2C.PERIPHERAL.

  • addr é o endereço de 7 bits (só faz sentido para um periférico).

  • baudrate é a taxa do clock SCL (só faz sentido para um controlador).

  • gencall indica se deve suportar o modo de chamada geral (general-call).

  • dma indica se deve permitir o uso de DMA para as transferências I2C (note que as transferências DMA têm temporização mais precisa, mas atualmente não tratam erros de barramento adequadamente).

A frequência real do clock pode ser menor que a frequência solicitada. Isso depende do hardware da plataforma. A taxa real pode ser determinada imprimindo o objeto I2C.

is_ready(addr: int) bool

Verifica se um dispositivo I2C responde no endereço fornecido. Válido apenas no modo controlador.

mem_read(data: int | bytearray, addr: int, memaddr: int, *, timeout: int = 5000, addr_size: int = 8) bytes

Lê da memória de um dispositivo I2C:

  • data pode ser um inteiro (número de bytes a ler) ou um buffer no qual ler

  • addr é o endereço do dispositivo I2C

  • memaddr é a localização de memória dentro do dispositivo I2C

  • timeout é o tempo limite em milissegundos para aguardar a leitura

  • addr_size seleciona a largura de memaddr: 8 ou 16 bits

Retorna os dados lidos. Isso é válido apenas no modo controlador.

mem_write(data: int | bytes | bytearray, addr: int, memaddr: int, *, timeout: int = 5000, addr_size: int = 8) None

Escreve na memória de um dispositivo I2C:

  • data pode ser um inteiro ou um buffer de onde escrever.

  • addr é o endereço do dispositivo I2C.

  • memaddr é a localização de memória dentro do dispositivo I2C.

  • timeout é o tempo limite em milissegundos para aguardar a escrita.

  • addr_size seleciona a largura de memaddr: 8 ou 16 bits.

Válido apenas no modo controlador.

recv(recv: int | bytearray, addr: int = 0x00, *, timeout: int = 5000) bytes

Recebe dados no barramento:

  • recv pode ser um inteiro, que é o número de bytes a receber, ou um buffer mutável, que será preenchido com os bytes recebidos

  • addr é o endereço do qual receber (necessário apenas no modo controlador)

  • timeout é o tempo limite em milissegundos para aguardar a recepção

Valor de retorno: se recv for um inteiro, então um novo buffer com os bytes recebidos; caso contrário, o mesmo buffer que foi passado para recv.

send(send: int | bytes | bytearray, addr: int = 0x00, *, timeout: int = 5000) None

Envia dados no barramento:

  • send são os dados a enviar (um inteiro a enviar, ou um objeto buffer).

  • addr é o endereço para o qual enviar (necessário apenas no modo controlador).

  • timeout é o tempo limite em milissegundos para aguardar o envio.

scan() List[int]

Escaneia todos os endereços I2C de 0x01 a 0x7f e retorna uma lista daqueles que respondem. Válido apenas no modo controlador.

Constantes

CONTROLLER: int

Inicializa o barramento como o mestre (controlador) – ele aciona SCL e inicia as transações.

PERIPHERAL: int

Inicializa o barramento como um escravo (periférico) que escuta no addr definido em init() e responde às transações iniciadas por um controlador no mesmo barramento.