classe I2C – um protocolo serial de dois fios¶
I2C é um protocolo de dois fios para comunicação entre dispositivos. No nível físico, ele consiste em 2 fios: SCL e SDA, as linhas de clock e de dados, respectivamente.
Os objetos I2C são criados associados a um barramento específico. Eles podem ser inicializados no momento da criação ou inicializados posteriormente.
Imprimir o objeto I2C fornece informações sobre sua configuração.
Existem implementações de I2C tanto em hardware quanto em software, por meio das classes I2C e SoftI2C. O I2C de hardware utiliza o suporte de hardware subjacente do sistema para realizar as leituras/escritas e geralmente é eficiente e rápido, mas pode ter restrições sobre quais pinos podem ser usados. O I2C de software é implementado por bit-banging e pode ser usado em qualquer pino, mas não é tão eficiente. Essas classes têm os mesmos métodos disponíveis e diferem principalmente na forma como são construídas.
Nota
O barramento I2C requer circuitos de pull-up tanto em SDA quanto em SCL para seu funcionamento. Normalmente esses são resistores na faixa de 1 a 10 kOhm, conectados de cada SDA/SCL ao Vcc. Sem eles, o comportamento é indefinido e pode variar de bloqueio, reinicialização inesperada do watchdog, até apenas valores incorretos. Frequentemente, esse circuito de pull-up já vem embutido na placa do MCU ou em placas de breakout do sensor, mas não há uma regra para isso. Portanto, verifique em caso de problemas. Veja também este excelente guia de aprendizado da Adafruit sobre o cabeamento I2C.
Exemplo de uso:
from machine import I2C
i2c = I2C(freq=400000) # create I2C peripheral at frequency of 400kHz
# depending on the port, extra parameters may be required
# to select the peripheral and/or pins to use
i2c.scan() # scan for peripherals, returning a list of 7-bit addresses
i2c.writeto(42, b'123') # write 3 bytes to peripheral with 7-bit address 42
i2c.readfrom(42, 4) # read 4 bytes from peripheral with 7-bit address 42
i2c.readfrom_mem(42, 8, 3) # read 3 bytes from memory of peripheral 42,
# starting at memory-address 8 in the peripheral
i2c.writeto_mem(42, 2, b'\x10') # write 1 byte to memory of peripheral 42
# starting at address 2 in the peripheral
Construtores¶
- class machine.I2C(id: int, *, scl: Pin | None = None, sda: Pin | None = None, freq: int = 400000, timeout: int = 50000)¶
Constrói e retorna um novo objeto I2C usando os seguintes parâmetros:
id identifica um periférico I2C específico. Os valores permitidos dependem da porta/placa específica
scl deve ser um objeto de pino que especifica o pino a ser usado para SCL.
sda deve ser um objeto de pino que especifica o pino a ser usado para SDA.
freq deve ser um inteiro que define a frequência máxima para SCL.
timeout é o tempo máximo em microssegundos permitido para transações I2C. Esse parâmetro não é permitido em algumas portas.
Observe que algumas portas/placas terão valores padrão de scl e sda que podem ser alterados neste construtor. Outras terão valores fixos de scl e sda que não podem ser alterados.
Métodos Gerais¶
- init(scl: Pin, sda: Pin, *, freq: int = 400000) None¶
Inicializa o barramento I2C com os argumentos fornecidos:
scl é um objeto de pino para a linha SCL
sda é um objeto de pino para a linha SDA
freq é a taxa de clock de SCL
No caso do I2C de hardware, a frequência de clock real pode ser menor do que a frequência solicitada. Isso depende do hardware da plataforma. A taxa real pode ser determinada imprimindo o objeto I2C.
Operações I2C primitivas¶
Os métodos a seguir implementam as operações primitivas do barramento do controlador I2C e podem ser combinados para realizar qualquer transação I2C. Eles são fornecidos caso você precise de mais controle sobre o barramento; caso contrário, os métodos padrão (veja abaixo) podem ser usados.
Esses métodos estão disponíveis apenas na classe
SoftI2C.- start() None¶
Gera uma condição START no barramento (SDA transita para baixo enquanto SCL está alto).
- readinto(buf: bytearray, nack: bool = True, /) None¶
Lê bytes do barramento e os armazena em buf. O número de bytes lidos é o comprimento de buf. Um ACK será enviado no barramento após o recebimento de todos os bytes, exceto o último. Após o recebimento do último byte, se nack for verdadeiro, um NACK será enviado; caso contrário, um ACK será enviado (e, nesse caso, o periférico assume que mais bytes serão lidos em uma chamada posterior).
Operações padrão do barramento¶
Os métodos a seguir implementam as operações padrão de leitura e escrita do controlador I2C que têm como alvo um dispositivo periférico específico.
- readfrom(addr: int, nbytes: int, stop: bool = True, /) bytes¶
Lê nbytes do periférico especificado por addr. Se stop for verdadeiro, uma condição STOP é gerada ao final da transferência. Retorna um objeto
bytescom os dados lidos.
- readfrom_into(addr: int, buf: bytearray, stop: bool = True, /) None¶
Lê em buf a partir do periférico especificado por addr. O número de bytes lidos será o comprimento de buf. Se stop for verdadeiro, uma condição STOP é gerada ao final da transferência.
O método retorna
None.
- writeto(addr: int, buf: bytes, stop: bool = True, /) int¶
Escreve os bytes de buf no periférico especificado por addr. Se um NACK for recebido após a escrita de um byte de buf, os bytes restantes não são enviados. Se stop for verdadeiro, uma condição STOP é gerada ao final da transferência, mesmo que um NACK seja recebido. A função retorna o número de ACKs que foram recebidos.
- writevto(addr: int, vector: tuple | list, stop: bool = True, /) int¶
Escreve os bytes contidos em vector no periférico especificado por addr. vector deve ser uma tupla ou lista de objetos com o protocolo de buffer. O addr é enviado uma vez e, em seguida, os bytes de cada objeto em vector são escritos sequencialmente. Os objetos em vector podem ter comprimento zero, caso em que não contribuem para a saída.
Se um NACK for recebido após a escrita de um byte de um dos objetos em vector, os bytes restantes, e quaisquer objetos restantes, não são enviados. Se stop for verdadeiro, uma condição STOP é gerada ao final da transferência, mesmo que um NACK seja recebido. A função retorna o número de ACKs que foram recebidos.
Operações de memória¶
Alguns dispositivos I2C atuam como um dispositivo de memória (ou conjunto de registradores) que pode ser lido e escrito. Nesse caso, há dois endereços associados a uma transação I2C: o endereço do periférico e o endereço de memória. Os métodos a seguir são funções de conveniência para comunicação com esses dispositivos.
- readfrom_mem(addr: int, memaddr: int, nbytes: int, *, addrsize: int = 8) bytes¶
Lê nbytes do periférico especificado por addr a partir do endereço de memória especificado por memaddr. O argumento addrsize especifica o tamanho do endereço em bits. Retorna um objeto
bytescom os dados lidos.
- readfrom_mem_into(addr: int, memaddr: int, buf: bytearray, *, addrsize: int = 8) None¶
Lê em buf a partir do periférico especificado por addr começando no endereço de memória especificado por memaddr. O número de bytes lidos é o comprimento de buf. O argumento addrsize especifica o tamanho do endereço em bits.
O método retorna
None.
classe SoftI2C – barramento I2C emulado por software¶
A classe SoftI2C implementa I2C por meio de bit-banging em pinos GPIO arbitrários. Ela expõe o mesmo conjunto de métodos que I2C além das operações primitivas de baixo nível do barramento (start(), stop(), readinto(), write()) para chamadores que precisam montar transações não padronizadas. Use-a quando os pinos de que você precisa não estiverem conectados a um bloco I2C de hardware, quando você precisar de mais barramentos do que o hardware fornece, ou para conversar com dispositivos que exigem sequências incomuns (clocks extras, starts repetidos após escritas, etc.).
Construtores¶
- class machine.SoftI2C(scl: Pin, sda: Pin, *, freq: int = 400000, timeout: int = 50000)¶
Constrói um barramento I2C de software controlado por
scl/sda.freqé a taxa de clock de SCL desejada em Hz (a taxa real é normalmente menor devido à sobrecarga do laço de bit-bang).timeouté o tempo máximo em microssegundos para aguardar o clock stretching (SCL mantido em nível baixo por outro dispositivo no barramento); ao expirar, umOSError(ETIMEDOUT)é levantado.Métodos Gerais¶
Operações I2C primitivas¶
Os métodos a seguir implementam as operações primitivas do barramento do controlador I2C e podem ser combinados para realizar qualquer transação I2C. Eles são exclusivos do SoftI2C – a classe
I2Cde hardware não os expõe.- start() None¶
Gera uma condição START no barramento (SDA transita para baixo enquanto SCL está alto).
- readinto(buf: bytearray, nack: bool = True, /) None¶
Lê bytes do barramento para
buf.len(buf)bytes são lidos; um ACK é enviado após cada byte, exceto o último. Após o último byte,nack=True(o padrão) envia um NACK para encerrar a transferência;nack=Falseenvia um ACK para que o dispositivo permaneça selecionado para umreadinto()subsequente.
Operações padrão do barramento¶
Os métodos a seguir implementam as operações padrão de leitura e escrita do controlador I2C que têm como alvo um dispositivo periférico específico.
- readfrom(addr: int, nbytes: int, stop: bool = True, /) bytes¶
Lê
nbytesdo dispositivo no endereço de 7 bitsaddr. Sestopfor verdadeiro, uma condição STOP é gerada ao final da transferência.
- readfrom_into(addr: int, buf: bytearray, stop: bool = True, /) None¶
Lê
len(buf)bytes do dispositivo emaddrparabuf. Sestopfor verdadeiro, uma condição STOP é gerada ao final da transferência.
Operações de memória¶
Alguns dispositivos I2C atuam como um dispositivo de memória (ou conjunto de registradores) que pode ser lido e escrito. Nesse caso, há dois endereços associados a uma transação I2C: o endereço do periférico e o endereço de memória. Os métodos a seguir são auxiliares de conveniência para conversar com esses dispositivos.
- readfrom_mem(addr: int, memaddr: int, nbytes: int, *, addrsize: int = 8) bytes¶
Lê
nbytesdo dispositivo emaddra partir do registradormemaddr.addrsizeé a largura do endereço de registrador em bits (normalmente8ou16).