Jste zde

Vše co jste kdy chtěli vědět o I<sup>2</sup>C EEPROM a báli se zeptat..

Konečně článek opravdu z praxe, který si musíte přečíst. To platí i když I2C považujete

za vyčerpané téma, určitě se něco dozvíte.. Navíc je doplněn příkladem programu - zde..

24C01/02/04/08/16/32/64/128/256/512

Při návrhu zapojení se vyskytují případy, kdy je nutno uchovat po vypnutí napájení poměrně velké množství dat. V případě malého procesoru, jako jsou AT89C1051, AT89C2051, AT90S1200 nebo dokonce AT90S2343, je nutno použít sériové paměti. Sériové paměti typu 93C jsou dostupné pouze v malé kapacitě. Při požadavku na vyšší kapacitu přicházejí v úvahu sériové paměti typu 24C (128B až 64kB), využívající komunikace pouze pomocí dvou vodičů. Jedinou výhodou těchto pamětí není pouze ušetření vývodů procesoru, ale hlavně možnost na jeden komunikační kanál (hodiny a obousměrná data) osadit až osm těchto pamětí. Začátečníka asi velmi často odradí na první pohled složitý komunikační protokol, obousměrná datová linka a nutnost generovat a kontrolovat bit zvaný ACK. Toto je složité skutečně pouze na první pohled. Stručně řečeno, výhody typu 24C oproti 93C jsou asi následující.:

  • 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!).
  • Mnohonásobně větší kapacita oproti typu 93C.
  • 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).
  • Velmi vhodný poměr cena/kapacita (24C64 – 8kB za cca 40kč s DPH ).

Pro tyto a mnoho dalších výhod se vyplatí používat sériové paměti typu 24C. Pro ty, kteří se zalekli (pouze na první pohled) složitého komunikačního protokolu, uvádím celkem jednoduchý a názorný příklad komunikace vytažený z programátoru všech typů sériových pamětí typu 24C. Příklad je určen jak pro jednobytový tak i pro stránkový zápis a čtení. Něž stručně popíši ukázkový program, chtěl bych zdůraznit některé podstatné rozdíly těchto pamětí od různých výrobců. Než použijete sériovou paměť (hlavně pro začátečníky) typu 24C, je třeba zjistit následující vlastnosti (srovnány zhruba podle důležitosti):
 

  • Jak velká je zápisová stránka pro zvolenou kapacitu paměti. Pohybuje se od 2B do 64B. Tento parametr udává kolik bytů je možno zapsat do paměti najednou a poté teprve odstartovat zápis (zápis je odstartován vygenerováním STOP značky). Tento parametr velmi urychluje zápis. Zápis (vlastní uložení) stránky trvá stejný čas, jako uložení jednoho bytu. Pokud zapíšete do paměti najednou více bytů, než je kapacita stránky, dojde k přepisování stránky opět od začátku a tím zničení dat na začátku stránky. (Při čtení paměti nemá velikost stránky žádný vliv.)
  • Zda jsou použity nebo nepoužity výběrové vstupy A0, A1 a A2 pouzdra paměti. Pouzdro paměti obsahuje tři výběrové vstupy označené A0, A1 a A2. Při komunikaci s pamětí je nutno v adrese udat stav těchto vstupů (pokud jsou interně zapojeny). Pokud paměť rozpozná v přišlé adrese své nastavení, potvrdí adresaci bitem zvaným ACK (jinak ne). Pokud chcete použít na jednom kanále více pamětí typu 24C, velmi dobře prostudujte, zda zvolený výrobce tyto vstupy skutečně používá. Například 24C04 od ATMELu tyto vstupy používá, ale od MICROCHIPu ne! Možná novější verze již ano, nevím. Tato chyba se těžko hledá, když studujete popis paměti, která je jiná, než jste skutečně použili.
  • Dobré je i zjistit potřebný čas pro zápis (pro byte a stránku jsou většinou stejné). U novějších pamětí 24C se již udává mnohem menší zápisový čas (někde pouhé 2ms), ale toto se také liší podle výrobce. Při použití pamětí od různých (na jednom kanále, nebo při několika kusové výrobě) je nutno na toto brát ohled.
  • Pozor na skutečnost, že různí výrobci tyto paměti až znatelně vylepšují (24C65 je z hlediska základu totožná s 24C64, ale obsahuje například možnost zablokování/heslování interních dat).

Podle zde uvedených doporučení, by se opět mohl zdát použití pamětí typu 24C složité. Je třeba si prohlédnout potřebnou dokumentaci a porozumět jejich činnosti. Jako vhodnou dokumentaci bych doporučil od ATMELu na WWW.ATMEL.COM. Já osobně jsem použil paměť typu 93C poprvé před asi třemi lety a také naposled pro její malou kapacitu a „složité“ ovládání (čtyři nebo tři vodiče a mnoho povelů).

 


Popis přiloženého programu :
Nebudu zde popisovat princip komunikace po SCL a SDA mezi procesorem a pamětí, toto lze najít třeba na uvedené adrese. Stručně popíši ukázkový program, který najdete přiložen k tomuto příspěvku. Obecný program lze jistě zmenšit, pokud bude požadováno připojení pouze jedné paměti a pouze bytový nebo stránkový zápis. Zde je však uvedena přehledná varianta pro začátečníky v  oboru zvaném 24C.

 Nejprve jsou uvedeny použité bitové a bytové adresy a konstanty:
 

  • AT24C32 (AT je uvedeno pouze z důvodu, že název nemůže začínat číslem a neznamená žádná omezení na paměti od AMELu). Tímto bitem se rozlišuje, zda se komunikuje s pamětí 24C01/02/04/08/16 (AT24C32=0), nebo s 24C/32/64/128/256/512 (AT24C32=1). Pro tyto dvě skupiny pamětí se poněkud liší zasílaný paket (pouze do paměti).
  • I2C_ERROR Udává, zda komunikace proběhla v pořádku (I2C_ERROR=0), nebo nastala nějaká chyba (I2C_ERROR=1). Tento příznak je nutno po každé komunikaci otestovat a nulovat.
  • I2C_END Tento bit se používá pouze při čtení/zápisu několika bytů najednou. Hodnota I2C_END=1 udává, že se bude číst poslední byte z paměti a je tedy nutno generovat neplatný ACK (pouze při čtení z paměti) následovaný STOP značkou. Pokud je I2C_END=0 znamená to, že se při čtení generuje platný ACK (bude následovat ještě další požadavek na čtení) a nevytváří se STOP značka. STOP značka se vytváří pouze při ukončení (třeba i několika bytového) čtení (po té co byl generován neplatný ACK) a při ukončení zápisu (jak bytu, tak i stránky) pro zahájení (samo)zápisu. Při použití čtení/zápis pouze jednoho bytu není nutno I2C_END nastavovat.
  • I2C_ACK Používán pouze při přímém přístupu ke komunikaci. Z vyšší sféry netřeba uvažovat. (Požadovaný přímý stav generovaného ACK při vysílání, nebo přímý stav přijatého ACK. Nerad bych toto zamlžil, ale je třeba říci, že platný ACK je ve skutečnosti log.0).
  • I2C_SELECT Zde v bitech 2,1,0 musí být uveden stav výběrových vstupů pouzdra obvodu označených A2, A1, A0. Pro první pokusy doporučuji naplnit tuto adresu hodnotou 00h a výběrové vstupy zapojit na log.0. (Ne všechny paměti používají všechny výběrové vstupy. Toto záleží na kapacitě a výrobci.)
  • ADR_LOW a ADR_HIGH Do těchto bytů je třeba uložit adresu, ze které se bude v paměti 24C číst, nebo na kterou se bude do paměti 24C zapisovat. Pozor na maximální dovolenou adresu (pro paměti 24C32/64/128/256/512 budou po překročení adresy přepisovány počátečný adresy, ale pro 24C01/02/04/08/16 může dojít k vytvoření chybného paketu). Je dobré si prohlédnout formát paketu a způsob vytváření ve zde popisovaném příkladu a vše bude jasné.
  • I2C_POCET Zde je třeba nastavit počet čtených/zapisovaných bytů při vícebytovém přístupu (minimálně dva).
  • I2C_TEMP Pro dočasné uložení vysílané hodnoty.
  • I2C_SPEED Konstanta pro vytvoření zpoždění při vytváření komunikační frekvence. Nastavujeme podle odhadu z údajů výrobce a rychlosti procesoru.
  • SCL Výstup hodin komunikačního kanálu (zde pouze výstup).
  • SDA Vstupně/výstupní data komunikačního kanálu.

Ukázkový program je vytvořen pro možnost okamžitého použití (po nastavení uvedených hodnot). Nejprve je proveden zápis do 24C32 (nebo vyšší), poté je vykonáno čtení. Přečtená hodnota je uložena na adresu 05h a stav I2C_ERROR předán na P1.7 (možno změřit). Pokud po připojení paměti například 24C64 spustíme program a na portu P1.7 je log.0, je vše v pořádku a můžeme začít s vylepšováním pro své použití.


Zápis jednoho bytu z vyšší úrovně je velmi jednoduchý a nepotřebuje vysvětlení. Totéž platí pro čtení jednoho bytu.

Zápis několika hodnot :
V tomto ukázkovém příkladě pouze do velikosti jedné stránky. Nejprve je nastaven počet zapisovaných bytu, poté adresa v paměti 24C a nakonec adresa v interní paměti procesoru, odkud se budou byty pro zápis do 24C vyzvedávat. Nejprve se do paměti zapíše kontrolní byte, adresa od které se bude číst a rovnou i jedna hodnota (viz. dokumentace k 24C). Toto se ale nesmí ukončit STOP značkou, protože by začal interní zápis v paměti. Je tedy nutno nastavit I2C_END=0. Nyní se do.paměti postupně zapisují další byty (maximálně v délce stránky). Teprve po zápisu posledního je nastaveno I2C_END=1 pro vygenerování STOP značky a paměť 24C v tento okamžik zahájí zápis (ukládání) celé přijaté stránky. (Při zápisu do paměti všechny bity ACK generuje paměť a úkolem komunikačního programu je kontrolovat, zda paměť skutečně zápis všech hodnot potvrzuje platným ACK. Toto se děje na nižší úrovni a výše se oznamuje pomocí I2C_ERROR.)

Čtení hodnot :

  • Počet čtených bytů vůbec nezáleží na velikosti „zápisové“ stránky, a proto je možno paměť vyčíst od adresy 0000h najednou (stále číst a teprve nakonec vygenerovat STOP značku). Mezi čtenými byty může být libovolná časová pauza.
  • ACK bit generuje příjemce. Při čtení tedy ACK generuje procesor. Tímto paměti po každém přečteném bytu oznamuje, zda byl poslední (neplatné ACK) nebo bude požadovat ještě další (platné ACK). Pozor na skutečnost, že není možno čtení vždy ukončit pouze vygenerováním STOP značky, která (podle dokumentace) ukončuje komunikaci. (Pro vygenerování STOP značky je nutno zvednout SDA na log.1 (při SCL v log.1), což nemusí být vždy možné. Pokud procesor paměti potvrdí přijatá data pomocí platného ACK, tak při spádové hraně SCL již paměť vysouvá další data. První bit nového bytu může mít hodnotu log.0, kterým paměť přidrží SDA v log.0 do příští spádové hrany SCL, aby jej procesor mohl přečíst a není možno vygenerovat STOP značku. Paměť tedy zablokuje SDA, tím že již poskytuje další data. Toto je častá chyba.)


Nerad bych zde popisoval celou komunikaci, která je dostupná v dokumentaci. Ukázkový program je dosti okomentovaný a proto na závěr uvedu pouze stručné vysvětlení částí nižší (ne nejnižší) úrovně komunikace. 

Pro zápis do paměti je třeba dodržet následující posloupnost:

  1. - Vygenerovat START značku.
  2. - Zapsat kontrolní slovo, které obsahuje nastavení výběrových vstupů pouzdra, příznak pro zápis a u pamětí 24C01/02/04/06/16 i vyšší bity adresy.
  3. - Zbylou část adresy pro 24C01/02/04/08/16, ale teprve celou adresu pro 24C32/64/128/256/512.
  4. - Postupně zapsat požadovaný počet bytů (maximálně velikost stránky).
  5. - Vygenerovat STOP značku. (Nyní začíná interní zápis v paměti.)


Pro čtení platí následující posloupnost:

  1. - Vygenerovat START značku.
  2. - Zapsat kontrolní slovo, které obsahuje nastavení výběrových vstupů pouzdra, příznak pro zápis (bude se zapisovat adresa, od které se bude číst) a u 24C/01/02/04/08/16 i vyšší bity adresy.
  3. - Zbylou část adresy pro 24C01/02/04/08/16, ale teprve celou adresu pro 24C32/64/128/256/512.
  4. - Vygenerovat STOP, čímž dojde k zápisu do interního čítače adres (ne na adresu).
  5. - Vygenerovat START značku (*).
  6. - Zapsat kontrolní slovo, které obsahuje nastavení výběrových vstupů pouzdra, příznak pro čtení (již se budou číst hodnoty).
  7. - Postupné čtení hodnot a potvrzování ACK.
  8. - Po poslední požadované hodnotě ACK nepotvrdit.
  9. - Vygenerovat STOP značku.


(*) S každým přečteným bytem se interní čítač adres zvětšuje o jedničku. Pokud postupné čtení skončíme na  určité adrese a poté požadujeme pokračovat dále, stačí začít čtení od tohoto okamžiku (poslední adresa je zachována).

Nyní pracuji s obvody ATMEL AVR. Jakmile vytvořím takovouto obecnou komunikaci na bázi AVR, tak ji zde najdete také. 

A na závěr jednu možná radu. Používejte součástky, které dodává více výrobců a prodejen. Ušetříte si tím za nějaký čas trápení při hledání náhrady, když jeden výrobce jejich produkci ukončí. Rovněž používejte součástky, které lze v budoucnu velmi snadno nahradit lepšími. Toto například platí o řadě 24C, kde jsou shodná pouzdra, zatím pouze dva jen mírně se lišící pakety, ale hlavně kapacita se zvyšuje podle potřeby. Pro zařízení na zakázku používám pouze řadu 24C. Zákazník může přijít za nějaký čas s prosbou o uchovávání mnohem většího množství dat. Nedávno jsem měnil pouze 24C32 za 24C256 a prodlužoval čas měření v odlehlém procesoru, který na požádání vyšle data po RS485. Tato úprava by byla při použití 93C téměř neproveditelná. Většinu zákazníků nezajímá jak pracná byla úprava, ale hlavně že je. Vývojář si ušetří mnoho práce, když myslí dopředu a navíc k němu zákazník získá důvěru.


Pokud máte hotové podobnoé SW rutiny, které chcete publikovat, pošlete nám je pokošíme se zde vytvořit knihovnu podobných utilit. - INFORMACE PRO AUTORY


Výpis rutiny a její download

Hodnocení článku: