mikrocontroller.net

Forum: Compiler & IDEs Problem beim Schreiben in I2C EEPROM


Autor: Christof Kauba (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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:
void recTime(void)
{
  // Überprüfung auf Änderung des Monats oder des Jahres
  
  if ((prevMonth != recMonth) || (count == 0))
  {
    eeprom_write_word(&eeMonthAddress[recMonth-1], address);
  }

  // Schreiben der Werte in externen EEPROM
  
  i2c_start_wait(i24c512+I2C_WRITE);
  i2c_write(address >> 8);
  i2c_write(address);
  i2c_write(recHour);
  i2c_write(recMinute);
  i2c_write(recSecond);
  i2c_write(recDate);
  i2c_write(recMonth);
  i2c_stop();
  
  address += 5;    // Adresse erhöhen
  
  count++;  
}
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?

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hast du schon probiert zu warten, bis die Zugriffe auf das interne 
EEPROM beendet sind?

  // ... Restcode ...

  // Warten Bis vorangegangene EEPROM Zugriffe
  // beendet sind und ggf. gesperrte Interrupts
  // wieder eingeschaltet sind.
  eeprom_busy_wait();

  i2c_start_wait(i24c512+I2C_WRITE);

  // ... Restcode ...

EEPROM in der AVR-Libc
http://www.nongnu.org/avr-libc/user-manual/group__...

Autor: Daniel Heppner (heppi_)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dann ist doch eigentlich i24c512 ungeschickt definiert.

EDIT: Holger war schneller.

Autor: Daniel Heppner (heppi_)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tut mir leid das stimmt nicht. Die Adresse wird auch nciht geändert 
sondern nur das Byte, dass über den I2C Bus geschickt wird. Lies z.B. 
das Datenblatt des PCA9554/PCA9554A (8-bit I2C and SMBus I/O port with 
interrupt) auf Seite 7 .

Autor: Daniel Heppner (heppi_)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Im Anhang ein Bild der Bytes die über I2C gesendet werden müssen. 
Interessant in das Control Byte! 7 bit für die Adresse und ein Bit für 
Lesen/Schreiben!

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Daniel

Ach du meinst die Subadress die man aussen an den
Pins einstellen kann. Gut, die musst du schieben.
Oder definier sie gleich mit dem geschobenen Wert.
Dann sparst du dir das schieben.

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Christof Kauba (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Manfred S. (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Christof Kauba (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Manfred S. (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.