Ako používať externú EEPROM

Zápisník experimentátora

Hierarchy: Externá EEPROM

V tomto článku si vysvetlíme, ako môžeme pracovať s externou EEPROM. Externé EEPROM sa obvykle ovládajú protokolom I2C a v tomto článku sa budeme venovať práve takýmto EEPROM. Príklad bude pre 24LC16B, ale až na drobnosti bude tento návod univerzálny pre ľubovolnú EEPROM.

Použité súčiastky

Na tento experiment stačí iba pár súčiastok:

  • Arduino Pro Mini (link) - Použil som ho preto, lebo sa zmestí aj na najmenšie skúšobné pole.
  • Breadboard 400 Holes (link) - Na ňom máme dosť miesta na dva mikrospínače.
  • Prevodník CP2102 USB to Serial (link) - Prevodník slúži na naprogramovanie Arduina.
  • Mikrospínače (link, link) - Potrebujeme dva kusy. Do skúšobného pola sa dajú použiť aj štvorpinové aj dvojpinové. Niekedy sú piny dlhé, alebo majú podivné výstupky. Nebojte sa tie konce odstrihnúť, aby sa lepšie dali zastrčiť.
  • EEPROM 24LC16B

Arduino je upravené tak, že má na I2C (nachádza sa netradične na extra pinoch uprostred Arduina) prispájkovanú pin lištu s otvormi, aby sa pomocou dvoch prepojovacích vodičov dalo ľahko prepojiť s EEPROM.

Dve tlačidlá sa používajú na spustenie konkrétnych testov a sú pripojené na piny 6 a 8 na Arduine. EEPROM je pripojená na napájanie a adresové piny A0, A1 a A2 sú nezapojené. To platí ale iba pre tento konkrétny typ EEPROM. Ostatné musia obvykle pripojiť tieto piny na GND alebo na VCC, čím si nastavia I2C adresu. Treba si vždy skontrolovať datasheet ku konkrétnemu typu a nastaviť to podľa neho.

Knižnice

Na ovládanie EEPROM existuje dobrá knižnica extEEPROM. Nainštalujte si ju prostredníctvom správcu knižníc.

Vzorový príklad

Pri tvorbe tohto vzorového príkladu som vyšiel z toho, čo je priložený ku knižnici. V čase písania tohto článku bol priložený príklad s chybami. Preto sa orientujte podľa môjho vzoru.

Príklad po spustení vypíše obsah EEPROM a čaká na stlačenie tlačidla. Dve tlačidlá môžu vyvolať nasledovnú akciu:

  • Tlačidlo 6 - Test zapisovania. Test zaplní celú pamäť postupne sa zvyšujúcimi 32-bitovými číslami. Potom vypíše obsah celej pamäte.
  • Tlačidlo 8 - Test mazania. Test zaplní celú pamäť hodnotou 0xff. Potom vypíše obsah celej pamäte.

Nebudem komentovať celý zdrojový kód, iba jeho podstatné časti. Funkcie eeErase, eeWrite a eeRead som iba mierne pozmenil voči originálu a nachádzajú sa iba v kompletných zdrojových textoch.

Externá EEPROM 24LC16B dokáže uložiť 2 kB 8-bitových hodnôt. V tomto prípade ju reprezentuje objekt eep. Chvíľu mi trvalo, kým som zo zdrojových textov uhádol, na čo slúži parameter page size. Pre vás je dôležitá informácia, že tam treba nechať vždy hodnotu 16. Je to veľkosť údajov, ktoré sa dajú naraz prepraviť a veľkosť je limitovaná aj možnosťami implementácie I2C v Arduine.

#include <extEEPROM.h>

//One 24LC16B EEPROMs on the bus
const uint32_t totalKBytes = 2; // for read and write test functions
const uint8_t chunkSize = 4;    // this can be changed, but must be a multiple of 4 since we're writing 32-bit integers
extEEPROM eep(kbits_16, 1, 16); // device size, number of devices, page size

const uint8_t btnStart = 6;     // start button
const uint8_t btnErase = 8;     // erase button

Vo funkcii setup nastavím dve tlačidlá ako vstupy a aby som na skúšobné pole nemusel dávať externé rezistory, sú tu aktivované interné pull-up rezistory. To znamená, že na danom pine nameriame hodnotu LOW iba vtedy, keď je mikrospínač stlačený. Sériový port je nastavený na hodnotu 115200, aby boli výpisy údajov rýchle. Po resete Arduina sa vypíše aktuálny obsah EEPROM a legenda so zoznamom funkcií.

void setup(void)
{
  pinMode(btnStart, INPUT_PULLUP);
  pinMode(btnErase, INPUT_PULLUP);
  Serial.begin(115200);
  uint8_t eepStatus = eep.begin(twiClock400kHz);      //go fast!
  if(eepStatus) {
    Serial.print(F("extEEPROM.begin() failed, status = "));
    Serial.println(eepStatus);
    while (1);
  }

  // dump current EEPROM memory
  dump(0,totalKBytes*1024);

  Serial.println(F(""));
  Serial.println(F("Press button '6' to start write test"));
  Serial.println(F("Press button '8' to start erase test"));
}

Funkcia loop sleduje, či sme nestlačili nejaké tlačidlo. Krátky delay slúži na ošetrenie zákmitov, ale v reáli trvá zapísanie a vypísanie údajov o čosi dlhšie a preto by tam volanie funkcie nemuselo byť.

void loop(void)
{
if(digitalRead(btnStart) == LOW) {
  delay(100);
  eeWrite(chunkSize);
  eeRead(chunkSize);
  dump(0,totalKBytes*1024);
  }
 
if(digitalRead(btnErase) == LOW) {
  delay(100);
  eeErase(chunkSize,0,totalKBytes*1024);
  dump(0,totalKBytes*1024);
  }
}

Funkcia dump slúži na kontrolný výpis údajov. Nepísal som ju, len som na jej konci opravil chyby, ktoré zabraňovali tomu, aby bol obsah pamäte pekne formátovaný. Páči sa mi, ako sa jej autor pokúsil prehľadne formátovať údaje. Pokúste sa podľa jej kódu uhádnuť, ako asi vyzerajú výsledné údaje.

void dump(uint32_t startAddr, uint32_t nBytes)
{
  Serial.print(F("EEPROM DUMP 0x"));
  Serial.print(startAddr, HEX);
  Serial.print(F(" 0x"));
  Serial.print(nBytes, HEX);
  Serial.print(F(" "));
  Serial.print(startAddr);
  Serial.print(F(" "));
  Serial.println(nBytes);
  uint32_t nRows = (nBytes + 15) >> 4;

  uint8_t d[16];
  for(uint32_t r = 0; r < nRows; r++) {
    uint32_t a = startAddr + 16 * r;
    eep.read(a, d, 16);
   
    Serial.print(F("0x"));
    if ( a < 16 * 16 * 16 ) Serial.print(F("0"));
    if ( a < 16 * 16 ) Serial.print(F("0"));
    if ( a < 16 ) Serial.print(F("0"));
    Serial.print(a, HEX); Serial.print(F(" "));
   
    for(int c = 0; c < 16; c++) {
      if(d[c] < 16)
        Serial.print(F("0"));
      Serial.print(d[c], HEX);
      Serial.print(c == 7 ? "  " : " ");
    }
    Serial.println(F(""));
  }
}

Ak na to nemáte čas alebo článok čítate len zo zvedavosti a nebudete si zapojenie skladať, potom výstup funkcie vyzerá takto.

EPROM DUMP 0x0 0x800 0 2048
0x0000 00 00 00 00 00 00 00 01  00 00 00 02 00 00 00 03
0x0010 00 00 00 04 00 00 00 05  00 00 00 06 00 00 00 07
0x0020 00 00 00 08 00 00 00 09  00 00 00 0A 00 00 00 0B
0x0030 00 00 00 0C 00 00 00 0D  00 00 00 0E 00 00 00 0F

Toto bol krátky úvod ku používanie externých EEPROM. V niektorom z nasledujúcich článkov sa na ukladanie údajov pozrieme z praktickej stránky a ukážeme si, ako ukladať aj zložitejšie údaje pohodlne a bezpečne.

Zdrojový kód

Zdrojový kód sa nachádza na GitHub.


20.03.2017


Menu