www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik ATmega128 + External Memory Interface


Autor: der mechatroniker (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen, habe ein interessantes Problem und wollte wissen, ob ich 
vielleicht irgendwo einen Denkfehler gemacht haben.

Zur Hardware:
- ATmega128, ext. Quarz mit 16 MHz
- 74HC373D als Adresslatch
- BS62LV1027S als RAM (ist ein 128K x 8, A16 ist auf Masse gelegt).

Nacheinander ein paar Werte schreiben und anschließend alle zurücklesen 
per Bitgewackel (mit deaktiviertem External Memory Interface) 
funktioniert problemlos, auch bei 16 MHz und ohne Delays (außer einem 
NOP zwischen !RD auf low ziehen und PINA einlesen im Lesezyklus, aber 
das liegt ja am Timing der GPIOs bei Atmel). Timing-Probleme halte ich 
daher für unwahrscheinlich.

Was ich natürlich eigentlich will, ist, daß sich der AVR um das SRAM 
kümmert.
Dafür habe ich eine Testroutine geschrieben. Der Compiler weiß nichts 
davon, ich kann also über einen Volatile-Pointer nach Herzenslust im 
betreffenden Adressbereich herumstochern.

So nun zu meinem Problem: Versuche ich das, so lese ich nur Müll.

Der Adressbereich, über den ich auf das externe SRAM zugreife, ist doch 
ab 0x1100, oder?

Zum Aktivieren des SRAMs verwende ich die folgende Init-Funktion:
void SetAutoSramConfig()
{
  // Externes SRAM durch uC-Hardware verwaltet
  // (betrifft Ports A, C und G)
  XMCRA = 0;            // Keine Wait states
  XMCRB = (1 << XMBK);  // Bus keeper aktiv, 16-Bittige Adressen
  MCUCR |= (1 << SRE) | (1 << SRW11) | (1 << SRW10);
              // SRAM aktivieren, viele Wait states
}

Mit der folgenden Testfunktion versuche ich erfolglos, 256 Bytes ab 
Adresse 0x100 im SRAM zu testen:
void Test_SRAM(char *pErrType, unsigned int *pErrAddr, unsigned char *pErrByte)
{
  volatile unsigned char *pSram = (volatile unsigned char *) 0x1100;
  volatile unsigned char *pByte;
  unsigned int i=0;
  unsigned char b;

  // Test mit Einsen (0xff)
  for (pByte=pSram, i=0; i<0x100; i++, pSram++)
    *pSram = 0xff;

  for (pByte=pSram, i=0; i<0x100; i++, pSram++) {
    if ((b = *pSram) != 0xff) {
      *pErrType = 2;
      *pErrAddr = i;
      *pErrByte = b;
      return;
    }
  }

  // Test mit Nullen
  for (pByte=pSram, i=0; i<0x100; i++, pSram++)
    *pSram = 0;

  for (pByte=pSram, i=0; i<0x100; i++, pSram++) {
    if ((b = *pSram) != 0) {
      *pErrType = 1;
      *pErrAddr = i;
      *pErrByte = b;
      return;
    }
  }


  // Test mit Bitmustern
  for (pByte=pSram, i=0; i<0x100; i++, pSram++)
    *pSram = (i & 0xff) ^ (i >> 8);
  
  for (pByte=pSram, i=0; i<0x100; i++, pSram++) {
    if ((b = *pSram) != ((i & 0xff) ^ (i >> 8))) {
      *pErrType = 3;
      *pErrAddr = i;
      *pErrByte = b;
      return;
    }
  }

  *pErrType = 0;
  *pErrAddr = 0;
  *pErrByte = 0;
}

Grüße
Sebastian

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
  for (pByte=pSram, i=0; i<0x100; i++, pSram++)
    *pSram = 0xff;

  for (pByte=pSram, i=0; i<0x100; i++, pSram++) {
    if ((b = *pSram) != 0xff) {
      *pErrType = 2;
      *pErrAddr = i;
      *pErrByte = b;
      return;
    }
  }

pSram wird nur hochgezählt, aber nicht
wieder auf die Startadresse gesetzt.

  for (pByte=pSram, i=0; i<0x100; i++, pByte++)
    *pByte = 0xff;

Autor: der mechatroniker (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Aua! Danke!

Autor: der mechatroniker (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jetzt klappts bis auf den dritten Test (den mit den Bitmustern). Dort 
lese ich für i=0 (also an Adresse 0x1100) statt einer 0x00 eine 0x18. 
Überleg gerade, ob ich tatsächlich einen Hardwarefehler gefunden habe 
oder ob in meiner Software immer noch der Wurm drin ist.

Werd die aktuelle Software heut abend nochmal posten, wenn ich sie von 
meinem Bastelrechner rüberkopiert hab. Muss jetzt weg.

Autor: der mechatroniker (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also jetzt wie versprochen der Code: Mein dritter Test lautet jetzt
  // Test mit Bitmustern
  for (pByte=pSram, i=0; i<0x100; i++, pByte++)
    *pByte = (i & 0xff) ^ (i >> 8);
  
  for (pByte=pSram, i=0; i<0x100; i++, pByte++) {
    if ((b = *pByte) != ((i & 0xff) ^ (i >> 8))) {
      *pErrType = 3;
      *pErrAddr = i;
      *pErrByte = b;
      return;
    }
  }

Das sollte es auch bei näherem Betrachten eigentlich tun. Also doch ein 
gefundenes Hardwareproblem?

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.