Forum: Mikrocontroller und Digitale Elektronik immer noch EEprom


von Ingo L. (grobian)


Lesenswert?

ist irgendwie merkwürdig, was vor 2 Tagen noch ohne delay funftionierte, 
funktioniert jetzt nur noch mit delay im Hauptprogramm..wieso.
Ich warte doch die Stop-Bedingung vom EEprom ab bevor ich neu beschreibe


int EEPROM_SCHREIBEN (void)
{
  BasisAdresse = 0xA0;
    BlockAdresse = EEpromAdresse/256;
    BasisAdresse1 = BasisAdresse + BlockAdresse * 2;
    Speicherzelle = EEpromAdresse%256;

TWSR = (0<<TWPS0) | (0<<TWPS1);       // Prescaler 1
TWBR = 0x34;                // berechnung ergab 52


TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTA);  // start senden
while  (!(TWCR & (1<<TWINT)));        // warten bis fertig
if ((TWSR & 0xF8) != START)
ERROR();


TWDR = BasisAdresse1  ;            // Controll BYTE fur 24c08  OxA1 = 
lesen !!
TWCR = (1<<TWINT) | (1<<TWEN);
while (!(TWCR & (1<<TWINT)));        // warten bis fertig
if ((TWSR & 0xF8) != TWI_MTX_ADR_ACK)    // hats geklappt ?
ERROR();


TWDR = Speicherzelle;            // Daten(ADRERSSE) an das EEPROM senden
TWCR = (1<<TWINT) | (1<<TWEN);
while (!(TWCR & (1<<TWINT)));        // warten bis fertig
if ((TWSR & 0xF8) != TWI_MTX_DATA_ACK)    // hats geklappt ?
ERROR();


TWDR = EEPROM_DATEN;            // Daten(DATEN) an das EEPROM senden
TWCR = (1<<TWINT) | (1<<TWEN);
while (!(TWCR & (1<<TWINT)));        // warten bis fertig
if ((TWSR & 0xF8) != TWI_MTX_DATA_ACK)    // hats geklappt ?
ERROR();

TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO); // und STOP senden
while(TWCR & (1<<TWSTO));          // warten bis fertig

return 0;
}
int main (void)
{

for (EEpromAdresse=0 ; EEpromAdresse <=1023 ; EEpromAdresse++)

  {
      EEPROM_DATEN = 0;
      EEPROM_SCHREIBEN();
      _delay_ms(10);
  }

while(1)
  {
    return 0;
  }
}

von gast (Gast)


Lesenswert?

wenn der EEPROM das stop akzepziert ist   fängt er an mit schreiben
dann muss man so je mach typ 2-5ms warten

du must dann eigentlich prüfen ob du beim senden der EEPROM adresse ein 
ACK bekommst
wenn ein NACK kommt schreibt er noch

also :

schreiben ()
while (prüfen ob ACK)

von Ingo L. (grobian)


Lesenswert?

das mach ich doch hier..oder?

TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO); // und STOP senden
while(TWCR & (1<<TWSTO));          // warten bis fertig

von Michael U. (amiga)


Lesenswert?

Hallo,

Ingo Laabs schrieb:
> das mach ich doch hier..oder?
>
> TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO); // und STOP senden
> while(TWCR & (1<<TWSTO));          // warten bis fertig

nein, hier wartest Du auf das Ende von Stop. Danach ist der I2C-Nus 
wieder frei, um z.B. mit einem anderen Baustein reden zu können.

Der EEPROM beginnt jetzt intern erst mit dem Schreiben.

Wie man abfragt, ob er damit fertig ist, sollte das Datenblatt verraten, 
ein Hinweis kam ja schon.

Gruß aus Berlin
Michael

von Ingo L. (grobian)


Lesenswert?

hmmm...

TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);  // und STOP senden
while (TWCR & (1<<TWINT));


so haut es aber auch nicht hin

von Stefan E. (sternst)


Lesenswert?

Ingo Laabs schrieb:

> so haut es aber auch nicht hin

Wie denn auch. Du machst hier nur Bus Abfragen. Du musst den Chip 
auf einer höheren Kommunikationsebene fragen, ob er schon wieder bereit 
ist.

von Uhu U. (uhu)


Lesenswert?

gast schrieb:
> wenn der EEPROM das stop akzepziert ist   fängt er an mit schreiben
> dann muss man so je mach typ 2-5ms warten
>
> du must dann eigentlich prüfen ob du beim senden der EEPROM adresse ein
> ACK bekommst
> wenn ein NACK kommt schreibt er noch

Ich hab letzthin so ein Teil angeschlossen. Wenn der Chip noch 
geschrieben hat, kam auf die Adresse noch ein ACK, das erste zu 
schreibende Datenbyte wurde mit NACK beantwortet.

von Ingo L. (grobian)


Lesenswert?

Stefan Ernst schrieb:
>
> Wie denn auch. Du machst hier nur Bus Abfragen. Du musst den *Chip*
> auf einer höheren Kommunikationsebene fragen, ob er schon wieder bereit
> ist.
 ja aber wie ?
Habe mich doch hier genau an das Beispiel aus dem Datenblatt gehalten 
was ja auch soweit funktioniert, aber nur einmal. Will ich dann ein 
zweites Byte schreiben funktioniert das nicht.

Gruß aus Berlin
Ingo

von Michael U. (amiga)


Angehängte Dateien:

Lesenswert?

Hallo,

ich habe jetzt nicht geschaut, ob Du den EEPROM-Typ erwähnt hast, aber 
mal das Datenblatt eines 24LC256 Seite 10 unter Acknowledge Polling.

Du mußt vor dem nächsten Zugriff abfragen, ob das EEPROM mit schreiben 
fertig ist. Wenn nicht, bekommst Du kein ACK und muß es eben nochmal 
versuchen.

Gruß aus Berlin
Michael

von gast (Gast)


Lesenswert?

alle eeproms haben das selbe schema :

startbit
eepromadresse ( mit schreibbit)
datenadresse
daten
.
.( für page write größe beachten )
.
.daten
stopbit
( und jetz muss man ~5ms warten  oder ackpolling betreiben )


wobei ich festgestellt hab das ackpolling bei meinen eeproms im schnitt 
3-5ms brauch -.-


der witz beim lernen ist der ..
wenn man nur ab und an was reischreibt ... ( ohne ackpolling oder 
warten)
wo genug luft dazwischen ist
und alles läuft

dann aber alles rumspinnt weil man nun mal mehrere werte speichert ^^

von Ingo L. (grobian)


Lesenswert?

> ( und jetz muss man ~5ms warten  oder ackpolling betreiben )


das ich jetzt warten muss, habe ich ja begriffen. Mit einem delay von, 
bei mir 10ms funktioniert es ja.

Ich weiß jetzt nur nicht wie ich das ACK-Polling nach dem Stopp 
durchführe.

von Uhu U. (uhu)


Lesenswert?

Einfach eine neue Schreiboperation ankicken und wenn ein NACK kommt, mit 
Stop abbrechen und neu versuchen.

von Ingo L. (grobian)


Lesenswert?

Uhu Uhuhu schrieb:
> Einfach eine neue Schreiboperation ankicken und wenn ein NACK kommt, mit
> Stop abbrechen und neu versuchen.

und genau das verstehe ich nicht, wie das funktionieren soll....

von Uhu U. (uhu)


Lesenswert?

Ingo Laabs schrieb:
> und genau das verstehe ich nicht, wie das funktionieren soll....

Die Brachiallösung ist ein 5 ms Delay nach jedem geschrieben Byte.

Die etwa feinere schreibt so lange, bis das EEPROM mit NACK antwortet 
und schickt dann ein Restart und versucht das abgewiesene Byte nochmal 
zu schreiben - so lange, bis ein ACK zurück kommt.

von Ingo L. (grobian)


Lesenswert?

5 ms !!!
ach du liebe Zeit.
Bei 1024 Byte beim 24C08 würden alleine diese 5 ms schon dafür sorgen, 
dass das schreiben des EEPROM 5,12 Sekunden benötigt.
Beim 24C512 wären es ja dann schon 327 Sekunden oder sehe ich das falsch 
?

von gast (Gast)


Lesenswert?

wenn man eine page schreibt geht das schneller :P

dieEEPROMs brauchen diese zeit für EINE schreiboperation
ob da nun 1 byte oder eine page geschrieben wird ist egal
beides dauert ~5ms

man muss beim schreiben jedoch aufpassen das man nicht Über die pagezise 
schreibt
da der adresscounter im EEPROM dann meist an den anfang der page springt 
und so alte werte überschreibt



zum ack polling

steht doch im datenblatt
steht auf dem datemblatt hier vom thread auf seite 10
bzw kapitel 7.0

zitat :
ACK polling can be initiated immediately. This involves the master
sending a Start condition, followed by the control byte
for a Write command (R/W = 0). If the device is still
busy with the write cycle, then no ACK will be returned.
If no ACK is returned, the Start bit and control byte must
be resent


zB von meinem 24FCxxxx

startbit
eeprom adresse mit  R/!W = 0 ( schreiboperation )
kommt ein ACK = 0  dann isser fertig
wenn nicht ...
neues senden von start
solange bis eben ACK kommt

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.