klasa I2C – dvožični serijski protokol

I2C je dvožični protokol za komunikaciju između uređaja. Na fizičkoj razini sastoji se od 2 žice: SCL i SDA, koje su redom linija takta i linija podataka.

I2C objekti stvaraju se pridruženi određenoj sabirnici. Mogu se inicijalizirati pri stvaranju ili kasnije.

Ispis I2C objekta daje vam informacije o njegovoj konfiguraciji.

Postoje i hardverske i softverske implementacije I2C-a putem klasa I2C i SoftI2C. Hardverski I2C koristi temeljnu hardversku podršku sustava za izvođenje čitanja/pisanja te je obično učinkovit i brz, ali može imati ograničenja na to koji se pinovi mogu koristiti. Softverski I2C implementiran je bit-bangingom i može se koristiti na bilo kojem pinu, ali nije toliko učinkovit. Te klase imaju iste dostupne metode i razlikuju se prvenstveno u načinu konstrukcije.

Napomena

I2C sabirnica za svoj rad zahtijeva pull-up sklopovlje na obje linije SDA i SCL. To su obično otpornici u rasponu od 1 - 10 kOhm, spojeni od svake od SDA/SCL linija na Vcc. Bez njih ponašanje je nedefinirano i može varirati od blokiranja, neočekivanog resetiranja watchdoga, do jednostavno pogrešnih vrijednosti. Često je to pull-up sklopovlje već ugrađeno na MCU ploču ili breakout ploče senzora, ali to nije pravilo. Stoga provjerite u slučaju problema. Pogledajte i ovaj izvrstan vodič za učenje tvrtke Adafruit o I2C ožičenju.

Primjer upotrebe:

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

Konstruktori

class machine.I2C(id: int, *, scl: Pin | None = None, sda: Pin | None = None, freq: int = 400000, timeout: int = 50000)

Konstruira i vraća novi I2C objekt koristeći sljedeće parametre:

  • id identificira određenu I2C periferiju. Dopuštene vrijednosti ovise o pojedinom portu/ploči

  • scl treba biti pin objekt koji određuje pin koji će se koristiti za SCL.

  • sda treba biti pin objekt koji određuje pin koji će se koristiti za SDA.

  • freq treba biti cijeli broj koji postavlja maksimalnu frekvenciju za SCL.

  • timeout je maksimalno vrijeme u mikrosekundama dopušteno za I2C transakcije. Ovaj parametar nije dopušten na nekim portovima.

Imajte na umu da neki portovi/ploče imaju zadane vrijednosti za scl i sda koje se mogu promijeniti u ovom konstruktoru. Drugi imaju fiksne vrijednosti za scl i sda koje se ne mogu mijenjati.

Opće metode

init(scl: Pin, sda: Pin, *, freq: int = 400000) None

Inicijalizira I2C sabirnicu s danim argumentima:

  • scl je pin objekt za SCL liniju

  • sda je pin objekt za SDA liniju

  • freq je brzina SCL takta

U slučaju hardverskog I2C-a, stvarna frekvencija takta može biti niža od tražene frekvencije. To ovisi o hardveru platforme. Stvarna brzina može se utvrditi ispisom I2C objekta.

scan() List[int]

Skenira sve I2C adrese između 0x08 i 0x77 uključivo i vraća popis onih koje odgovaraju. Uređaj odgovara ako povuče SDA liniju nisko nakon što je njegova adresa (uključujući bit pisanja) poslana na sabirnicu.

Primitivne I2C operacije

Sljedeće metode implementiraju primitivne operacije I2C upravljača na sabirnici i mogu se kombinirati za bilo koju I2C transakciju. Pružene su ako vam je potrebna veća kontrola nad sabirnicom, inače se mogu koristiti standardne metode (vidi dolje).

Ove su metode dostupne samo u klasi SoftI2C.

start() None

Generira START uvjet na sabirnici (SDA prelazi u nisko stanje dok je SCL u visokom stanju).

stop() None

Generira STOP uvjet na sabirnici (SDA prelazi u visoko stanje dok je SCL u visokom stanju).

readinto(buf: bytearray, nack: bool = True, /) None

Čita bajtove sa sabirnice i pohranjuje ih u buf. Broj pročitanih bajtova je duljina buf. ACK će biti poslan na sabirnicu nakon primanja svih bajtova osim posljednjeg. Nakon što je primljen posljednji bajt, ako je nack istinit tada će biti poslan NACK, inače će biti poslan ACK (a u tom slučaju periferija pretpostavlja da će se više bajtova čitati u kasnijem pozivu).

write(buf: bytes) int

Zapisuje bajtove iz buf na sabirnicu. Provjerava je li ACK primljen nakon svakog bajta i prestaje prenositi preostale bajtove ako se primi NACK. Funkcija vraća broj primljenih ACK-ova.

Standardne operacije sabirnice

Sljedeće metode implementiraju standardne operacije čitanja i pisanja I2C upravljača koje ciljaju zadani periferni uređaj.

readfrom(addr: int, nbytes: int, stop: bool = True, /) bytes

Čita nbytes s periferije određene s addr. Ako je stop istinit tada se na kraju prijenosa generira STOP uvjet. Vraća bytes objekt s pročitanim podacima.

readfrom_into(addr: int, buf: bytearray, stop: bool = True, /) None

Čita u buf s periferije određene s addr. Broj pročitanih bajtova bit će duljina buf. Ako je stop istinit tada se na kraju prijenosa generira STOP uvjet.

Metoda vraća None.

writeto(addr: int, buf: bytes, stop: bool = True, /) int

Zapisuje bajtove iz buf na periferiju određenu s addr. Ako se primi NACK nakon zapisivanja bajta iz buf tada se preostali bajtovi ne šalju. Ako je stop istinit tada se na kraju prijenosa generira STOP uvjet, čak i ako se primi NACK. Funkcija vraća broj primljenih ACK-ova.

writevto(addr: int, vector: tuple | list, stop: bool = True, /) int

Zapisuje bajtove sadržane u vector na periferiju određenu s addr. vector treba biti torka ili popis objekata s buffer protokolom. addr se šalje jednom, a zatim se bajtovi iz svakog objekta u vector zapisuju redom. Objekti u vector mogu imati duljinu nula bajtova u kojem slučaju ne doprinose izlazu.

Ako se primi NACK nakon zapisivanja bajta iz jednog od objekata u vector tada se preostali bajtovi i svi preostali objekti ne šalju. Ako je stop istinit tada se na kraju prijenosa generira STOP uvjet, čak i ako se primi NACK. Funkcija vraća broj primljenih ACK-ova.

Memorijske operacije

Neki I2C uređaji ponašaju se kao memorijski uređaj (ili skup registara) iz kojeg se može čitati i u koji se može pisati. U tom slučaju s I2C transakcijom su povezane dvije adrese: adresa periferije i adresa memorije. Sljedeće metode su pomoćne funkcije za komunikaciju s takvim uređajima.

readfrom_mem(addr: int, memaddr: int, nbytes: int, *, addrsize: int = 8) bytes

Čita nbytes s periferije određene s addr počevši od memorijske adrese određene s memaddr. Argument addrsize određuje veličinu adrese u bitovima. Vraća bytes objekt s pročitanim podacima.

readfrom_mem_into(addr: int, memaddr: int, buf: bytearray, *, addrsize: int = 8) None

Čita u buf s periferije određene s addr počevši od memorijske adrese određene s memaddr. Broj pročitanih bajtova je duljina buf. Argument addrsize određuje veličinu adrese u bitovima.

Metoda vraća None.

writeto_mem(addr: int, memaddr: int, buf: bytes, *, addrsize: int = 8) None

Zapisuje buf na periferiju određenu s addr počevši od memorijske adrese određene s memaddr. Argument addrsize određuje veličinu adrese u bitovima.

Metoda vraća None.

klasa SoftI2C – softverski emulirana I2C sabirnica

Klasa SoftI2C implementira I2C bit-bangingom proizvoljnih GPIO pinova. Izlaže istu površinu metoda kao I2C plus niskorazinske primitivne operacije sabirnice (start(), stop(), readinto(), write()) za pozivatelje kojima su potrebne nestandardne transakcije. Koristite je kada pinovi koji su vam potrebni nisu ožičeni na hardverski I2C blok, kada vam treba više sabirnica nego što ih hardver pruža, ili za komunikaciju s uređajima koji zahtijevaju neuobičajene sekvence (dodatni taktovi, ponovljeni startovi nakon pisanja itd.).

Konstruktori

class machine.SoftI2C(scl: Pin, sda: Pin, *, freq: int = 400000, timeout: int = 50000)

Konstruira softversku I2C sabirnicu pokretanu s scl / sda.

freq je ciljana brzina SCL takta u Hz (stvarna brzina obično je niža zbog dodatnih troškova bit-bang petlje).

timeout je maksimalno vrijeme u mikrosekundama za čekanje na rastezanje takta (SCL drži nisko drugi uređaj na sabirnici); po isteku se podiže OSError(ETIMEDOUT).

Opće metode

init(scl: Pin, sda: Pin, *, freq: int = 400000) None

Ponovno inicijalizira softversku I2C sabirnicu s danim pinovima i frekvencijom. Ekvivalentno konstruiranju nove SoftI2C na istom objektu.

scan() List[int]

Skenira sve I2C adrese između 0x08 i 0x77 uključivo i vraća popis onih koje su odgovorile.

Primitivne I2C operacije

Sljedeće metode implementiraju primitivne operacije I2C upravljača na sabirnici i mogu se kombinirati za bilo koju I2C transakciju. Dostupne su samo u SoftI2C-u – hardverska klasa I2C ih ne izlaže.

start() None

Generira START uvjet na sabirnici (SDA prelazi u nisko stanje dok je SCL u visokom stanju).

stop() None

Generira STOP uvjet na sabirnici (SDA prelazi u visoko stanje dok je SCL u visokom stanju).

readinto(buf: bytearray, nack: bool = True, /) None

Čita bajtove sa sabirnice u buf. Čita se len(buf) bajtova; ACK se šalje nakon svakog bajta osim posljednjeg. Nakon posljednjeg bajta, nack=True (zadano) šalje NACK za završetak prijenosa; nack=False šalje ACK tako da uređaj ostaje odabran za naknadni readinto().

write(buf: bytes) int

Zapisuje buf na sabirnicu, provjeravajući ACK nakon svakog bajta. Prijenos se zaustavlja na prvom NACK-u. Vraća broj primljenih ACK-ova.

Standardne operacije sabirnice

Sljedeće metode implementiraju standardne operacije čitanja i pisanja I2C upravljača koje ciljaju zadani periferni uređaj.

readfrom(addr: int, nbytes: int, stop: bool = True, /) bytes

Čita nbytes s uređaja na 7-bitnoj adresi addr. Ako je stop istinit, na kraju prijenosa se generira STOP uvjet.

readfrom_into(addr: int, buf: bytearray, stop: bool = True, /) None

Čita len(buf) bajtova s uređaja na addr u buf. Ako je stop istinit, na kraju prijenosa se generira STOP uvjet.

writeto(addr: int, buf: bytes, stop: bool = True, /) int

Zapisuje buf na uređaj na addr. Prijenos se zaustavlja na prvom NACK-u. Ako je stop istinit, STOP uvjet se uvijek generira na kraju prijenosa (čak i kod ranog NACK-a). Vraća broj primljenih ACK-ova.

writevto(addr: int, vector: tuple | list, stop: bool = True, /) int

Zapisuje konkatenaciju međuspremnika iz vector na uređaj na addr kao jednu transakciju. Prazni međuspremnici se zanemaruju. Ponaša se kao writeto() glede stop semantike i povratne vrijednosti.

Memorijske operacije

Neki I2C uređaji ponašaju se kao memorijski uređaj (ili skup registara) iz kojeg se može čitati i u koji se može pisati. U tom slučaju s I2C transakcijom su povezane dvije adrese: adresa periferije i adresa memorije. Sljedeće metode su pomoćni alati za komunikaciju s takvim uređajima.

readfrom_mem(addr: int, memaddr: int, nbytes: int, *, addrsize: int = 8) bytes

Čita nbytes s uređaja na addr počevši od registra memaddr. addrsize je širina adrese registra u bitovima (obično 8 ili 16).

readfrom_mem_into(addr: int, memaddr: int, buf: bytearray, *, addrsize: int = 8) None

Čita u buf s uređaja na addr počevši od registra memaddr.

writeto_mem(addr: int, memaddr: int, buf: bytes, *, addrsize: int = 8) None

Zapisuje buf na uređaj na addr počevši od registra memaddr.