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 kΩ tot 10 kΩ 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:
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 (
0voor schrijven,1voor 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 0x08 – 0x77; 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”) en400 kHz(“fast mode”) dekken vrijwel elke sensor.1 MHzis 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.