classe I2C – un protocole série à deux fils

I2C est un protocole à deux fils pour communiquer entre appareils. Au niveau physique, il se compose de deux lignes, SCL (horloge) et SDA (données). L’OpenMV Cam ne fournit pas de résistances de tirage embarquées sur l’une ou l’autre ligne – des résistances de tirage externes sont requises à la fois sur SCL et SDA pour que le bus fonctionne.

Les objets I2C sont attachés à un bus spécifique et peuvent être initialisés au moment de la construction ou plus tard via init().

Exemple

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

L’affichage de l’objet I2C montre sa configuration.

Les méthodes de base sont send() et 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

Pour recevoir sur place, créez d’abord un bytearray

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

Vous pouvez spécifier un délai d’expiration (en ms)

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

Un contrôleur doit spécifier l’adresse du destinataire

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

Un contrôleur dispose également de ces méthodes

# 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)

Constructeurs

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

Construit un objet I2C sur le bus donné (un index entier de périphérique, par exemple 2 pour I2C2). Sans paramètres supplémentaires, l’objet est créé mais non initialisé (il conserve les réglages de bus précédents, le cas échéant) ; si des arguments supplémentaires sont fournis, le bus est initialisé. Voir init() pour les paramètres disponibles.

I2C(2) est câblé aux mêmes broches d’embase sur chaque OpenMV Cam qui expose pyb.I2C (M4 / M7 / H7 / H7 Plus / Pure Thermal) :

Signal

Broche d’embase

Notes

SCL

P4

SDA

P5

I2C(4) est en outre disponible sur les OpenMV Cam M7, H7, H7 Plus et Pure Thermal, avec SCL sur la broche d’embase P7 et SDA sur la broche d’embase P8.

L’OpenMV Cam N6 n’expose pas pyb.I2C ; utilisez plutôt machine.I2C.

Méthodes

deinit() None

Désactive le bus I2C.

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

Initialise le bus I2C avec les paramètres donnés :

  • mode doit valoir soit I2C.CONTROLLER soit I2C.PERIPHERAL.

  • addr est l’adresse 7 bits (n’a de sens que pour un périphérique).

  • baudrate est la fréquence d’horloge SCL (n’a de sens que pour un contrôleur).

  • gencall indique s’il faut prendre en charge le mode d’appel général.

  • dma indique s’il faut autoriser l’utilisation du DMA pour les transferts I2C (notez que les transferts DMA ont un timing plus précis mais ne gèrent actuellement pas correctement les erreurs de bus).

La fréquence d’horloge réelle peut être inférieure à la fréquence demandée. Cela dépend du matériel de la plateforme. La fréquence réelle peut être déterminée en affichant l’objet I2C.

is_ready(addr: int) bool

Vérifie si un appareil I2C répond à l’adresse donnée. Valide uniquement en mode contrôleur.

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

Lit depuis la mémoire d’un appareil I2C :

  • data peut être un entier (nombre d’octets à lire) ou un tampon dans lequel lire

  • addr est l’adresse de l’appareil I2C

  • memaddr est l’emplacement mémoire dans l’appareil I2C

  • timeout est le délai d’expiration en millisecondes à attendre pour la lecture

  • addr_size sélectionne la largeur de memaddr : 8 ou 16 bits

Renvoie les données lues. Ceci n’est valide qu’en mode contrôleur.

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

Écrit dans la mémoire d’un appareil I2C :

  • data peut être un entier ou un tampon depuis lequel écrire.

  • addr est l’adresse de l’appareil I2C.

  • memaddr est l’emplacement mémoire dans l’appareil I2C.

  • timeout est le délai d’expiration en millisecondes à attendre pour l’écriture.

  • addr_size sélectionne la largeur de memaddr : 8 ou 16 bits.

Valide uniquement en mode contrôleur.

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

Reçoit des données sur le bus :

  • recv peut être un entier, qui est le nombre d’octets à recevoir, ou un tampon mutable, qui sera rempli avec les octets reçus

  • addr est l’adresse depuis laquelle recevoir (requise uniquement en mode contrôleur)

  • timeout est le délai d’expiration en millisecondes à attendre pour la réception

Valeur de retour : si recv est un entier, alors un nouveau tampon contenant les octets reçus, sinon le même tampon que celui passé à recv.

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

Envoie des données sur le bus :

  • send est la donnée à envoyer (un entier à envoyer, ou un objet tampon).

  • addr est l’adresse à laquelle envoyer (requise uniquement en mode contrôleur).

  • timeout est le délai d’expiration en millisecondes à attendre pour l’envoi.

scan() List[int]

Analyse toutes les adresses I2C de 0x01 à 0x7f et renvoie une liste de celles qui répondent. Valide uniquement en mode contrôleur.

Constantes

CONTROLLER: int

Initialise le bus en tant que maître (contrôleur) – il pilote SCL et initie les transactions.

PERIPHERAL: int

Initialise le bus en tant qu’esclave (périphérique) qui écoute sur l’adresse addr définie dans init() et répond aux transactions démarrées par un contrôleur sur le même bus.