Bevezetés
Ebben a bejegyzésben szó lesz az I2C kommunikációs protokollról, hogy miért jó használni, és hogy hogyan működik.
Az inter-IC (I2C) protokoll olyan kommunikációs forma, amely lehetővé teszi, hogy több slave IC kommunikáljon egy vagy több masterrel (master: ő a "főnök, ő felel a kommunikációért, slave (a jelentése szerint szolga): tőle tudjuk lekérni az információt amire szükségünk van (pl. hőmérő), vagy neki tudunk információt küldeni pl. egy kijelző esetében). A SPI-hez hasonlóan csak közeli eszközök közötti kommunikációra szánják, egyetlen készüléken belül, ennek ellenére sikerrel valósítottak meg kommunikációt 100 m távolságra is. Az aszinkron soros rendszerekhez (például RS-232 vagy UART) hasonlóan csak két jelvezeték szükséges az információ cseréjéhez.
Ajánlott olvasmány a bejegyzésben foglaltak megértéséhez
Ha nem ismeri az alábbi témák egyikét, akkor érdemes elolvasnia azokat, mielőtt elolvassa ezt a bejegyzést:
- Soros kommunikáció (angol)
- SPI kommunikáció (magyar)
- Bináris rendszerek (angol)
- Szintillesztők (angol)
- Logikai szintek (magyar)
Miért használjuk az I2C-t?
Ahhoz, hogy megértse, miért jó használni az I2C protokollt, először hasonlítsa össze a többi általánosan használt rendszerrel, hogy lássa, miben különbözik.
Mi a probléma az UART-tal?
Mivel ez a soros kommunikáció asszinkron (nincsenek órajeladatok), az őket használó eszközöknek előre kell megállapodniuk az adatsebességről. A két készüléknek ugyanolyan sebességűnek kell lennie, ha a sebességükben túl nagy eltérés van, akkor az adatok átvitele nem 100 százalékosan garantálható.
Az aszinkron soros adatátvitel hardveres megvalósítást igényel, nehéz szoftveresen megvalósítani a pontosan és jól működő adatátvitelt. Ráadásul ezen kommunikáció sajátossága miatt - start illetve stop biteket is kell küldenünk, ez a gyakorlatban azt eredményezi, hogy minden 8 elküldött bit mellé kell még küldeni kettőt, ami a sebességet jelentősen lassítja.
Az aszinkron soros portok másik alapvető hibája az, hogy a kétirányú kommunikációt jellemzően csak 2 eszköz között tudja megvalósítani. Lehet kisebb trükkökkel több eszközt is csatlakoztatni hozzá, de alapjában véve akkor is 2 eszköz közötti kommunikáció megvalósítására tervezték.
Végül az adatsebesség is problémát jelent. Bár az aszinkron soros kommunikációnak nincs elméleti korlátja, a legtöbb UART eszköz csak bizonyos rögzített átviteli sebességeket támogat, és ezek közül a legmagasabbak általában 230400 bit másodpercenként.
Mi a probléma az SPI-vel?
Az SPI legnyilvánvalóbb hátránya a szükséges vezetékek száma. Egy mester csatlakoztatása egyetlen slave-hez egy SPI buszhoz négy vezetéket igényel; minden további slave egy további lábat igényel a kiválasztáshoz. Ez nem kívánatos abban az esetben, ha sok slave eszközzel kell dolgoznunk. Továbbá, az egyes készülékek nagy számú kapcsolata megnehezítheti a nyomtatott áramkör megtervezését abban az esetben, ha kisméretű NYÁK-ot kell terveznünk. Az SPI csak egy mestert engedélyez a buszon, de támogatja a tetszőleges számú slave-et (csak a szabad IO száma korlátozza).
Az SPI jó adatátviteli sebességű, teljes duplex (adatküldés és -fogadás) kapcsolatokhoz, néhány eszköz esetében pedig 10MHz-es (és így 10 millió bit másodpercenkénti) órajeleket támogat, és a sebessége jól skálázható. A hardver mindkét végén általában egy nagyon egyszerű szintillesztő található, amely lehetővé teszi az egyszerű szoftveres megvalósítást.
Ismerkedjünk meg az I2C-vel, amely mind a két rendszer előnyeit nyújtja:
Az I2C csak két vezetéket igényel, mint például az aszinkron soros kommunikáció, de a két vezetéken akár 1008 slave eszközt is csatlakoztathatunk. Szintén az SPI-vel ellentétben az I2C többmesteres rendszert is támogathat, amely lehetővé teszi, hogy egynél több mester kommunikáljon a busz összes eszközével (bár a masterek nem tudnak egymással beszélni a buszon, és a buszvonalak használata egyidőben csak egy masternek engedélyezett).
Az adatsebesség az aszinkron soros és az SPI között van. A legtöbb I2C eszköz képes kommunikálni 100 kHz-en vagy 400 kHz-en. Az I2C-nél a küldendő adatok minden 8 bitje után meg kell küldeni egy extra bit metaadatot (az „ACK / NACK” bit, amelyet később tárgyalunk).
Az I2C használatához szükséges hardver bonyolultabb, mint az SPI esetében használt, de kevésbé bonyolult, mint az aszinkron sorosé. Szoftveres oldalról meglehetősen egyszerű használni.
I2C - rövid történet
Az I2C-t eredetileg 1982-ben fejlesztette ki Philips a saját integrált áramköreihez. Az eredeti specifikáció csak 100 kHz-es kommunikációt engedélyezett, és csak 7 bites címekre vonatkozott, korlátozva a buszon lévő eszközök számát 112-re (több fenntartott cím létezik, amelyeket soha nem használnak érvényes I2C-címekhez). 1992-ben közzétették az első nyilvános specifikációt, amely 400 kHz-es sebességet és bővített, 10-bites címzést engedélyezett. A legtöbb eszköz (például az ATMega328 az Arduinonál) ezt a sebességet támogatja. Három további üzemmód áll még rendelkezésre: a gyors üzemmód 1MHz-en, a nagy sebességű üzemmód 3,4 MHz-en és a rendkívül gyors üzemmód, ami 5MHz-en képes kommunikálni.
Az Intel 1995-ben kiadott egy I2C variánst, „System Management Bus” néven (SMBus). Az SMBus egy szigorúbban szabályozott protokoll, amely a PC alaplapján lévő támogató IC-k közötti kommunikáció megvalósítására szolgál, az elsődleges szempont a lehető legmegbízhatóbb működés volt. A legjelentősebb különbség az SMBus és az I2C között az az, hogy 100 kHz-re korlátozza a sebességet, míg az I2C maximálisan 5MHz-es sebességet tesz lehetővé. Az SMBus tartalmaz egy óra időtúllépési módot, amely az alacsony sebességű műveleteket tiltja. Sok SMBus eszköz támogatja mindazonáltal a beágyazott I2C rendszerekkel való együttműködést.
I2C a hardver szintjén
Jelek:
Minden I2C busz két jelből áll: SCL és SDA. Az SCL (SerialCLock) az órajel, és az SDA (SerialData) az adatjel. Az órajelet mindig az aktuális mester generálja. Egyes slave eszközök le tudják húzni alacsonyra az órajelet, ezzel késleltetvén a master által küldött adatfolyamot. Ezt „órajel-nyújtásnak” nevezik, és a protokolloldalon ismertetjük.
Ellentétben az UART vagy SPI kapcsolatokkal, az I2C meghajtók „open drain” elven működnek, ami azt jelenti, hogy a megfelelő jelvezetéket alacsonyra tudják húzni, de nem képesek magasra szintet ráadni. Tehát nem fordulhat elő olyan helyzet, hogy az egyik eszköz feszültséget ad a buszra, amíg a másik éppen lehuzná a földre (zárlat).Mindegyik jelvezetékre beszerelésre kerül egy felhúzó-ellenállás, amely biztosítja a jelvezeték magas szintjét abban az esetben, ha az egyik eszköz sem húzza le alacsony szintre.
A képen látható a 2 db 4.7k értékű felhúzó ellenállás
Az ellenállás kiválasztása a buszon lévő készülékektől függ, de jó ökölszabály az, hogy 4,7k-val kezdjük és szükség kisebbre cseréljük. Az I2C meglehetősen robusztus protokoll, és rövid vezetékekkel (2-3 m) használható. Hosszabb vezetékeknél, vagy sok buszra csatlakoztatott eszköznél a felhúzó ellenállás értékének a csökkentése javasolt.
Jelszintek
Mivel a buszon történő kommunikációhoz nincs szükség a master vagy a slave által magas jelszintet kapcsolni a buszhálózatra, ezért a magas jelszintet rugalmasabban tudják az eszközök kezelni. Abban az esetben, ha a rendszer elemei különböző feszültségen üzemelnek, az alacsonyabb feszültségű rendszer tápfeszültségére kell a felhúzó ellenállásokat rakni. A maximális feszültség különbség csak annyi lehet, ahol még a magasabb feszültségű rendszer logikai szintjének magasba billentéséhez elegendő az alacsonyabb feszültségű rendszer feszültsége. Ilyen esetben nem kell szintillesztőt használni. Ezért lehet pl. egy 5 voltos arduinora csatlakoztatni egy 3,3 voltos gyorsulásmérőt.
Ha a két rendszer közötti feszültségkülönbség túl nagy (mondjuk 5 V és 2,5 V), a SparkFun kínál egy egyszerű I2C szintillesztőt. Mivel a kártya tartalmaz egy engedélyező lábat is, felhasználható a kiválasztott eszközökkel folytatott kommunikáció letiltására. Ez akkor hasznos, amikor egyazon címhez egynél több eszközt kell csatlakoztatni - a Wii Nunchaku jó példa erre.
A protokoll
Az I2C-n keresztüli kommunikáció összetettebb, mint egy UART vagy SPI megoldással. A jelnek meg kell felelnie az I2C szabvány által leírt formátumnak, hogy a buszon lévő eszközök érvényes I2C kommunikációként felismerjék azt. Szerencsére a legtöbb készülék gondoskodik magának a nem megfelelő jelek kiszűrésére, így Önnek csak a kommunikációval kell foglalkoznia.
Alapok
Normál esetben a címben 7 bitet továbbítunk
Az üzenetek két részre oszlanak: a címzésre, ahol a master jelzi, hogy melyik slave eszközzel kíván kommunikálni és egy vagy több 8 bites adatcsomagra, amelyet küldhet a master a slave eszköznek, vagy a slave is a masternek. Az adatokat az SDA vonalra helyezzük, miután az SCL alacsonyra csökken, és akkor kerül feldolgozásra, amikor az SCL vonal magasra emelkedik. Az órajel magas szintre emelkedése és az adatok beolvasásának vége közötti időt az IC gyártója adja meg.
A kommunikáció indítása
A címzés elküldése előtt a master az SCL lábat magasra hagyja, és az SDA-t alacsonyra húzza. Ez minden slave eszközt figyelmeztet arra, hogy az átvitel megkezdődik. Ha két mester eszköz egyidejűleg kívánja elfoglalni a buszt, akkor az az eszköz, amelyik az SDA-t vonalat először húzza le alacsonyra, az lesz jogosult a kommunikációra. Lehetőség van ismételt üzenet küldésére anélkül, hogy a busz feletti rendelkezést a master átadná másik eszköznek, erről később beszélünk.
Címzés
Minden új kommunikációs csomagban először a címzés kerül továbbításra. 7 bites címek esetén először a címet a legfontosabb bittel (MSB) kell lezárni, amelyet egy R/W (Read/Write, Olvasás/Írás) bit követ, amely jelzi, hogy ez olvasási (1) vagy írási (0) művelet.
A cím 9. bitje a NACK/ACK (jóváhagyás, ACKnowledge) bit (ez vonatkozik a címzésre és az adatátvitelre is). Miután a címzés első 8 bitjét elküldtük (7+R/W), a fogadó eszköznek kell az adatvonalat alacsonyra húznia, ezzel jelzi, hogy tudomásul vette, hogy vele akar a master kommunikálni és egyben azt is jelzi, hogy készen áll a kommunikációra.
Adattovábbítás
A címzés elküldése után az adatok következnek. A mester egyszerűen folytatja az órajel impulzusok generálását, és az adatokat az master vagy a slave helyezi az SDA vonalra, attól függően, hogy az R/W bit olvasási vagy írási műveletet jelez-e. Az adatcsomagok száma tetszőleges, és a legtöbb slave eszköz automatikusan növeli a belső regisztert, azaz a későbbi olvasások vagy írások a sorban lévő következő regiszterből származnak.
A kommunikáció befejezése
Az összes adat elküldése után a master állítja le a kommunikációt. A leállítást az SDA vonal 0->1 (alacsonyról magasra) átmenete határozza meg, miután az SCL vonal 0->1 átmenetet mutat, és az SCL magas marad. A normál adatírás közben az SDA-érték nem változhat, ha az SCL magas, hogy elkerüljék a hamis leállási feltételeket.
Speciális protokoll
10 bites címek
A 10 bites címzési rendszerben két részben lehetséges (ezeket frame-eknek hívják)csak a címzés folyamatának a végrehajtása. Az első rész b11110xyz kódból áll, ahol 'x' a slave cím MSB-je (és egyben a címzés 9. bitje), y a slave cím 8. bitje, és z az R/W bit a fent leírtak szerint. Az első rész ACK bitjét minden olyan slave érvényesíti, amelyek megegyeznek a cím első két bitjével. Mint a normál 7 bites átvitelnél , egy másik átvitel azonnal megkezdődik, és ez az átvitel a cím 7: 0 bitjét tartalmazza. Ezen a ponton a címzett slave egységnek válaszolnia kell egy ACK bittel. Ha nem, akkor a hiba mód megegyezik a 7 bites rendszerrel.
Megjegyzés: az '11110' cím nem nem tartozik az engedélyezett címek közé, ezért nem lehetséges, hogy egy 7 bites címmel ellátott eszköz válaszoljon egy 10 bites címzésű eszköz helyett.
Ismételt indítás
Időnként fontos (a több masterrel ellátott áramköröknél), hogy a master egymás után több adatcserét is el tudjon intézni, anélkül, hogy a hálózaton lévő másik master átvenné az irányítást. Ezért meghatározták az ismételt indítási feltételt.
Az ismételt indítás végrehajtásához az SDA-t hagyjuk magasra emelkedni, míg az SCL alacsony, az SCL-t magasra kell emelni, majd az SDA-t ismét alacsonyra kell állítani, miközben az SCL magas. Mivel a buszon nem voltak megállási feltételek, az előző kommunikáció nem valósult meg teljesen, és a jelenlegi mester fenntartja a busz irányítását.
Ezen a ponton megkezdheti a következő üzenet továbbítását. Az új üzenet szintaxisa megegyezik a többi üzenettel - egy címkeret, amelyet adatkeretek követnek. Tetszőleges számú ismételt indítás megengedett, és a mester fenntartja a busz irányítását mindaddig, amíg megállási állapotot nem ad ki.
Órajel nyújtás
Időnként a master adatsebessége meghaladja a slave azon képességét, hogy ezeket az adatokat fel tudja dolgozni. Ennek oka az lehet, hogy az adatok még nem állnak készen (például a slave egység még nem fejezte be az analóg-digitális konvertálást), vagy azért, mert egy korábbi művelet még nem fejeződött be (mondjuk, egy EEPROM, amelynél még nem fejeződött be a nem felejtő memóriába való írás, és ezt be kell fejeznie, mielőtt más kéréseket kiszolgálna).
Ebben az esetben néhány slave eszköz végrehajtja az úgynevezett "órajel nyújtást". Alapvetően az összes órajelet a master adja meg - a slave eszközök egyszerűen csak adatokat helyeznek el a buszon, vagy az adatokat olvassák ki, a master által kiadott órajel alapján. Az adatátviteli folyamat bármely pontján egy címzett slave eszköz alacsonyan tarthatja az SCL vonalat, miután a mester alacsony szintre húzta le. A masternek tartózkodnia kell a további óraimpulzusoktól vagy adatátviteltől mindaddig, amíg a slave eszköz nem engedi ismét magas szintre az SCL vonalat.
További információk
Az I2C egy viszonylag összetett protokoll, és rengeteg ismeretanyag áll rendelkezésre. Az alábbiakban bemutatunk néhányat.
Wikipedia cikk az I2C-ről - Nem nagyszerű, de nem egy szörnyű kezdőhely.
Standards Doc - Phillips Semiconductor néhány évvel ezelőtt NXP lett; ez az I2C hivatalos szabványdokumentuma.
I2C alapozó - Az I2C és a kapcsolódó technológiák hivatalos alapozója.
Linux eszközök az I2C-hez - Szép eszközkészlet az I2C-vel és a kapcsolódó buszokkal való beágyazott Linux környezetben, például a pcDuino vagy a Raspberry Pi kezeléséhez.
Qwiic Connect rendszer
Az eredeti oldal IDE kattintva nyílik meg.