Lekce 18 - Arduino a externí EEPROM přes I2C

11.05.2013 15:15

Translate to English

V minulém díle jsme si ukázali jak využít vestavěnou pamět EEPROM v Arduinu. Dnes si ukážeme jak připojit přes I2C rozhraní (2-vodičové) přívě libovolnou seriovou pamět EEPROM.

Já jsem si tedy pro naše pokusy sehnal několik pamětí. Jedná se o tyto kousky:

Typ EEPROM paměť cena cca datasheet
24C01 125 x 8bitů (1kbit)   4,40 Kč zde
24C08 1000 x 8bitů (8kbit) 1kB 7,30 Kč zde
24C32 4 096 x 8bitů (32kb) 4,096kB 11,10 Kč zde
24C128 16 384x 8 bitů  27,70 Kč zde 

My si teď ukážeme nejdříve jak pamět připojit k Arduinu. Není to složité stačí nám pouze napájení z Arduina a dva vodiče s SLA a SLC (I2C rozhraní) napojené na v případě Arduino UNO na A4 a A5. Plánek zapojení je zde:

V mém zapojení jsem vynechal kondenzátor 100nF zapojený mezi zem a napájení. Pokud chcete můžete jej tam dát, ale ať jsem hledal jak jsem hledal, účel a nutnost jej použít jsem nenašel. Jak můžete vidět vývody 1, 2 a 3 z EEPROM jsou takzvané adresovací vývody. To znamená, že když jsou všechny A0 až A2 připojeny k zemi, je adresa paměti 0x50. Když nějaký ten pin připojíte na +5V tak se adresa paměti změní - viz následující tabulka:

A2 A1 A0 adresa
GND GND GND 0x50
GND GND +5V 0x51
GND +5V GND 0x52
GND +5V +5V 0x53
+5V GND GND 0x54
+5V GND +5V 0x55
+5V +5V GND 0x56
+5V +5V +5V 0x57

 

My ale v zapojení nebude nic měnit a ponecháme adresu na 0x50 tím, že bude A0 až A2 zapojen k zemi. Vývod 4 z EEPROM je  také zem a vývod 8 je připojen k napájecímu napětí +5V. Vývod 7 z EEPROM je WP (write protection), tzv. pojistka proti zápisu, tu máme připojenu k +5V a je umožněno na paměť zapisovat. Když to bude naopak ke GND (zemi) toto umožneno nebude. Vývod 5 (SDA) připojíme na Arduino na I2C rozhraní, kde je na vývodu A4 (analogový pin4) a vývod 6 (SCL) na A5. Pokud vše máme zapojeno můžeme Arduino naprogramovat (Program je určen pro 24C01 nebo 24C02 - později vysvětlím):

Jak můžete vidět v okomentovaném kódu, je potřeba načíst knihovnu pro práci s rozhraním I2C a to wire.h. Zápis je jednoduchý. Nejdříve inicializujeme komunikaci s adresou zařízení 0x50 (můžeme i změnit), dále odešleme adresu v paměti (byte) u nás "5" a jako další byte odešleme naše data - pro test jsme zvolili číslo 222. 

Po zapnutí Serial Monitoru, musíme vidět prostě tohle:

Tak nám to funguje a zkusíme zapojit teď 24c08. No chvilka napětí a výsledek ten samý, na Serial Monitoru se objevilo číslo 222. Tak třetí pokus 24C128 - skoro Mercedes mezi EEPROM, 4kB paměti :-). A program na Serial vypsal hodnotu 255. Co se stalo? Proč to nefunguje?

Vysvetlení je jednoduché  a spočívá v adresování paměti v EEPROM. Když se koukneme do dokumentace k pamětím 24C01 a 24C08, tak k adresování jednotlivých bytes tak po nás byla vyžadována jedna hodnota (word) a u paměti 24C32 a 24C128, takže chyba je způsobena špatnou adresací. Program si upravíme tak, aby odeslal adresu na dvakrát. Jak si můžete prohlédnout zde:

V kódu jsem již odeslání hodnoty a získání integroval do funkce, aby byl kód přehlednější. Použil jsem zrovna 24C32 takže jsem mohl použít maximální adresu 4095, protože má kapacitu 4096 x 8 bitů a první adresa již začíná na 0. Já jsem na adresu 2574 odeslal hodnotu 147 a jak můžete vidět poté po spuštění serial monitoru, hodnota přečtené z téže adresy je v pořádku. :-)

V případě 24C128  je kapacita 16384 x 8 bitů tak poslední adresa je 16383. Když náhodou zkusíte překročit kapacitu a adresujete byte nějak za maximálná hranici EEPROM záčíná adresovat opět od začátku. Např. adresa u 24C32 maximální použitelná je 4095, ale když u této paměti budeme adresovat např. 4098 byte se zapíše nebo přečte z adresy 2.

Tak já myslíš, že pro vysvětlení EEPROM s použitím I2C to stačí. Ukládat jiné hodnoty jsme se naučili rozkladem na bytes v předchozím tutoriálu a ukládání textů je téměř shodné jako u interní EEPROM. Video nepřikládám, nebylo moc co točit :-) 

 

Zpět

Diskusní téma: Lekce 18 - Arduino a externí EEPROM přes I2C

Datum
Vložil
Titulek

uff

ten, kdo nevi, proc je tam ten kondik, ten by si nemel hrat s dratecky a mikroprocesory.. uff ta nova generace!

Datum
Vložil
Titulek

Re: uff

Kritizovat umí každý, ale vysvětlit, to už ne, že?

Datum
Vložil
Titulek

Re: Re: uff

Každý číslicový obvod způsobuje proudové impulsy na napájecím vodiči. Vzhledem k jeho nenulové indukčnosti tak budou vznikat napěťové impulsy na napájení, které mohou ovlivnit činnost toho obvodu nebo dalších obvodů napájených stejným přívodem. Jev se potlačí právě tím kondenzátorem, který slouží jako vyrovnávací zásobník náboje a udržuje na sobě více méně v čase neměnné napětí.

Datum
Vložil
Titulek

24C32

Mě s 24C32 funguje toto:

// funkce zápis byte
void i2c_eeprom_write_byte( int deviceaddress, unsigned int eeaddress, byte data ) {
int rdata = data;
Wire.beginTransmission(deviceaddress);
Wire.write((int)(eeaddress >> 8)); // MSB
Wire.write((int)(eeaddress & 0xFF)); // LSB
Wire.write(rdata);
Wire.endTransmission();
}

// funkce čtení byte
byte i2c_eeprom_read_byte( int deviceaddress, unsigned int eeaddress ) {
byte rdata = 0xFF;
Wire.beginTransmission(deviceaddress);
Wire.write((int)(eeaddress >> 8)); // MSB
Wire.write((int)(eeaddress & 0xFF)); // LSB
Wire.endTransmission();
Wire.requestFrom(deviceaddress,1);
if (Wire.available()) rdata = Wire.read();
return rdata;
}

Datum
Vložil
Titulek

24C01 Nefunguje

Přepsal jsem si ten 1 program a nefunguje to v serial monitoru mi to vypíše 255. Program jsem zkoušel i překopírovat a dělá to to samé. Proč?

Datum
Vložil
Titulek

Re: 24C01 Nefunguje

WP musí být připojeno na GND. Potom je umožněn zápis. Po připojení na 5V je zápis zakázán. V textu to je obráceně.

Datum
Vložil
Titulek

Zápis do celé EEPROM 24C16

Problém vyřešen - paměť 24C16 je uvnitř rozdělená do osmi oddílů po 256 bytech a ty se přepínají adresou zařízení, vývody A0, A1 a A2 nejsou zapojené a nefungují. Adresa 0x50 je pro zápis do prvního oddílu, 0x51 do druhého ....... a 0x57 je pro zápis do poslední části paměti. Odzkoušen zápis přes Arduino do celé paměti 24C16 a paměť pak přečtena v programátoru, funguje to.

Datum
Vložil
Titulek

Adresace jen prvních 256B

Vyzkoušel jsem program pro zápis do 24C01 a 24C02 s pamětí 24C16 a dopadlo to tak, jak jsem čekal - zapisuje jen do prvních 256B, takže při adrese 1999 zapíše data na adresu 207, protože do 8 bitů se tak velké číslo nevejde. Jak by se dalo zapisovat do celé paměti 24C16 (také 24C04 a 24C08)?

Datum
Vložil
Titulek

i2c eeprom zápis int hodnoty

je tedy správně toto? pro 24c32 a větší

void i2c_eepromIntWrite( int device, unsigned int adresa, int hodnota )
{
byte byte1 = hodnota;
byte byte2 = hodnota >> 8;
Wire.beginTransmission(device);
Wire.write((int)(adresa)); // odešle vyšší byte
Wire.write((int)(adresa & 0xFF)); // odešle nižší byte
Wire.write(byte1);
Wire.write(byte2);
Wire.endTransmission();
}

int i2c_eepromIntRead( int device, unsigned int adresa )
{
byte rdata1;
byte rdata2;
Wire.beginTransmission(device);
Wire.write((int)(adresa)); // odešle vyšší byte
Wire.write((int)(adresa & 0xFF)); // odešle nižší byte
Wire.endTransmission();
Wire.requestFrom(device,2);
if (Wire.available()) rdata1 = Wire.read();
if (Wire.available()) rdata2 = Wire.read();
return (rdata1+(rdata2 << 8));
}

Vyhledávání

arduino8.cz © 2015 Všechna práva vyhrazena.