class I2C – kaksijohtiminen sarjaprotokolla#

I2C on kaksijohtiminen protokolla laitteiden väliseen tiedonsiirtoon. Fyysisellä tasolla se koostuu kahdesta johtimesta: SCL ja SDA, eli kello- ja datalinjasta.

I2C-objektit luodaan liitettyinä tiettyyn väylään. Ne voidaan alustaa luonnin yhteydessä tai myöhemmin.

I2C-objektin tulostaminen antaa tietoa sen kokoonpanosta.

Sekä laitteistopohjaisia että ohjelmistopohjaisia I2C-toteutuksia on olemassa I2C- ja SoftI2C-luokkien kautta. Laitteistopohjainen I2C käyttää järjestelmän laitteistotukea luku- ja kirjoitusoperaatioiden suorittamiseen, ja se on yleensä tehokas ja nopea, mutta voi asettaa rajoituksia siihen, mitä nastoja voidaan käyttää. Ohjelmistopohjainen I2C toteutetaan bittien manuaalisella ohjauksella (bit-banging), ja sitä voidaan käyttää millä tahansa nastalla, mutta se ei ole yhtä tehokas. Näillä luokilla on käytettävissä samat metodit, ja ne eroavat toisistaan ensisijaisesti siinä, miten ne luodaan.

Muista

I2C-väylä vaatii toimiakseen ylösvetokytkennän sekä SDA- että SCL-linjoille. Yleensä nämä ovat vastuksia välillä 1–10 kOhm, jotka on kytketty kustakin SDA/SCL-linjasta Vcc:hen. Ilman näitä käyttäytyminen on määrittelemätöntä ja voi vaihdella jumiutumisesta ja odottamattomasta vahtikoiran (watchdog) nollauksesta aina pelkästään virheellisiin arvoihin. Usein tämä ylösvetokytkentä on jo sisäänrakennettu MCU-korttiin tai sensorin laajennuskortteihin, mutta tästä ei ole mitään sääntöä. Tarkista siis tämä ongelmatilanteissa. Katso myös tämä erinomainen Adafruitin oppimisopas I2C-johdotuksesta.

Esimerkki käytöstä:

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

Konstruktorit#

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

Luo ja palauta uusi I2C-objekti käyttäen seuraavia parametreja:

  • id yksilöi tietyn I2C-oheislaitteen. Sallitut arvot riippuvat tietystä portista/kortista

  • scl tulee olla pin-objekti, joka määrittää SCL-linjalle käytettävän nastan.

  • sda tulee olla pin-objekti, joka määrittää SDA-linjalle käytettävän nastan.

  • freq tulee olla kokonaisluku, joka asettaa SCL:n enimmäistaajuuden.

  • timeout on enimmäisaika mikrosekunteina, joka sallitaan I2C-tapahtumille. Tätä parametria ei sallita kaikissa porteissa.

Huomaa, että joillakin porteilla/korteilla on oletusarvot scl:lle ja sda:lle, jotka voidaan muuttaa tässä konstruktorissa. Toisilla on kiinteät scl- ja sda-arvot, joita ei voi muuttaa.

Yleiset metodit#

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

Alusta I2C-väylä annetuilla argumenteilla:

  • scl on pin-objekti SCL-linjaa varten

  • sda on pin-objekti SDA-linjaa varten

  • freq on SCL-kellotaajuus

Laitteistopohjaisen I2C:n tapauksessa todellinen kellotaajuus voi olla pyydettyä taajuutta alhaisempi. Tämä riippuu alustan laitteistosta. Todellinen taajuus voidaan selvittää tulostamalla I2C-objekti.

scan() List[int]#

Skannaa kaikki I2C-osoitteet välillä 0x08–0x77 (mukaan lukien) ja palauta lista niistä, jotka vastaavat. Laite vastaa, jos se vetää SDA-linjan alas sen jälkeen, kun sen osoite (mukaan lukien kirjoitusbitti) on lähetetty väylälle.

I2C:n primitiivioperaatiot#

Seuraavat metodit toteuttavat I2C-ohjaimen primitiiviset väyläoperaatiot, ja ne voidaan yhdistää minkä tahansa I2C-tapahtuman muodostamiseksi. Ne ovat saatavilla, jos tarvitset enemmän hallintaa väylästä; muutoin voidaan käyttää vakiometodeja (katso alta).

Nämä metodit ovat saatavilla vain SoftI2C-luokassa.

start() None#

Muodosta väylälle START-ehto (SDA siirtyy alas SCL:n ollessa ylhäällä).

stop() None#

Muodosta väylälle STOP-ehto (SDA siirtyy ylös SCL:n ollessa ylhäällä).

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

Lukee tavuja väylältä ja tallentaa ne buf-puskuriin. Luettujen tavujen määrä on buf:n pituus. ACK lähetetään väylälle jokaisen vastaanotetun tavun jälkeen viimeistä lukuun ottamatta. Viimeisen tavun vastaanottamisen jälkeen, jos nack on tosi, lähetetään NACK, muutoin lähetetään ACK (ja tässä tapauksessa oheislaite olettaa, että lisää tavuja luetaan myöhemmässä kutsussa).

write(buf: bytes) int#

Kirjoita tavut buf-puskurista väylälle. Tarkistaa, että ACK vastaanotetaan jokaisen tavun jälkeen, ja lopettaa loppujen tavujen lähettämisen, jos NACK vastaanotetaan. Funktio palauttaa vastaanotettujen ACK-kuittausten määrän.

Vakioväyläoperaatiot#

Seuraavat metodit toteuttavat I2C-ohjaimen vakioluku- ja vakiokirjoitusoperaatiot, jotka kohdistuvat tiettyyn oheislaitteeseen.

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

Lue nbytes tavua addr:lla määritetystä oheislaitteesta. Jos stop on tosi, siirron lopussa muodostetaan STOP-ehto. Palauttaa bytes-objektin luetun datan kanssa.

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

Lue addr:lla määritetystä oheislaitteesta buf-puskuriin. Luettujen tavujen määrä on buf:n pituus. Jos stop on tosi, siirron lopussa muodostetaan STOP-ehto.

Metodi palauttaa None.

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

Kirjoita tavut buf-puskurista addr:lla määritettyyn oheislaitteeseen. Jos NACK vastaanotetaan buf:n tavun kirjoituksen jälkeen, loppuja tavuja ei lähetetä. Jos stop on tosi, siirron lopussa muodostetaan STOP-ehto, vaikka NACK olisi vastaanotettu. Funktio palauttaa vastaanotettujen ACK-kuittausten määrän.

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

Kirjoita vector:ssa olevat tavut addr:lla määritettyyn oheislaitteeseen. vector:n tulee olla monikko tai lista objekteja, jotka tukevat puskuriprotokollaa. addr lähetetään kerran, minkä jälkeen kunkin vector:n objektin tavut kirjoitetaan ulos peräkkäin. vector:n objektit voivat olla pituudeltaan nolla tavua, jolloin ne eivät vaikuta tulosteeseen.

Jos NACK vastaanotetaan jonkin vector:n objektin tavun kirjoituksen jälkeen, loppuja tavuja ja jäljellä olevia objekteja ei lähetetä. Jos stop on tosi, siirron lopussa muodostetaan STOP-ehto, vaikka NACK olisi vastaanotettu. Funktio palauttaa vastaanotettujen ACK-kuittausten määrän.

Muistioperaatiot#

Jotkin I2C-laitteet toimivat muistilaitteena (tai rekisterijoukkona), josta voidaan lukea ja johon voidaan kirjoittaa. Tässä tapauksessa I2C-tapahtumaan liittyy kaksi osoitetta: oheislaitteen osoite ja muistiosoite. Seuraavat metodit ovat apufunktioita tällaisten laitteiden kanssa kommunikointiin.

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

Lue nbytes tavua addr:lla määritetystä oheislaitteesta alkaen memaddr:lla määritetystä muistiosoitteesta. Argumentti addrsize määrittää osoitteen koon bitteinä. Palauttaa bytes-objektin luetun datan kanssa.

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

Lue addr:lla määritetystä oheislaitteesta buf-puskuriin alkaen memaddr:lla määritetystä muistiosoitteesta. Luettujen tavujen määrä on buf:n pituus. Argumentti addrsize määrittää osoitteen koon bitteinä.

Metodi palauttaa None.

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

Kirjoita buf addr:lla määritettyyn oheislaitteeseen alkaen memaddr:lla määritetystä muistiosoitteesta. Argumentti addrsize määrittää osoitteen koon bitteinä.

Metodi palauttaa None.

class SoftI2C – ohjelmistoemuloitu I2C-väylä#

SoftI2C-luokka toteuttaa I2C:n ohjaamalla mielivaltaisia GPIO-nastoja bittitasolla (bit-banging). Se tarjoaa saman metodipinnan kuin I2C sekä matalan tason primitiiviset väyläoperaatiot (start(), stop(), readinto(), write()) niitä kutsujia varten, jotka tarvitsevat epästandardien tapahtumien kokoamista. Käytä sitä, kun tarvitsemiasi nastoja ei ole kytketty laitteistopohjaiseen I2C-lohkoon, kun tarvitset enemmän väyliä kuin laitteisto tarjoaa, tai kun haluat kommunikoida laitteiden kanssa, jotka vaativat epätavallisia sekvenssejä (ylimääräisiä kelloja, toistettuja startteja kirjoitusten jälkeen jne.).

Konstruktorit#

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

Muodosta ohjelmistopohjainen I2C-väylä, jota ohjaavat scl / sda.

freq on kohde-SCL-kellotaajuus hertseinä (todellinen taajuus on tyypillisesti alhaisempi bit-bang-silmukan yleisrasitteen vuoksi).

timeout on enimmäisaika mikrosekunteina, joka odotetaan kellon venyttämistä (clock stretching) varten (toinen väylän laite pitää SCL:n alhaalla); ajan umpeutuessa nostetaan OSError(ETIMEDOUT).

Yleiset metodit#

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

Alusta ohjelmistopohjainen I2C-väylä uudelleen annetuilla nastoilla ja taajuudella. Vastaa uuden SoftI2C:n muodostamista samaan objektiin.

scan() List[int]#

Skannaa kaikki I2C-osoitteet välillä 0x08–0x77 (mukaan lukien) ja palauta lista niistä, jotka vastasivat.

I2C:n primitiivioperaatiot#

Seuraavat metodit toteuttavat I2C-ohjaimen primitiiviset väyläoperaatiot, ja ne voidaan yhdistää minkä tahansa I2C-tapahtuman muodostamiseksi. Ne ovat vain SoftI2C-luokassa – laitteistopohjainen I2C-luokka ei tarjoa niitä.

start() None#

Muodosta väylälle START-ehto (SDA siirtyy alas SCL:n ollessa ylhäällä).

stop() None#

Muodosta väylälle STOP-ehto (SDA siirtyy ylös SCL:n ollessa ylhäällä).

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

Lue tavuja väylältä buf-puskuriin. Luetaan len(buf) tavua; ACK lähetetään jokaisen tavun jälkeen viimeistä lukuun ottamatta. Viimeisen tavun jälkeen nack=True (oletus) lähettää NACK:n siirron päättämiseksi; nack=False lähettää ACK:n, jolloin laite pysyy valittuna seuraavaa readinto()-kutsua varten.

write(buf: bytes) int#

Kirjoita buf väylälle ja tarkista ACK jokaisen tavun jälkeen. Lähetys pysähtyy ensimmäiseen NACK:iin. Palauttaa vastaanotettujen ACK-kuittausten määrän.

Vakioväyläoperaatiot#

Seuraavat metodit toteuttavat I2C-ohjaimen vakioluku- ja vakiokirjoitusoperaatiot, jotka kohdistuvat tiettyyn oheislaitteeseen.

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

Lue nbytes tavua laitteesta 7-bittisessä osoitteessa addr. Jos stop on tosi, siirron lopussa muodostetaan STOP-ehto.

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

Lue len(buf) tavua laitteesta osoitteessa addr buf-puskuriin. Jos stop on tosi, siirron lopussa muodostetaan STOP-ehto.

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

Kirjoita buf laitteeseen osoitteessa addr. Lähetys pysähtyy ensimmäiseen NACK:iin. Jos stop on tosi, siirron lopussa muodostetaan aina STOP-ehto (myös aikaisen NACK:in tapauksessa). Palauttaa vastaanotettujen ACK-kuittausten määrän.

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

Kirjoita vector:n puskureiden yhdistelmä laitteeseen osoitteessa addr yhtenä tapahtumana. Tyhjät puskurit ohitetaan. Toimii stop-semantiikan ja paluuarvon osalta kuten writeto().

Muistioperaatiot#

Jotkin I2C-laitteet toimivat muistilaitteena (tai rekisterijoukkona), josta voidaan lukea ja johon voidaan kirjoittaa. Tässä tapauksessa I2C-tapahtumaan liittyy kaksi osoitetta: oheislaitteen osoite ja muistiosoite. Seuraavat metodit ovat apuvälineitä tällaisten laitteiden kanssa kommunikointiin.

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

Lue nbytes tavua laitteesta osoitteessa addr alkaen rekisteristä memaddr. addrsize on rekisteriosoitteen leveys bitteinä (tyypillisesti 8 tai 16).

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

Lue laitteesta osoitteessa addr buf-puskuriin alkaen rekisteristä memaddr.

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

Kirjoita buf laitteeseen osoitteessa addr alkaen rekisteristä memaddr.