Wire.beginTransmission(0x50)
Wire.write(0 | 1) <<<<<<<<<<<< hier die Umschaltung auf Page 1 (oder 2-7.)
Wire.write(245)
den Rest schreiben.
meine Frage ist jetzt, funktioniert das mit der Page - Steuerung so wie oben beschrieben?
Ich würde gerne jede Speicherzelle Byteweise beschreiben.., die Codesegmente sind nur
lückenhaft, es fehlen natürlich noch einige Zeilen und delays...
Beim Schreiben einzelner Bytes brauchst Du Dich nicht um die Pages zu kümmern. es genügt die Adresse anzugeben.
Um die Pages mußt Du Dich beim Brust-schreiben (sequenzielles Schreiben /lesen von mehreren Bytes nacheinander ohne immer wieder die Adresse einzugeben zu müssen) kümmern, da dies nicht über Pagesgrenzen hinaus funktioniert bzw die Daten an den Anfang der gleichen Page geschrieben werden und nicht in die nächste Page.
Grüße Uwe
Meine Frage ist eher "funktionell" gedacht, funktioniert denn das so mit dem schreiben auf einzelne Pages, wie im Beispiel oben?
Hintergrund ist folgender, ich habe 4 Sensoren deren Werte ich voraussichtlich halbstündlich abspeichern möchte.
und ich hätte das gerne so abgespeichert:
Das EEprom hat Pages zu 16 Byte. Du kannst darum 16 Byte in einem Rutsch übermitteln (page write bzw Page read) wobei das erste Byte aber am Pagesanfang stehen muß (alle 16 Byte in der gleichen Page).
Die Page gehen von den Ardessen 0 bis 15, 16 bis 31 ecc) (siehe Seite 16 Datenblatt).
Natürlich kannst Du Daten auf den Adressen 0, 16, 32, und 48 abspeichern, aber ich sehe weder die Notwendigkeit noch einen Sinn.
Du hast aber viel heufigere Writezyklen da Du auch in der gleichen Page alle Daten der 4 Sensoren in einem Rutsch abspeichern kannst.
Die Kombination aus Page und Adresse in der Page kann man mit Division und Modulo-Division berechnen
Das fehlt mir noch in meinen (nichtvorhandenen) Multibyte Funktionen
uwefed:
Es sind 16 Byte Pages.
Hmm...
Vielleicht so besser: (?)
256 Byte Pages, welche wiederum in 16 Byte Rows unterteilt sind.
uwefed:
Der AT24c08 scheint mir kompatibel zu dem von ST zu sein.
Softwareseitig, wohl ja, scheint mir....
Der folgende Code ist völlig ungetestet, da ich keinen einzigen vergleichbaren Baustein im Zugriff habe. Wäre schön wenn das jemand tun könnte.....
Also: Keine Garantie auf garnichts.
#include <Wire.h>
/*
* Verwendbar für 24C01 , 24C02 , 24C04 , 24C08 24C16
* Wenn die EEProm Adressen (A0 bis A2) fortlaufend vergeben sind,
* reicht eine I2cEeprom Instanz um mehrere Bausteine anzusprechen.
*
* Ausnahmen:
* Der 24C16, der nutzt schon alle Adressen
* Bei mehreren 24C01 entstehen Doppeleinblendungen im Adressraum,
* denn er nutzt nur 7 Bit adressen, eine Page ist also nur
* 128 Byte groß.
*
* Die anderen Bausteine fügen sich Nahtlos aneinander.
*
*
* Kompatibilität:
* Die Zugriffsmethoden dieser Klasse sind aufrufkompatibel mit
* der original Arduino EEPROM Library. Also sollten die dort
* mitgelieferten Beispiele grundsätzlich funktionieren.
*
* Ausnahme:
* Das Array Access Interface ist nicht implementiert. Die darauf
* basierenden Beispiele funktionieren nicht.
*
* Desweiteren muss eine Instanz der Klasse erzeugt werden.
* Die orginallib macht das automatisch.
*
* ToDo:
* Adressüberschreitungen abfangen
* Array Access implementieren
* Multibyte Read&Write, also schreiben in 16 Byte Row Durchgängen
*
*/
class I2cEeprom
{
private:
uint8_t busAddress;
public:
I2cEeprom(uint8_t busAddress):busAddress(busAddress){}
uint8_t read(uint16_t address)
{
uint8_t result = 0;
int Adresse = busAddress + (address >> 8);
Wire.beginTransmission(Adresse);
Wire.write(address & 0x00ff);
Wire.endTransmission();
Wire.requestFrom(Adresse,1);
if (Wire.available()) result = Wire.read();
return result;
}
void write(uint16_t address,uint8_t value)
{
int Adresse = busAddress + (address >> 8);
Wire.beginTransmission(Adresse);
Wire.write(address & 0x00ff);
Wire.write(value);
Wire.endTransmission();
}
void update(uint16_t address,uint8_t value)
{
uint16_t old = read(address);
if (old != value) write(address,value);
}
template< typename T >
T &get(uint16_t address, T &customvar)
{
uint8_t *ptr = (uint8_t*) &customvar;
for(int i = 0; i < sizeof(T); i++)
*ptr++ = read(address + i);
return &customvar;
}
template< typename T >
T put(uint16_t address,T &customvar)
{
uint8_t *ptr = (uint8_t*) &customvar;
for(int i = 0; i < sizeof(T); i++)
update(address + i,*ptr++);
return &customvar;
}
// EEPROM[]
};
I2cEeprom eep(0x50); // Instanz anlegen mit der I2C Basisadresse 0x50
void setup()
{
Wire.begin();
eep.update(0,112); // 112 an die Adresse 0 schreiben. (wenn nicht schon geschehen)
}
void loop() {
// put your main code here, to run repeatedly:
}
Ja, warum ich da zu kompliziert denke weis ich nicht...
ich habe bislang, wenn ich ein ext. EEPROM benötigt habe, immer nur einzelne Bytes an in div. Adr. geschrieben.
Da A0-A2 alle auf GND sind, sollte die Dev-Adr. ja 0x50 sein?
ich habe dann also an Adr. 0x50, Platz 0- (ich glaub) 127 gesendet, und das klappte auch,
eine Speicherzelle mit Adr. 0x50, Platz 200 z.B. konnte ich nicht beschreiben/lesen,..,
ich glaub da muss ich jetzt nachmals drüber schlafen und das Datenblatt des EEPROM nochmals lesen,
es ist übrigens von ST!
Wobei es da einfacher ist nur mit der Basis-Adresse 0x50 zu denken. Die Page/Seite kann man mit einem bitweisen ODER zur I2C-Adresse hinzufügen bevor man die Adresse auf den Bus schreibt.
ich dachte immer, ich kann alle Zellen unter 0x50 erreichen,...
aber, unter 0x50 sollte es dann ja die Zellen 0-255 (Byteweise) ansprechen können,
das hat bei mir bislang nicht geklappt, es ging nur bis Zelle 127, danach kamen nur falsche
Werte beim auslesen zurück.. Warum?
Kann ich nicht direkt in die höheren Zellen schreiben?
adr ist dabei eine Adresse durchgehend über alle Pages von 0 bis zur höchsten Speicherzelle!
Und wenn du Multi-Byte Datentypen hast rufst du mehrmals readByte() oder writeByte() auf. Dadurch entsteht zwar etwas Overhead wenn man in einer Seite ist, aber der Zugriff über Seiten-Grenzen hinaus ist sehr einfach.
Hab jetzt noch schnell nachgeschaut, das EEPROM ist von ST und trägt die Aufschrift 24C08WP 78277 325.
Den Code den ich nutze, muss ich von einem anderen PC kopieren, ist aber eigentlich nur so wie oben
Wire.beginTransmission(0x50);
Wire.write((250); <<- hier stehen dann die Adr. 0-255 - was aber nur von 0-127 funktioniert
Wire.write(100); <<- hier sehen dann die zu speichernden Werte von 0-255.
Wire.endTransmission();