Choď na obsah Choď na menu
 

I2C (2)

http://www.dhservis.cz/iic.htm


     Sběrnice I2C (I2C-bus, Inter-IC-bus) je dvouvodičové datové propojení mezi jedním nebo několika procesory (Masters) a speciálními periferními součástkami (Slaves). Všechny součástky jsou připojeny na téže sběrnici a jsou cíleně vybírány svými adresami. Adresy i data se přenášejí týmiž vodiči. Sběrnice umožňuje velmi jednoduché propojení mezi několika integrovanými obvody a bezproblémové dodatečné rozšiřování. 
 

Protokol sběrnice

     Mohou být připojeny všechny integrované obvody, které zvládají speciální protokol sběrnice. Mimo integrovaných obvodů RAM, EEPROM , obvodů pro rozšíření portů, A/D a D/A převodníků a obvodů hodinových signálů existuje ještě celá řada speciálních integrovaných obvodů, jako například budiče displejů nebo integrovaných obvodů pro televizní a audio techniku. Sběrnice I2C používá sériovou datovou linku SDA a linku hodinového signálu SCL. Data a adresy se přenášejí podobně jako v posuvných registrech společně hodinovými impulsy. Obě linky je možno používat jako obousměrné. Jsou vybaveny zvyšovacím (pull-up) odporem a mohou být každým účastníkem sběrnice staženy na nízkou úroveň výstupem s otevřeným kolektorem nebo drainem. 

     Obrázek ukazuje princip propojení sběrnice. Neaktivní účastníci sběrnice mají vysokou impedanci, neustále však vyhodnocují signály na sběrnici. Je-li použit jen jeden master, vydává hodinový signál jen on. Data však může vysílat jak master, tak slave. 

     Protokol I2C rozeznává řadu přesně definovaných situací, které každému účastníkovi umožňují rozeznat začátek a konec přenosu a také své možné adresování: 
Klidový stav: SDA i SCL jsou na vysoké úrovni (HIGH) a tím neaktivní. 
Podmínka startu: SDA je masterem stažena na nízkou úroveň, zatímco SCL zůstává na úrovni HIGH. 
Podmínka stopu: SDA přejde z LOW na HIGH, SCL zůstává na úrovni HIGH. Přenos dat: Příslušný vysílač přivede na datovou linku SDA osm datových bitů, které jsou hodinovými impulsy na lince SCL vysílanými masterem posouvány dále. Přenos začíná bitem s nejvyšší váhou. 
Potvrzení(acknowledge): Příslušný přijímač potvrzuje příjem bytu nízkou úrovní na SDA, dokud master nevyšle devátý hodinový impuls na SCL. Potvrzení současně znamená, že se má přijímat další byte. Požadované ukončení přenosu se musí ohlásit neexistencí potvrzení. Vlastního ukončení přenosu se dosahuje podmínkou stopu.

 

     Přenos a potvrzování adres se provádí přesně stejně jako přenos dat. V nejjednodušším případě přenosu dat od mastera k podřízenému zařízení (slave), např. výstupnímu portu, probíhají následující děje: master vyrobí podmínku startu a pak v bitech 7 až 1 přenese adresu portu (součástky) a v bitu 0 požadovaný směr přenosu dat, totiž 0 pro "zápis". Podřízené zařízení (slave) adresu potvrdí. Pak master vyšle datový byte, který rovněž bude potvrzen. Master nyní může spojení přerušit zasláním podmínky stopu nebo může témuž zařízení slave posílat další byty.
 

     Mají-li se číst data od zařízení slave, musí se adresa přenést s nahozeným bitem přenosu R/W. Master vždy vydá osm hodinových impulsů a dostane osm datových bitů . Potvrdí-li příjem vysláním devátého hodinového impulsu, může přijímat další byty. Přenos je nakonec masterem ukončen vynecháním potvrzení a podmínkou stopu. Každá součástka I2C má stanovenou svoji adresu, která je zčásti pro daný typ specificky stanovená (SA0...SA3), zčásti proměnná (DA0...DA2). Při třech vyvedených adresních linkách může být na jedné sběrnici I2C až osm součástek téhož typu. Maximální hodinový kmitočet pro sběrnici I2C je pro většinu integrovaných obvodů 100 kHz. 
 


     Pro typický příklad použití sběrnice I2C si vezměme paměť EEPROM typu 24cxx.Pro komunikaci postačí pouze dva vodiče (SCL a SDA), na jednu komunikační linku je možno umístit až 8 pouzder (podle kapacity a výrobce!). Používají zápisovou stránku až 64B, což umožňuje rychlé uložení velkého množství dat. Jsou dostupné od mnoha výrobců (asi nejvíce ATMEL a MICROCHIP), pro dosavadní typy 24C postačí pouze dva typy komunikačních protokolů (ukázkový program), je velmi vhodný poměr cena/kapacita (24C64 – 8kB za cca 40kč s DPH ). 


     Dalším příkladem využití možností sběrnice I2C je expandér (rozšíření) portů.Integrovaný obvod PCF8574 je 8 bitový expandér portu se sběrnicí I2C. Sběrnicová adresa je 0100xxx0 pro zápis a 0100xxx1 pro čtení, přičemž tři proměnné bity xxx je možno stanovit externími adresními vstupy A0 až A2. Integrovaný obvod má osm obousměrných portů, odpovídajících standardnímu 8051. Výstupní linka s vysokou úrovní má interní zvyšovací rezistory a vysokou impedanci. Je možné ji zvějšku stáhnout do úrovně log. L. Po resetu po připojení napájecího napětí jsou všechny linky na úrovni H t.j. jsou nastaveny jako vstupy.
      Chceme-li na výstupu zapojit např. LED bez dalšího budiče, musí se v inverzní logice zapojit proti kladnému napájecímu napětí (totéž platí vlastně i u MCU51). Obvod PCF8574 má k dispozici také výstup přerušení s otevřeným kolektorem, který je možno připojit na odpovídající vstup přerušení mikroprocesoru. Přerušení je vyvoláno změnou úrovně na jedné z osmi linek portu. Příznak přerušení je vynulován, jestliže je port čten, nebo jestliže se port vrací do svého výchozího stavu. Výstupy přerušení několika expandérů je možno spojit dohromady. Tím vznikne vazba NEBO, takže mikroprocesor musí při každém výskytu přerušení určit jeho vektor (odkud přerušení vzniklo).

 

Blokové zapojení obvodu PCF8574
 


Zapojení jednoho bitu brány

 

Rutinu pro obsluhu tohoto expandéru naleznete na stránce rutin
 Datasheet tohoto obvodu si můžete stáhnout z tohoto odkazu.


     Sběrnice I2C má velkou výhodu snadné rozšiřitelnosti. Pomocí několika expandérů portu lze získat řadu nových portů. Při třech pevně zapojitelných adresních bitech PCF8574 je možno vytvořit až osm bytových portů. Ve formě obvodu PCF8574A je k dispozici kompatibilní součástka se změněnou bázovou adresou (70H), takže je možno přidat ještě jednou osm bytových portů. 
 


     Další zajímavou součástkou je digitální audioprocesor řízený I2C a tou je TDA7318. Spojuje v sobě jednoduchost zapojení, relativně jednoduché ovládání, 4 nezávislé vstupy/výstupy, nezávislé ovládání hlasitosti po 1,25 dB, ovládání výšek, hloubek a vyvážení. Blokové schéma obvodu naleznete níže. Více zde k němu psát nebudu, jen bych opisoval datasheet. Bohužel, momentálně nemám žádnou samostatnou rutinu k dispozici, ale pokud máte funkční klasickou sběrnici I2C stačí zasílat data do registrů dle dokumentace a vše by mělo fungovat. Bratr s tímto obvodem stavěl zesilovač a je plně funkční. 
 

Blokové zapojení obvodu TDA7318

 
Šestnáctibitový I/O expandér s ovládáním I2C - obvod Microchip MCP 23016

     Tento obvod sdružuje 2 x 8 bitový obousměrný GPIO port a linky jsou defaultně nastaveny jako vstup. GPIO linky mají vysokou proudovou zatížitelnost (+/- 25 mA; typ OC) - čili můžete s nimy přímo budit např. LED a podobně. MCP23016 je určen pro rozsah napájecího napětí 2,0 až 5,5 V a rozsah pracovních teplot -40 až 85 °C. 
      Obvod podporuje standardní rozsah kmitočtů 0 - 400 kbps. Jako zdroj interního kmitočtu 1 MHz slouží jednoduchý RC člen (3k9, 33pF), který se jednoduše zapojí na vstup CLK. MCP23016 obsahuje výstupní linku přerušení a tři vstupní hardwarové adresovací linky (A0, A1, A2). 

 

Blokové zapojení obvodu MCP23016


 

Pouzdro DIP obvodu MCP23016



     U obvodu se nastavuje režim V/V linek pomocí registru IODIR0 nebo IODIR1(IO direction) pro port 0 nebo port1, zapsáním úrovně log. 1 do příslušného bitu nastavíme bit do vstupního režimu, zapsáním log. 0 jej nastavíme do výstupního režimu. 
     Vlastní výstupní registry jsou GP0, GP1 (general purpose IO port) jejichž hodnoty jsou po zápisu do těchto registrů kopírovány do brány (opět GP0 = PORT0 - čili GP0.0 až GP0.7 a obdobně pro GP1). Při zápisu do těchto V/V registrů se hodnota zapisuje také do výstupních latch registrů (OLATH). 
     Obvod má také výstupní registry (OLATH0 a OLATH1 - output latch register). Tyto registry obsahují aktuální hodnotu, zapsanou do výstupu. Pokud tedy odešleme hodnotu na port (zápis do GP0,GP1) hodnota je zapsána do registru a až pak je nastavena hodnota na výstupní bráně. Pokud čteme hodnotu tohoto registru (OLATH), pak čteme hodnotu naposledy zaslanou na bránu, ne hodnotu, která je skutečně při čtení na bráně !! Skutečnou hodnotu na bráně získáme, čteme-li registr GP0 (GP1). 
     Registry IPOL0, IPOL1 (input polarity) jsou registry pro nastavení polarity vstupních signálů. Pokud je bit v tomto registru nastaven, pak je hodnota odpovídajícího bitu v GP0 (GP1) invertována (tedy hodnota, která je v okamžiku čtení na odpovídajícím bitu), pokud nastaven není, čteme skutečnou hodnotu na odpovídajícím vývodu. 
     Registry INTCAP0, INTCAP1 (interrupt capture) jsou registry, které obsahují po přerušení poslední načtenou hodnotu na portu 
     Registry IOCON0, IOCON1 (IO expander control). Každý z těchto registrů obsahuje pouze jeden nastavitelný bit - IARES (Interrupt Activity Resolution). Tímto bitem nastavujeme samlovací rychlost expandéru, t.zn. rychlost, s jakou se u vstupního režimu testují změny na portu pro vyvolání přerušení při změně hodnoty. Pokud je tento bit nastaven (log. 1) pak je rychlost samplování 200 usec. a obvod odebírá vyšší proud. Pokud je (imlicitně) bit nulován, je rychlost samplování 32 msec. a odběr obvodu je nižší. 

      Obvod dále umožňuje využít výstup přerušení, který je společný pro oba porty. Tento výstup je výstup s otevřeným kolektorem. Po změně na portu je výstup INT stažen do nízké úrovně. Pak je nutno čtením obvodu zjistit vektor přerušení (tedy odkud přerušení vzešlo). Pro více informací doporučuji číst datasheet
     Protože jsem tento obvod potřeboval použít, a na stránkách Microchipu je příklad (a software) pouze v jazyku C, uveřejňuji k tomuto obvodu svoji malou knihovnu rutin.

Obvod jsem testoval podle následujícího zapojení:


Náhled na schéma - ke zvětšení obrázku klikněte na náhled



      Expandér je ovládán procesorem PIC16F877A, který má kompletní hardwarovou obsluhu sběrnice I2C, čímž se obsluha expandéru podstatně zjednodušuje. Adresa obvodu (expandéru) je pro příklad nastavena na 000. První příklad, který je v knihovně povolen (čili, pokud přeložíte *.asm tak, jak je) je blikání LED připojenou na portu GP0 nebo GP1 libovolneho bitu. Další rutiny si povolíte na počátku v sekci:

;**************************************************************************
MAIN
;povolte si rutinu dle pozadavku
goto	blikani		;test zapisu do MCP23016
;goto	read_pin
;goto	read_int	;test cteni pod prerusenim
	goto	$
;**************************************************************************

prostým smazáním středníku u požadovaného testu. Nezapomeňte, že je to soubor rutin, takže vždy může být povolena jen jedna. V archivu ke stažení v závěru stránky je komentovaná knihovna rutin pro zápis do expandéru, pro čtení dat z expandéru a pro čtení dat z expandéru pod přerušením. Přerušení není typicky připojeno na přerušení mikroprocesoru, ale na jeden bit portu, který se opakovaně testuje. Je to pouze pro snazší průhlednost rutiny, implementaci do přerušení jistě zvládne každý sám. Odkaz na tuto rutinu naleznete také na stránce rutin pro procesory x51 a PIC 

     Co dodat ke komunikaci s expandérem ? Po resetu vždy musí následovat pauza 72 msec. a po odeslání příkazu (resp. přijmutí potvrzení acknowledge) musí následovat pauza minimálně 12 mikrosekund. V těchto knihovnách (aby Vás to nemátlo) jsou ale časy podstatně delší, z toho důvodu, protože jsem využil časovací rutiny, které jsem již měl ve zbytku software a netlačila mne tolik rychlost komunikace. Proto je na počátku místo 72 milisekund čas 100 msec. a místo 12 mikrosekund je čas 40 mikrosekund.


POZOR - Ještě snad zaslouží drobný popis zapsání vždy druhého byte. Protože obvod má registry dvoubytové, pak stačí,pokud odešleme adresu prvního byte, zapíšeme do něj data. Pak stačí znovu odeslat data a ta budou zapsána do druhého registru v registrovém páru. 
Příklad:
Chci zapisovat do výstupu GP0 a pak GP1. Zapíšu adresu registru GP0, odešlu data. A dále nemusím nastavovat adresu na GP1, ale rovnou odešlu znovu data a ta jsou umístěna do GP1. Pokud budete nejprve zapisovat do GP1, pak další zápis bez adresy zapisuje do GP0. Toto platí pro všechny registry.

 

 

Ke stažení jsou tyto soubory:

Velikost 89 kByte   Archiv s obslužnými knihovnami ve formátu *.asm a schéma ve větší velikosti

 

Na stránce dokumentace v mojí knihovně součástek do EAGLE naleznete tuto součástku kompletně vytvořenou pro Vaše použití.