Problem beim Schreiben in I2C EEPROM

Gast #742009
Lesenswert?

Hallo, ich benutze die I2C Master Library von P. Fleury und habe da ein 
kleines Problem.
Hin und wieder, wenn ich mit meiner Funktion ein Datum + Uhrzeit in den 
externen I2C EEPROM AT24C512 speichern will, schreibt er mir den ersten 
Eintrag, also die Stunde nicht, sondern stattdessen einfach gar nichts, 
also ich bekomme dann beim Auslesen entweder das, was vorher schon unter 
dieser Adresse stand oder 0xFF.
Hier meine Funktion:
1
void recTime(void)
2
{
3
  // Überprüfung auf Änderung des Monats oder des Jahres
4
  
5
  if ((prevMonth != recMonth) || (count == 0))
6
  {
7
    eeprom_write_word(&eeMonthAddress[recMonth-1], address);
8
  }
9

10
  // Schreiben der Werte in externen EEPROM
11
  
12
  i2c_start_wait(i24c512+I2C_WRITE);
13
  i2c_write(address >> 8);
14
  i2c_write(address);
15
  i2c_write(recHour);
16
  i2c_write(recMinute);
17
  i2c_write(recSecond);
18
  i2c_write(recDate);
19
  i2c_write(recMonth);
20
  i2c_stop();
21
  
22
  address += 5;    // Adresse erhöhen
23
  
24
  count++;  
25
}
Ich sollte vielleicht noch dazu sagen, dass ich nicht den Hardware TWI 
meines ATMEGA32 verwende, da dieser komischerweise gar nicht 
funktioniert hat, also jedes mal, wenn ich aus dem EEPROM lesen bzw. in 
den EEPROM schreiben wollte, blieb das Programm einfach stehen.
Also verwende ich die softwareemulierte Version auf den Pins des 
Hardware TWI Interface.

Außerdem verwende ich noch den internen Timer2 zwecks Uhrzeit.

Woran kann nun dieses EEPROM Problem liegen, bzw. hat einer von euch 
eine Idee, wie ich es beheben kann?
Persönliche Seite #742604
Lesenswert?

Hast du schon probiert zu warten, bis die Zugriffe auf das interne 
EEPROM beendet sind?
1
  // ... Restcode ...
2

3
  // Warten Bis vorangegangene EEPROM Zugriffe
4
  // beendet sind und ggf. gesperrte Interrupts
5
  // wieder eingeschaltet sind.
6
  eeprom_busy_wait();
7

8
  i2c_start_wait(i24c512+I2C_WRITE);
9

10
  // ... Restcode ...

EEPROM in der AVR-Libc
http://www.nongnu.org/avr-libc/user-manual/group__avr__eeprom.html
#742622
Lesenswert?

Gute Idee, stimmt aber leider nicht. Es liegt an der Übergabe der 
Adresse des I2C Gerätes und des Read/Write Bits. Im ersten über I2C 
gesendeten Byte steht die Adresse und die Art des Zugriffs. Daher ergibt 
sich für Schreibzugriff:
Adresse * 2
da Bit 0 beim Schreibzugriff 0 sein muss und in 1 bis 7 die Adresse 
steht,
und fürs Lesen:
Adresse * 2 + 1
da Bit 0 beim Lesezugriff 1 sein muss. Habs grad eben noch getestet.
Gast #742641
Lesenswert?

@ Daniel

So ein Quatsch !
Wenn die I2C Adresse 0xA0 ist dann bleibt sie das auch.
Da muss nix geschoben werden. Schreiben geht dann mit
0xA0 und lesen mit 0xA1. Punkt und aus.

Wenn DU deine I2C Adresse anders definierst,
dann musst DU wohl schieben.
Gast #742675
Lesenswert?

Ich denke mal das ist ein Problem mit den Pages.
Mehrere Bytes kann man nur innerhalb einer Page
direkt nacheinander schreiben.

Wenn nicht sicher ist das alle Bytes in einer
Page liegen muss man sie alle EINZELN schreiben.
Und nach jedem Byte schön warten (20ms reicht oder
per ACK-Polling) bis es auch drin ist.
#742705
Lesenswert?

@ holger (Gast)

>Wenn nicht sicher ist das alle Bytes in einer
>Page liegen muss man sie alle EINZELN schreiben.

Oder mit ein wenig Grips die Page-Grenze berechnen und dann wieder 
teileweise/volle Pagezugriffe machen.

alle Bytes bis zu nächsten Page-Grenze schreiben
N mal volle Pages schreiben
Rest schreiben.

MFG
Falk
Gast #742731
Lesenswert?

Ich hatte die gleichen Probleme, dass nur jedes Zweite Byte geschrieben 
wurde. Das liegt an den Timings vom EEPROM. Dadurch dass es bei mir 
nicht schnell gehen sollte, habe ich für jedes Byte eine Start+Stopp 
Routine gemacht mit einer kleinen Wartezeit zwischendurch.
Gast #742787
Lesenswert?

Hi, also das mit den Pages habe ich auch schon wo gelesen, aber ich habe 
es auch schon so probiert, das ich jeden Wert einzeln in den EEPROM 
geschrieben habe, also jeweils mit Start und Stopp.
Außerdem passiert mir das ja immer nur beim ersten Wert, den ich in den 
EEPROM schreibe, also glaube ich fast, das es daran nicht liegt.
Gast #743820
Lesenswert?

Hallo,

ich habe die letzten Tage auch mit dieser Routine versucht ein Slave 
anzusprechen. Über den Fehler mit der Adresse bin ich auch gestolpert. 
Weiterhin funktioniert diese Routine nur, wenn der Slave schnell genug 
ist, da eine vom Slave low gehaltene CLK-Leitung ingoriert wird (Da ist 
das Protokoll nur teilweise implementiert). Nachdem ich die Routine 
entsprechen geändert hatte ging es dann. Am besten mit einem 
Speicheroszi mal den Übertragungsversuch aufzeichen. So habe ich die 
Fehler bei mir auch gefunden.
Gast #743939
Lesenswert?

Hallo, leider habe ich zur Zeit kein Speicheroszi zur Verfügung, mitdem 
ich die Übertragung aufzeichnen könnte.
Inwiefern hast du die Routine geändert, damit es dann funktioniert hat?
Gast #744426
Lesenswert?

Hallo Christof,

alle Details weiß ich nicht mehr. Ich hatte solange geändert, bis ich 
auf dem Oszi das passende hatte. Ich habe meine aktuelle i2cmaster.S 
angehängt. Probier sie doch einfach mal aus, ob es was hilft. Durch die 
Änderung kann es theoretisch vorkommen dass er bei einem Fehler auf dem 
Buss "hängen" bleibt (wenn CLK während einer Übertragung auf low geht 
und low bleibt). Diese Problem hatte ich bei der Orginal Atmel USI 
Application Note als Slave, wenn der Sedebuffer im Slave leer war.
Angehängte Dateien:

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren