25 Sériová paměť prakticky

Pojďme si připojit sériovou paměť a něco s ní dělat. Co? Pojďme si třeba ukládat naměřená data do sériové paměti EEPROM, připojené přes sběrnici I2C.

Arduino Uno má samozřejmě vyvedené signály SDA a SCL pro sběrnici I2C. Překladač pro Arduino navíc nabízí knihovnu Wire, která právě se sběrnicí I2C pracuje. Navíc umí zapnout interní pull-up rezistory, takže není potřeba připojovat ehterní. Připojení sériové paměti je tak otázka jen několika propojovacích vodičů.

Použijte paměť z řady 24LC – třeba 24LC01, ale klidně i jakoukoli jinou s větší kapacitou. Budeme si ukazovat princip, ne konkrétní řešení.

Paměti 24LCxx mají následující zapojení vývodů:

Vývody 1, 2 a 3 nastavují adresu. Už jsem se zmiňoval, že zařízení na sběrnici I2C mají svou sedmibitovou adresu, a že u některých ji lze změnit. Sériové paměti EEPROM mívají jako základní adresu 0x50, a tři nejnižší bity lze nastavit pomocí vstupů A0-A2. Konkrétní čip tedy může být nastaven tak, aby se hlásil na jedné ze sedmi adres 0x50 – 0x57. Pokud máte na jedné sběrnici jen jednu paměť, tak připojte všechny vstupy A na zem, paměť tak bude mít adresu 0x50.

Na zem připojte i vývod 7 – WP (Write protect). Pokud je připojen k zemi, může se do paměti zapisovat, pokud je spojen s napájecím napětím, je zápis zakázán.

Teď zbývá jen připojit napájecí napětí a signály pro I2C, tedy SDA a SCL. Na konci knihy, v přílohách, najdete takzvaný „pinout“, neboli rozložení vývodů Arduina včetně speciálních funkcí. A tam zjistíte, že SCL je vyveden na pin A5 a SDA na pin A4. propojení pak vypadá nějak takto:

Pro zápis do této paměti stačí poslat po sběrnici I2C nejprve adresu obvodu (tedy výše zmíněných 0x50), poté adresu v paměti (dva bajty, nejprve vyšší), a nakonec požadovaný bajt k zápisu. Nezapomeňte po zápisu počkat dostatečně dlouhou dobu – EEPROM zapisují pomalu.

void writeEEPROM(unsigned int address, uint8_t data) 
{
    Wire.beginTransmission(0x50);
    Wire.send((int)(address >> 8)); // MSB
    Wire.send((int)(address & 0xFF)); // LSB
    Wire.send(data);
    Wire.endTransmission();
    delay(5);
}

Při čtení pošlete adresu stejně jako při zápisu, ale pak namísto poslání bajtu k zápisu jeden bajt přečtěte:

uint8_t readEEPROM(unsigned int address) 
{
    uint8_t data = 0xFF;
    Wire.beginTransmission(0x50);
    Wire.send((int)(address >> 8));   // MSB
    Wire.send((int)(address & 0xFF)); // LSB
    Wire.endTransmission();
    Wire.requestFrom(0x50,1);
    if (Wire.available()) data = Wire.receive();
    return data;
}

Schéma a zdrojový kód najdete na eknh.cz/eep

26 Hodiny reálného času

Last updated