Fórum témák
» Több friss téma |
Cikkek » HMC6352 iránytűmodul - I2C (TWI) használata AVR-rel HMC6352 iránytűmodul - I2C (TWI) használata AVR-rel
Szerző: Fizikus, idő: Nov 27, 2010, Olvasva: 23916, Oldal olvasási idő: kb. 9 perc
Az I2C busz fizikai kialakításaAz I2C egy soros, 8 bit-es, kétirányú kommunikációs protokoll, amelynek sebessége normál üzemmódban 100kbit/s, gyors üzemmódban 400kbit/s. I2C busz csak két db kétirányú vezetékből áll (SDA és SCL), amelyre az összes eszköz is csatlakozik. Az egyik vezeték az (SDA – Serial DAta), amin a soros adatforgalom zajlik; a másik pedig az órajel vonal (SCL – Serial CLock), amit az I2C buszon történő mindkét irányú adatátvitel szinkronizására használunk. Az SDA és az SCL vonalak az I2C buszon lévő minden eszközhöz hozzá vannak kötve (plusz természetesen a tápvezeték és a föld is). Az I2C eszközök buszra csatlakozó kimeneti fokozatai nyitott kollektorosak vagy nyitott drain-űek. Ez azt jelenti, hogy az adatvonalat le tudják húzni föld potenciálra, de a pozitív tápfeszültségre már nem tudják felhúzni. Azért hogy a vonal állapota magas lehessen az SDA és SCL vezetékeket egy felhúzó ellenálláson keresztül pozitív tápfeszültségre kell kötni. Az egész I2C buszra csak egy-egy felhúzó ellenállás kell vezetékenként amint az a lenti ábrán is látható. A használt ellenállás értéke nem kritikus. 1k8, 4k7 és 10k a leggyakrabban előforduló értékek. Nekem épp 4k7 ellenállások voltak kéznél ezért ezt használtam. Ha a felhúzó ellenállások hiányoznak, akkor az SDA és az SCL vonalak mindig alacsony állapotban lesznek és az I2C busz nem fog működni. Master-ek és Slave-ekAz I2C protokoll un. Master és Slave módszert használ. A Master legtöbbször egy mikrovezérlő, a Slave pedig a fentiekben felsorolt bármilyen I2C-t használó IC, sőt akár egy másik mikrovezérlő is lehet. Az az eszköz, amelyik a kommunikációt kezdeményezi a Master. Az az eszköz, amelyik felé az információt küldi/amelyikkel "beszélget" az a Slave. Mindig a Master az az eszköz amelyik kezdeményezi az adatátvitelt, adja az órajelet és befejezi az adatátvitelt. A Master időzíti az adatokat, melyeket az adatvonalon küld illetve fogad. Az órajelet, amely a kommunikáció sebességét szabályozza, mindig a Master generálja az SCL vonal vezérlésével Egy Slave eszköz nem kezdeményezhet adatátvitelt, csak a Master. Azoknak a Slave eszközöknek, melyeket a Master nem szólított meg, a kommunikáció alatt csöndben kell maradniuk. Amikor a Slave eszköz válaszolni kíván a Master megszólítására, akkor ezt az SDA vonalon át jelzi. Mind a Master, mind a Slave eszközök küldhetnek adatokat az I2C buszon keresztül, de az adatátvitelt mindig a Master irányítja. Több különböző Slave eszköz is lehet ugyanazon az I2C buszon, de általában csak egy Master (lehetséges több Master eszköz használata is, de ezt a cikkben nem tárgyalom). Az I2C fizikai protokollAmikor a Maser (a mikrovezérlő) kommunikálni akar egy Slave eszközzel, akkor először egy Start jelet küld az I2C buszon. A Start és a Stop jel 2 különleges jel, mert csak ezek azok a helyek ahol az SDA (adat) vonal megváltoztathatja az értékét, amíg az SCL (órajel) vonal magasan van. A Start és a Stop jelalakok jelzik a Slave eszközzel történő adatcsere kezdetét és végét. Adatküldés alatt az adatnak az SDA vezetéken stabilnak kell lennie az órajel magas periódusa alatt (amíg az SCL vonal magas állapotban van). A magas-alacsony állapot csak akkor változhat meg az adatvezetéken, amikor az SCL vezetéken az órajel értéke logikai 0. Az adatok átvitele 8 bites adagokban történik. Az adatbitek egymás után kerülnek továbbításra az adatvonalon (SDA), a legnagyobb helyi értékű bittel kezdve a sort, az SCL vonalon érkező órajellel léptetve. Minden fogadott 8 bit után az adatot fogadó eszköz küld egy „vettem” jelzőbitet (acknowledge bit ACK). Ezért valójában 9 órajelciklus kell egy adatbájt elküldéséhez. Ha a fogadó eszköz alacsony ACK bitet küld vissza, akkor azt jelzi hogy megkapta az adatot és kész a következő adatbájt fogadására. Ha magas ACK bitet küld vissza, akkor azt jelzi hogy nem fogad több adatot és a Master lezárhatja az adatforgalmat egy Stop jellel. I2C eszköz címzésAzért hogy az I2C buszon lévő eszközöket meg lehessen különböztetni egymástól, minden eszköz egy egyedi, 7 bitből álló azonosítóval (I2C címmel) rendelkezik. Ezért egyszerre akár 128 eszköz is rákapcsolható egyetlen I2C buszra (feltéve hogy mindegyik eszköz címe különböző). Címzéskor a Master mindig 8 bitet küld ki, nemcsak a 7 bites I2C címet. Az utolsó nyolcadik bit az adatirányt jelző bit (R/W), ami azt jelzi a Slave-nek, hogy a Master írni (0), vagy olvasni (1) akar az eszközről. A 7 bites cím a bájt felső 7 bitjén helyezkedik el, az adatirányt jelző Olvasás/Írás bit (Read/Write) pedig a legkisebb helyi értékű bit. Az hogy a 7 bites cím egy bájt felső részén helyezkedik el, sok félreértésre adhat okot. A gyártók van hogy a R/W bit nélküli 7 bitet adják meg az eszközök címének az adatlapon, és van hogy az R/W bittel együtt adják meg. Az előbbi esetben, ha a 7 bites címet adják meg, akkor pl. ha az eszköz címe 21, akkor ezt 1 helyi értékkel el kell tolnunk balra, és az eszköz írásához 42-t kel elküldeni az I2C buszon, nem 21-et. Az előbbiekhez hasonlóan, az eszközről történő olvasáshoz pedig 43-at kell elküldeni. Ha a gyártó az adatlapban az eszköz címét a R/W bittel együtt adja meg, akkor az is előfordulhat, hogy két külön címet ad meg. Egy páros címet az eszközre történő íráshoz, és egy páratlan címet az olvasáshoz. Például az ebben a cikkben használt iránytűmodul címe írás esetén 42, olvasás esetén 43. A legtöbb I2C eszköznél a 7 bites cím egy a gyártó által fixen megadott 4 bites eszköz azonosító részből és egy szabadon állítható 3 bites fizikai eszközcímből áll össze. Például az alábbi ábrán látható Microchip 24AA128 soros EEPROM esetén az eszközazonosító cím első 4 bit-je a gyártó által fixen beégetett “1010" , az utolsó 3 bit értéke azonban szabadon állítható a soros EEPROM megfelelő címlábainak (A0, A1 és A2) logikai alacsony vagy magas szintre történő kapcsolásával. Látható, hogy a címlábak megfelelő bekötésével akár 8 db Microchip 24AA128 soros EEPROM-ot is ráköthetünk ugyanarra az I2C buszra, ezáltal összesen akár 8 x 16 Kbyte-nyi EEPROM memóriát tudunk használni. Ha ennél is több memóriára lenne szükségünk, akkor egy másik típust felhasználva (amelyiknek nem "1010” az első fix 4 bit-je) újabb 8 db memóriát köthetünk az I2C buszra és igy tovább… Ugyan ez az elv használható más I2C-t használó eszközök esetén is, mint például a Microchip MCP23008 8-bites általános kétirányú (be/kimenet – input/output) portbővítő (I/O Expander). Amelynek használatával a mikrokontroller 2 I/O lábának felhasználásával akár 64 db I/O porthoz juthatunk. Ez ideális megoldás lehet LED-ek, relék meghajtására. A megszakításjelző lábbal rendelkező I/O portbővítő pedig kapcsolók, nyomógombok állapotának beolvasására. I2C szoftver protokollAdat írása a Slave eszközreAdat írása esetén az I2C kommunikáció azzal kezdődik, hogy a Master kontroller (TRON Rulez…) elküld egy Start jelet. Ez figyelmezteti az I2C buszon lévő összes Slave eszközt, hogy figyeljenek, mert adatátvitel következik. A Master ezután elküldi annak az I2C eszköznek a címét amelyikkel kommunikálni akar. A Slave céleszköz I2C címe 7-bites, ami a 4-bites I2C eszköz azonosítóból, a 3-bites fizikai címből, és végül az adatirányt jelző utolsó 1-bitből áll. Adat olvasása esetén az adatirányt jelző bit értéke logikai “1", adat írása esetén pedig logikai "0". Az az I2C Slave eszköz amelyik saját 7 bites I2C címe megegyezik a Master által küldött címmel, válaszol egy "vettem" (ACK - acknowledge) jel elküldésével, majd folytatja az adatátvitelt. A többi Slave eszköz, amelyek nem lettek megszólítva, figyelmen kívül hagyja a cím után bekövetkező kommunikációt és egy újabb Start jelre vár. Miután a Master kijelölte a cím elküldésével azt a Slave eszközt amivel kommunikálni akar, és megkapta az I2C Slave eszköz "címet vettem" (ACK) jelét, akkor elküldi azt a Slave eszközre jellemző belső memóriacímet/regisztercímet amelyikbe adatot akar írni. Ez a belső cím természetesen attól függ, hogy a különböző Slave eszközöknek milyen a belső szerkezete, és hány belső regiszterrel rendelkeznek. Néhány egyszerű eszköznek egyetlen egy belső regisztere sincs, de például egy EEPROM-nak vagy egy RAM nak akár több száz vagy t0bb ezer is lehet. A Slave a cím vétele után is visszajelez egy "vettem" (ACK) jellel. Miután a Master elküldte az I2C címet és a belső regiszter címet, folytatja a kommunikációt az adat küldésével, ami az adott regiszterbe kerül. Több adatbájt írása esetén a Masternek nem kell minden egyes adatbájt után elküldeni a következő regisztercímet, mert a Slave eszköz minden fogadott adat után automatikusan megnöveli eggyel a belső regisztercímet, így az adatbájtok sorban egymás után lesznek eltárolva. A Slave eszköz minden egyes adatbájt után az adatok vételét nyugtázza egy ACK jellel. Miután a Master végzett az adatok Slave eszközre történő írásával, egy Stop jel elküldésével fejezi be az adatátvitelt. Ezzel le is zárja a kommunikációt és szabaddá teszi az I2C buszt. A Slave eszközre történő írási művelet a következőképpen foglalható össze:
A fentiek első olvasásra kicsit zavarosnak tűnhetnek, de nézzünk egy példát (Maradjunk a 24AA128-as EEPROM-nál és nézzük meg hogyan is zajlik az adat írása az EEPROM egy adott regiszterébe.): Az EEPROM az adatokat bájtonként tárolja. Egy IC 16Kbyte-nyi adatot képes tárolni, ez 16384 bájtot jelent. Ebből kifolyólag a memóriacímek megcímzéséhez egy bájt nem lesz elég. A fent vázolt eljárás annyiban módosul, hogy a Slave eszköz belső regisztercímének megadásához két bájtot kell használni. Az EEPROM adatlapjából vett alábbi ábra az írási folyamatot mutatja. A fenti ábra a Master és a Slave közötti adatáramlást és annak irányát nem mutatja, ezért megpróbálom érthetőbben is szemléltetni az írási folyamatot. (Az alábbi ábrán látható példában az EEPROM 3-as számú memória regiszterébe 169-et írunk.)
Adat olvasása a Slave eszközrőlAdat beolvasása egy Slave eszközről kicsit bonyolultabb, mert két fázist igényel. Az elsőben meg kell adnunk az I2C Slave eszköznek, hogy melyik belső regiszteréből akarunk adatot kiolvasni. Ez egy I2C írási művelet igényel Ezért a Slave eszközről történő adatbeolvasás lényegében egy írással kezdődik. Ez az előzőekben felvázolt folyamattal azonos. A Master elküldi a Start jelet, a Slave eszköz I2C azonosítóját az alacsony R/W bittel lezárva (páros eszközcím) és a belső regisztercímet. A második fázis maga az adatolvasási folyamat. Az I2C Master ekkor újra elküld egy Start jelet (Restart), majd ismét elküldi a 7 bites I2C címet, az olvasást jelző magas R/W bittel lezárva (páratlan eszközcím), majd várakozik a Slave eszköz vételt visszaigazoló (ACK) jelére. Amint a Slave eszköz visszaigazolta a vételt, a Master adatfogadási módba kapcsol. A Slave eszköz átveszi az SDA adatvonal feletti irányítást és elküldi az adatokat a kért regiszterből a Masternek. Ezután a Master beolvassa a kívánt mennyiségű adatbájtot. A Master minden bájt vételét nyugtázza egy ACK vagy NACK jellel. Az ACK-val azt jelzi, hogy az adatbeolvasás még nem ért véget és kíván még a céleszközről adatot olvasni. Amint a Master megkapta a kért adatokat, egy no acknowledge (NACK) jelet küld vissza, ezzel jelzi a slave eszköznek, hogy nem vár több adatot, az olvasási folyamat befejeződött. Végül a Master a kommunikációt egy STOP jel küldésével zárja le és teszi szabaddá az I2C buszt. A Slave eszközről történő olvasási művelet a következőképpen foglalható össze:
Az EEPROM adatlapjából vett alábbi ábra az olvasási folyamatot mutatja. A korábbi ábrához hasonlóan, következzen az olvasási műveletekhez tartozó, adatáramlást és annak irányát mutató ábra. (A példában az EEPROM 3-as számú memória regiszteréből olvassuk ki a benne tárolt értéket (169).) Ezzel majdnem be is fejeztük az I2C kommunikáció alapszintű elméleti áttekintését, de van itt még egy kis probléma! Amikor a Master olvas a Slave-ről, akkor a Slave adja az adatot az SDA vonalra, de a Master adja az órajelet (kezeli a SCK vonalat). Mi történik akkor, ha a Slave még nem kész arra, hogy küldje a következő adatot (pl. még nem fejezte be az előző feladatát). Ez olyan eszköznél mint az EEPROM nem egy nagy probléma, mert esetleg újra meg kell ismételni az olvasási műveletet. De ha a Slave történetesen egy mikrovezérlő, aminek rengeteg más műveletet is el kell végeznie, akkor ez komoly probléma is lehet. A Slave mikrovezérlőnek egy megszakításrutint kell végrehajtania, el kell mentenie a regisztereket amivel éppen dolgozott, meg kell állapítania hogy a Master melyik címről akar olvasni és a kért adatot az I2C adatküldő regiszterbe kell tennie. Ennek a végrehajtása akár néhány us-ig is eltarthat, mialatt a Master rendületlenül küldi az SCL vonalon az órajelimpulzusokat, amit a Slave nem tud elég gyorsan követni. Az I2C szabvány ezt a problémát hardveresen oldja meg, ugyanis a Slave eszköz alacsony állapotban tarthatja az SCL vonalat, és miután végzett a feladataival és kész a következő adat küldésére, akkor az SCL vonal vezérlését átengedi a Masternek. Ezt az eljárást órajelnyújtásnak nevezik. Amikor a Slave eszköz a Master-től egy olvasási parancsot kap, akkor az órajel vonalat alacsonyan tartja, majd ha már kész az adatküldésre, elengedi az órajelvonalat, ezáltal lehetővé téve hogy a felhúzó ellenállások magas szintre húzzak fel. A Master eszköz elküldi az olvasási utasítás első órajelét az SCL vonal magas szintre emelésével, és utána ellenőrzi hogy az SCL vonal valóban magas szintre került-e. Ha még alacsony szinten van, akkor az azt jelzi, hogy azt a Slave eszköz tartja alacsonyan, mert még dolgozik, és a Master eszköznek várnia kell addig amíg a Slave be nem fejezi a feladatát és az SCL vonal újra magas szintre nem kerül. Szerencsére ezt a feladatot (az SCL vonal figyelését) a mikrovezérlőn lévő hardveres I2C port automatikusan végrehajtja, nekünk külön ezzel nem kell foglalkozni. Most már minden lényeges dolgot említettünk, ami az I2C kommunikációhoz kell. Nézzük meg hogyan valósította ezt meg az Atmel a gyakorlatban az AVR-ekre integrált hardveres TWI periféria esetében. A cikk még nem ért véget, lapozz! Értékeléshez bejelentkezés szükséges! |
Bejelentkezés
Hirdetés |