3.23. Grondbeginselen van I2C

I2C (Inter-Integrated Circuit, uitgesproken als “I-kwadraat-C” of “I-twee-C”) is een tweedraads seriële bus die is ontworpen voor verbindingen over korte afstand tussen chips op hetzelfde bord. Hij zit qua prioriteiten tussen SPI en UART in: trager dan SPI maar zuiniger met pinnen, en geadresseerd (meerdere apparaten op dezelfde twee draden) waar SPI per apparaat een eigen CS-lijn nodig heeft.

I2C is de bus bij uitstek voor sensoren met een lage snelheid – versnellingsmeters, temperatuursensoren, vochtigheidssensoren, magnetometers, realtimeklokken, EEPROM’s – waar het besparen van pinnen en buscomplexiteit belangrijker is dan ruwe doorvoer.

3.23.1. Twee draden, beide open-drain

Een I2C-bus heeft slechts twee signalen:

  • SCL (seriële klok). Aangestuurd door de controller (meestal).

  • SDA (seriële data). Aangestuurd door welk apparaat op dat moment ook aan het woord is – de controller tijdens het adres en de uitgaande data, het randapparaat tijdens leesbewerkingen en ACK-bits.

Beide lijnen zijn open-drain: elk apparaat op de bus kan de lijn naar de massa trekken maar stuurt hem nooit hoog. Twee pull-upweerstanden op de bus (doorgaans 2.2 tot 10 naar de voedingsrail) trekken de lijnen hoog wanneer niemand ze laag trekt. Het wired-OR-gedrag volgt hieruit – elk apparaat dat de lijn laag trekt wint, en de hoge toestand betekent simpelweg “niemand is aan het woord”.

De interne pull-ups van de MCU op zijn SCL- en SDA-pinnen zijn meestal niet sterk genoeg om op zichzelf als de bus-pull-ups te fungeren; externe weerstanden op de bus zijn normaal gesproken nodig. Veel sensor-breakout-borden bevatten ze al; raadpleeg het databoekje voordat je er meer toevoegt.

3.23.2. De transactie

Elke I2C-transactie heeft dezelfde vorm:

SCL- en SDA-sporen. SDA valt terwijl SCL hoog is (START), daarna klokt SCL bytes op SDA -- een 7-bits adresbyte met een lees/schrijf-bit en een ACK, daarna een registerbyte en een ACK, daarna een databyte en een NACK, daarna stijgt SDA terwijl SCL hoog is (STOP).

Een I2C-transactie: START, 7-bits adres + R/W, ACK, register, ACK, data, NACK, STOP.

De uitwisseling ontvouwt zich bit voor bit:

  • START. De controller trekt SDA laag terwijl SCL nog hoog is. Deze ongewone flank vertelt elk apparaat op de bus dat een transactie op het punt staat te beginnen.

  • Adres + R/W. De controller klokt een 7-bits randapparaatadres uit, gevolgd door één lees/schrijf-bit (0 voor schrijven, 1 voor lezen).

  • ACK / NACK. Na elke byte stuurt de ontvanger SDA gedurende één klok aan om te ACK’en (laag) of NACK’en (hoog). Bij de adresbyte ACK’t het randapparaat als het zijn eigen adres herkent; als geen enkel apparaat ACK’t, ziet de controller een NACK en weet hij dat het adres niet op de bus zit.

  • Databytes. Elke gevolgd door een ACK van de ontvanger. Bij een schrijfbewerking ACK’t het randapparaat elke byte; bij een leesbewerking ACK’t de controller elke byte waar hij meer van wil en NACK’t de laatste byte om het randapparaat te vertellen te stoppen.

  • STOP. De controller laat SDA hoog gaan terwijl SCL hoog is, waarmee de transactie wordt beëindigd.

Een herhaalde start is een tweede START die wordt uitgegeven zonder een STOP ertussen – de controller wisselt van richting (schrijfadres, daarna leesadres) bij hetzelfde randapparaat zonder de bus op te geven.

3.23.3. Adressering

De 7-bits adresruimte bestrijkt 0x080x77; de waarden aan de uiteinden zijn gereserveerd voor speciale doeleinden. Het adres van elk apparaat wordt bepaald door de chipontwerper; veel onderdelen staan toe dat enkele van de lage bits op bordniveau worden gewijzigd (door een pin hoog of laag te koppelen) zodat twee dezelfde sensoren op dezelfde bus kunnen zitten.

Als twee apparaten een adres delen, is er geen manier om met een ervan te praten zonder dat de andere stoort, dus raadpleeg het databoekje voordat je onderdelen koppelt. i2c.scan() (behandeld op I2C in code) doorloopt de adresruimte en rapporteert welke adressen reageren, wat de standaardmanier is om te ontdekken wat er op de bus zit.

3.23.4. Sterke en zwakke punten

De sterke en zwakke punten van de bus bepalen zijn niche:

  • Twee pinnen voor veel apparaten. Een enkel SCL/SDA-paar kan een dozijn sensoren dragen. SPI zou een extra CS-pin per apparaat nodig hebben.

  • Standaardsnelheden. 100 kHz (“standard mode”) en 400 kHz (“fast mode”) dekken vrijwel elke sensor. 1 MHz is haalbaar maar begint meer te vragen van de buscapaciteit en de dimensionering van de pull-ups.

  • Traag ten opzichte van SPI. Alles wat meer dan een paar honderd kilobit per seconde verplaatst, wil liever SPI.

  • Adresconflicten. Twee apparaten met hetzelfde adres op één bus is een hardwarefout die het protocol niet kan omzeilen.