Forum: Mikrocontroller und Digitale Elektronik SPI-EEPROM 25LC640 -- page write zyklus


von Christian S. (roehrenvorheizer)


Lesenswert?

Hallo allerseits,

zur Zeit bin ich dabei, ein Übungsprogramm zur Benutzung eines 
SPI-EEPROMs zu schreiben.

Lesen einzelner Adressen geht,
schreiben einzelner Adressen geht
lesen oder beschreiben des ganzen 8192 Bytes großen EEPROMs geht.

Was nicht geht, ist der Schreibvorgang für eine ganze page, bei dem 32 
Bytes nacheinander eingeschoben werden, ohne jedes Mal einen neuen 
Schreibbefehl abzusenden. Es werden Adressen 0..32 beschrieben, Adressen 
33..64 nicht, dann 65..96 beschrieben, usw.


Aus dem Datenblatt erschließt sich für mich nicht so recht der 
geforderte Ablauf. (Link zum Datasheet habe ich weg gelassen, da er 
mehrere Zeile lang ist, findet Gurgel aber ganz leicht mit "25LC640 
datasheet")

Zitate Seite 7:
Prior to any attempt to write data to the 25XX640 array or STATUS 
register, the write enable latch must be set by issuing the WREN 
instruction.

Once the write enable latch is set, the user may proceed by setting the 
CS low, issuing a WRITE instruction, followed by the address, and then 
the data to be written. Up to 32 bytes of data can be sent to the 
25XX640 before a write cycle is necessary.

For the data to be actually written to the array, the CS must be brought 
high after the Least Significant bit (D0) of the nth data byte has been 
clocked in.

While the write is in progress, the STATUS register may be read to check 
the status of the WPEN, WIP, WEL, BP1, and BP0 bits (Figure 3-6). When 
the write cycle is completed, the write enable latch is reset.

Seite 9:
This latch must be set before any write operation will be completed 
internally. The WREN instruction will set the latch, and the WRDI will 
reset the latch.


Seite 12:

After a byte write, page write, or STATUS register write, the write 
enable latch is reset • CS must be set high after the proper number of 
clock cycles to start an internal write cycle.

Mit oder ohne WRDI-Befehl macht das keinen Unterschied an der 
Fehlfunktion. Mir ist auch nicht klar, wann und wozu man z.B. aus dem 
Status-Register die Bits WEL WIP auslesen sollte, wenn man nach dem 
Schreiben pauschal 5 ms lang wartet.

In diesem Beispiel hier, wird eines der Bits abgefragt vor dem 
Schreiben, aber danach kein WRDI-Befehl gegeben:
http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=40425

Kann mir da mal bitte jemand auf die Sprünge helfen? Unten der von mir 
verwendete Ablauf.

mit freundlichem Gruß

__________________________________

i = 0;
while ( i < EEPROMgroesse )
{
LED grün
// CS low
Write enable-Befehl 0x06    // WREN  =set the write enable latch
// CS high
2 µs


// CS low
Write Befehl 0x02    // WRITE = write data to memory array beginning at 
selected adress
// MSB Address
// LSB Address

5ms

for ( j = i; j < (i + 32) ; j++ ) //innere Schleife, die immer nur 32 
Bytes durchzählen soll.
    {
    // 0xFF Data schreiben zum Löschen

    5 ms            // TWC    Internal Write Cycle Time

    }

i = i + 32;          //erhöhen zu den nächten 32 Adressen, gehört zur 
While-Schleife
// CS high

10µs

// CS low
// WRDI  = 0x04 Reset the write enable latch  (disable write operations)
// CS high
2µs
}

von holger (Gast)


Lesenswert?

Wenn du schon mit delay arbeitest gehört das woanders hin:

for ( j = i; j < (i + 32) ; j++ ) //innere Schleife, die immer nur 32
Bytes durchzählen soll.
    {
    // 0xFF Data schreiben zum Löschen
    }

i = i + 32;          //erhöhen zu den nächten 32 Adressen, gehört zur
While-Schleife
// CS high

5ms


Der Programmiervorgang beginnt erst wenn du CS high ziehst!

von allu (Gast)


Lesenswert?

Christian S. schrieb:
> Es werden Adressen 0..32 beschrieben, Adressen
> 33..64 nicht, dann 65..96 beschrieben, usw.

0 .. 31  = 32 Bytes , 0 .. 32 sind aber 33 Bytes
32.. 63  = 32 Bytes
64 .. 95 = 32 Bytes

von Christian S. (roehrenvorheizer)


Lesenswert?

Hallo,


Danke für die beiden Hinweise. Die Wartezeit von 5 ms sollte tatsächlich 
erst kommen, NACHDEM CS auf 1 gegangen ist.
Die Sache mit den 0..32 Bytes war ein Schreibfehler von mir.

Das Programm läuft nun wie gewünscht.


Nur benötige ich den Write-disable-Befehl nun gar nicht. Seltsam.

Als Erweiterung lasse ich das WIP-Bit abfragen, das den Schreibvorgang 
anzeigt. Anbei mal der Schnipsel mit der Abfrage, den man an Stelle des 
delays einsetzen kann  (k ist eine uint8_t Variable):
(siehe 
http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=40425)

#ifdef WIP_Bit_abfragen
  do      //anstelle des delays einfach das Status-Bit abfragen, bis der 
Schreibvorgang beendet ist
  {
  _delay_us(2);
  PORTB &= ~(1 << CS_Pin_SPI_EEPROM);  // CS low
  SPI_MasterTransmit(0x05);    // RDSR  = Lesen des Status-Registers
  k = SPI_MasterTransmit(0x00);  //While the write is in progress, the 
STATUS register may be read to check the status of the WPEN, WIP, WEL, 
BP1, and BP0 bits
  PORTB |= (1 << CS_Pin_SPI_EEPROM);  // CS high
  }
  while ((k & 0x01) != 0);
#endif

#ifdef mit_delay
  _delay_ms(5);    // TWC  Internal Write Cycle Time, 2ms zu wenig, 3ms 
zu wenig, 4ms genug bei 5 Volt
#endif

Demnächst wird das ganze Programm in der Codesammlung zu finden sein.

mit freundlichem Gruß

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.