www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik SPI EEProm Hilfe gesucht


Autor: TobyTetzi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich nutze einen SPI EEProm, M95256 von ST, an einem ATmega8.

Nun habe ich folgendes Problem:

Ich beschreibe mit folgender C Routine den EEProm mit Daten, die er UART 
rein kommen:

// Definition der Leds
//#define ANZAHL_LEDS 8
//#define ANZAHL_LEDS 16
//#define ANZAHL_LEDS 24
//#define ANZAHL_LEDS 32
//#define ANZAHL_LEDS 40
#define ANZAHL_LEDS 48
//#define ANZAHL_LEDS 56
//#define ANZAHL_LEDS 64

// Definition der Bytes pro Spalte
#define ANZAHL_BYTES  ( ANZAHL_LEDS / 8 )

void Write_SPI_EEProm (void){

BYTE HighAdress = 0;
BYTE LowAdress = 0;
BYTE Daten[ANZAHL_BYTES];
BYTE i = 0;

while(RxBufferStatus()==0);
myReceivedByte = RxBufferLesen();
if(myReceivedByte==':'){

  while(RxBufferStatus()==0);
    HighAdress = RxBufferLesen();
  while(RxBufferStatus()==0);
    LowAdress = RxBufferLesen();

  for( i = 0; i < ANZAHL_BYTES; ++i ) {
    while(RxBufferStatus()==0);
    Daten[i] = RxBufferLesen();
  }


  //status = Read_EEProm_Status();
  //if ( status == 0b00000000 ){
  //while(Read_EEProm_Status()!=0);
  //while(Read_EEProm_Status()!=0);

  cbi(PORTB,0);
  spiTransferByte(0b00000110);//write enable WREN
  sbi(PORTB,0);
  cbi(PORTB,0);
  spiTransferByte(0b00000010);//write command
  spiTransferByte(HighAdress);//high adresse
  spiTransferByte(LowAdress);  //low adresse

  for( i = 0; i < ANZAHL_BYTES; ++i )
    spiTransferByte( Daten[i] );

  sbi(PORTB,0);

  nop;nop;nop;nop;nop;

  // Write disable
  cbi(PORTB,0);
  spiTransferByte(0b00000100);//write disable WRDI
  sbi(PORTB,0);

  nop;nop;nop;nop;nop;

while(RxBufferStatus()==0);
myReceivedByte = RxBufferLesen();
if(myReceivedByte==';'){

  //Bestätigung schicken
  TxDatenSenden('O');

    }
  }
}

Mit folgender Routine lese ich den EEProm aus, und sende die Daten per 
UART an den PC:

void Read_SPI_EEProm (void){

BYTE HighAdress = 0;
BYTE LowAdress = 0;
BYTE Daten[ANZAHL_BYTES];
BYTE i = 0;

while(RxBufferStatus()==0);
myReceivedByte = RxBufferLesen();
if(myReceivedByte==':'){

  while(RxBufferStatus()==0);
  HighAdress = RxBufferLesen();
  while(RxBufferStatus()==0);
  LowAdress = RxBufferLesen();

  //status = Read_EEProm_Status();
  //if ( status == 0b00000000 ){
  //while(Read_EEProm_Status()!=0);

  cbi(PORTB,0);
  spiTransferByte(0b00000011);  //read command
  spiTransferByte(HighAdress);  //high adresse
  spiTransferByte(LowAdress);  //low adresse

  for( i = 0; i < ANZAHL_BYTES; ++i ){
  Daten[i] = spiTransferByte(0b00000000);
    }

  sbi(PORTB,0);

while(RxBufferStatus()==0);
myReceivedByte = RxBufferLesen();
if(myReceivedByte==';'){

  //Daten mit "D" ankündigen, PC wartet, bis "D" kommt
  TxDatenSenden('D');

  for( i = 0; i < ANZAHL_BYTES; ++i )
   TxDatenSenden( Daten[i] );

   }
  }
}

Nun klappt Alles so weit ganz gut.
Das PC Programm erstellt mir eine Datei, mit den Daten : Highadresse, 
Lowadresse, EEPromDaten.
Allerdings bekomme ich Fehler, wenn ich 3,5,6,7 Bytes pro Adresse 
schreibe.
(Das ich umgekehrt lese, wie schreibe, abe ich schon bemerkt!)

Bei 2 Bytes pro Adresse sieht die Datei des PC Programms beispielweise 
so aus (EEPromdaten = 0xFF,0x00):

Schreiben:
W: 0 0 (ÿ );
W: 0 2 (ÿ );
W: 0 4 (ÿ );
W: 0 6 (ÿ );
W: 0 8 (ÿ );
W: 0 10 (ÿ );
W: 0 12 (ÿ );
W: 0 14 (ÿ );
W: 0 16 (ÿ );
W: 0 18 (ÿ );
W: 0 20 (ÿ );
W: 0 22 (ÿ );
W: 0 24 (ÿ );
...
...

Lesen:
R: 0 0 ( ÿ);
R: 0 2 ( ÿ);
R: 0 4 ( ÿ);
R: 0 6 ( ÿ);
R: 0 8 ( ÿ);
R: 0 10 ( ÿ);
R: 0 12 ( ÿ);
R: 0 14 ( ÿ);
R: 0 16 ( ÿ);
R: 0 18 ( ÿ);
R: 0 20 ( ÿ);
R: 0 22 ( ÿ);
R: 0 24 ( ÿ);
...
...

Nun aber bei 6 Bytes bekomme ich folgendes:
(EEPromdaten = 0xFF,0x00,0x00,0x00,0x00,0x00)

Schreiben:
W: 0 0 (ÿ     );
W: 0 6 (ÿ     );
W: 0 12 (ÿ     );
W: 0 18 (ÿ     );
W: 0 24 (ÿ     );
W: 0 30 (ÿ     );
W: 0 36 (ÿ     );
W: 0 42 (ÿ     );
W: 0 48 (ÿ     );
W: 0 54 (ÿ     );
W: 0 60 (ÿ     );
W: 0 66 (ÿ     );
W: 0 72 (ÿ     );
W: 0 78 (ÿ     );
W: 0 84 (ÿ     );
W: 0 90 (ÿ     );
W: 0 96 (ÿ     );
W: 0 102 (ÿ     );
W: 0 108 (ÿ     );
W: 0 114 (ÿ     );
W: 0 120 (ÿ     );
W: 0 126 (ÿ     );
W: 0 132 (ÿ     );
W: 0 138 (ÿ     );
W: 0 144 (ÿ     );
W: 0 150 (ÿ     );
W: 0 156 (ÿ     );
W: 0 162 (ÿ     );
W: 0 168 (ÿ     );
W: 0 174 (ÿ     );
W: 0 180 (ÿ     );
W: 0 186 (ÿ     );
W: 0 192 (ÿ     );
W: 0 198 (ÿ     );
W: 0 204 (ÿ     );
W: 0 210 (ÿ     );
W: 0 216 (ÿ     );
W: 0 222 (ÿ     );
W: 0 228 (ÿ     );
W: 0 234 (ÿ     );
W: 0 240 (ÿ     );
W: 0 246 (ÿ     );
W: 0 252 (ÿ     );
W: 1 2 (ÿ     );
...
...

Lesen:
R: 0 0 (      );   ??????Wo sind die Daten hin?????
R: 0 6 (     ÿ);
R: 0 12 (     ÿ);
R: 0 18 (     ÿ);
R: 0 24 (     ÿ);
R: 0 30 (     ÿ);
R: 0 36 (     ÿ);
R: 0 42 (     ÿ);
R: 0 48 (     ÿ);
R: 0 54 (     ÿ);
R: 0 60 (     ÿ);
R: 0 66 (      );   ??????Wo sind die Daten hin?????
R: 0 72 (     ÿ);
R: 0 78 (     ÿ);
R: 0 84 (     ÿ);
R: 0 90 (     ÿ);
R: 0 96 (     ÿ);
R: 0 102 (     ÿ);
R: 0 108 (     ÿ);
R: 0 114 (     ÿ);
R: 0 120 (     ÿ);
R: 0 126 (   ð ÿ);   ??????Was sind das für Daten?????
R: 0 132 (     ÿ);
R: 0 138 (     ÿ);
R: 0 144 (     ÿ);
R: 0 150 (     ÿ);
R: 0 156 (     ÿ);
R: 0 162 (     ÿ);
R: 0 168 (     ÿ);
R: 0 174 (     ÿ);
R: 0 180 (     ÿ);
R: 0 186 (     ÿ);
R: 0 192 (      );   ??????Wo sind die Daten hin?????
R: 0 198 (     ÿ);
R: 0 204 (     ÿ);
R: 0 210 (     ÿ);
R: 0 216 (     ÿ);
R: 0 222 (     ÿ);
R: 0 228 (     ÿ);
R: 0 234 (     ÿ);
R: 0 240 (     ÿ);
R: 0 246 (     ÿ);
R: 0 252 (     ÿ);
R: 1 2 (      );   ??????Wo sind die Daten hin?????
...
...

Woran kann das liegen?
Hat es etwa etwas mit dem PageWrite des EEProms zu tun?
Liegt es nun am Schreiben, oder am Lesen?

Für etwas Hilfe wäre ich sehr dankbar!

Gruß Toby

Autor: TobyTetzi (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

anliegend ist nochmal das Datenblatt zum besagten EEProm.

Gruß Toby

Autor: TobyTetzi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo nochmal,

weiß denn wirklichkeiner einen Rat?

Gruß Toby

Autor: Florian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du musst immer, wenn Du eine Page-Grenze erreichts, neu ansetzen. So 
verstehe ich zumindest das Datenblatt:

If the number of data bytes sent to
the device exceeds the page boundary, the internal
address counter rolls over to the beginning of
the page, and the previous data there are overwritten
with the incoming data. (The page size of
these devices is 64 bytes).

Bist Du außerdem sicher, dass Du die Timings korrekt beachtest?

Autor: TobyTetzi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Florian,

danke für deine Antwort.
ich habe mir so etwas mit der Page schon gedach, allerdings das 
Datenblatt nicht ganz verstanden.

Also, teile ich die 64 Byte pro Page durch meine zu schreibendnen Bytes, 
muß es immer eine Ganzzahl ergeben:

64/2 = 32       geht, wenn ich immer 2 Bytes schreibe.
64/3 = 21,33333 geht nicht, wenn 3 Bytes schreibe.
64/4 = 16       geht, wenn ich immer 4 Bytes schreibe.
64/5 = 12,8     geht nicht, wenn 5 Bytes schreibe.
64/6 = 10,6666  geht nicht, wenn 6 Bytes schreibe.
64/7 = 9,142    geht nicht, wenn 7 Bytes schreibe.
64/8 = 8        geht, wenn ich immer 8 Bytes schreibe.

Das mit dem Timing sollte hin hauen, da es ja bei 2,4 und 8 Bytes geht.

Wo gäbe es denn verbesserungen an meinem Code?

Gruß Toby



Autor: Magnus Müller (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du kannst immer nur innerhalb eines 64Bit-Blocks schreiben.

Zu schreiben sind jeweils 1 bis 64 Bytes.

Man kann auch mehr als 64 Bytes auf einmal schicken, es werden aber nur 
die letzten 64 Bytes geschrieben.

Initiiert man einen Schreibvorgang an Adresse 63(dez.) und gibt dem 
EEPROM zwei zu schreibende Bytes (z.B. 0xAA und 0x55) mit, so wird 
0xAA an Adresse 63 und 0x55 an Adresse 0(!) abgelegt.

Autor: TobyTetzi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Magnus,

daher kommt es auch, das ich hier:

Lesen:
R: 0 0 (      );   ??????Wo sind die Daten hin?????
R: 0 6 (     ÿ);
R: 0 12 (     ÿ);

Das ich in Adresse 0 nichts mehr habe,
da ich ja hier:

W: 0 54 (ÿ     );
W: 0 60 (ÿ     );
W: 0 66 (ÿ     );

bei Adresse 0 60 (dez) 6 bytes schreiben will.
Beim 3. byte bin ich ja schon an Adresse 0 63 (dez),
also wird das 4. byte nicht in Adresse 0 64,
sondern am Anfang dieser Page, Adresse 0 0 gespeichert.
Ich müsste also nach insgesammt 64 geschriebenen Bytes (ab Adresse 0 0) 
wieder einen Schreibvorgang starten, der bei Page 2, also Adresse 0 64 
(dez) beginnt.

Oder nochmal anders gesagt, ich darf, wenn ich mehrere bytes ab einer 
bestimmten Adresse schreiben will, nie die Pagegrenze überschreiten.

Ok, dann muß ich mein VB Programm ändern.

Danke und Gruß Toby

Autor: Magnus Müller (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bitteschön ;) und weiterhin gutes Gelingen!

Gruß,
Magnetus

[Edit]

P.S.:  Der entscheidende Hinweis kam von Florian (Gast). Ich hab
       nichts anderes getan, als ein kleines Beispiel zu nennen.

       --> Vielen Dank an Florian (Gast)

Autor: TobyTetzi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Oh, ein Fehler, sorry.
Es muß nicht das 3. byte bei Adresse 63 heißen, es ist ja schon das 4. 
byte.

W: 0 60 (123456);

Ich müßte also, um das 5. und 6. Byte zu schreiben, einen neuen 
Schreibvorgang starten.



Noch eine Frage, ist es beim lesen auch so????

Gruß Toby

Autor: Magnus Müller (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
TobyTetzi wrote:
> Oh, ein Fehler, sorry.
> Es muß nicht das 3. byte bei Adresse 63 heißen, es ist ja schon das 4.
> byte.
>
> W: 0 60 (123456);
>
> Ich müßte also, um das 5. und 6. Byte zu schreiben, einen neuen
> Schreibvorgang starten.
>
>
>
> Noch eine Frage, ist es beim lesen auch so????
>
> Gruß Toby

Siehe Datenblatt Seite 17.

Beim Lesen gibt es die Page-Beschränkung nicht. Ein fortlaufender 
Lesevorgang wird nur durch die Speichergröße (im konkreten Fall 32KB) 
begrenzt. Erreichst du beim fortlaufenden Lesen das Speicherende 
(Adresse 0x7FFF), so erhältst du mit den nächsten Bytes die Inhalte der 
Adressen 0x0000, 0x0001 usw.

Gruß,
Magnetus

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.