Forum: Mikrocontroller und Digitale Elektronik ATmega128 + External Memory Interface


von der mechatroniker (Gast)


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:
1
void SetAutoSramConfig()
2
{
3
  // Externes SRAM durch uC-Hardware verwaltet
4
  // (betrifft Ports A, C und G)
5
  XMCRA = 0;            // Keine Wait states
6
  XMCRB = (1 << XMBK);  // Bus keeper aktiv, 16-Bittige Adressen
7
  MCUCR |= (1 << SRE) | (1 << SRW11) | (1 << SRW10);
8
              // SRAM aktivieren, viele Wait states
9
}

Mit der folgenden Testfunktion versuche ich erfolglos, 256 Bytes ab 
Adresse 0x100 im SRAM zu testen:
1
void Test_SRAM(char *pErrType, unsigned int *pErrAddr, unsigned char *pErrByte)
2
{
3
  volatile unsigned char *pSram = (volatile unsigned char *) 0x1100;
4
  volatile unsigned char *pByte;
5
  unsigned int i=0;
6
  unsigned char b;
7
8
  // Test mit Einsen (0xff)
9
  for (pByte=pSram, i=0; i<0x100; i++, pSram++)
10
    *pSram = 0xff;
11
12
  for (pByte=pSram, i=0; i<0x100; i++, pSram++) {
13
    if ((b = *pSram) != 0xff) {
14
      *pErrType = 2;
15
      *pErrAddr = i;
16
      *pErrByte = b;
17
      return;
18
    }
19
  }
20
21
  // Test mit Nullen
22
  for (pByte=pSram, i=0; i<0x100; i++, pSram++)
23
    *pSram = 0;
24
25
  for (pByte=pSram, i=0; i<0x100; i++, pSram++) {
26
    if ((b = *pSram) != 0) {
27
      *pErrType = 1;
28
      *pErrAddr = i;
29
      *pErrByte = b;
30
      return;
31
    }
32
  }
33
34
35
  // Test mit Bitmustern
36
  for (pByte=pSram, i=0; i<0x100; i++, pSram++)
37
    *pSram = (i & 0xff) ^ (i >> 8);
38
  
39
  for (pByte=pSram, i=0; i<0x100; i++, pSram++) {
40
    if ((b = *pSram) != ((i & 0xff) ^ (i >> 8))) {
41
      *pErrType = 3;
42
      *pErrAddr = i;
43
      *pErrByte = b;
44
      return;
45
    }
46
  }
47
48
  *pErrType = 0;
49
  *pErrAddr = 0;
50
  *pErrByte = 0;
51
}

Grüße
Sebastian

von holger (Gast)


Lesenswert?

1
  for (pByte=pSram, i=0; i<0x100; i++, pSram++)
2
    *pSram = 0xff;
3
4
  for (pByte=pSram, i=0; i<0x100; i++, pSram++) {
5
    if ((b = *pSram) != 0xff) {
6
      *pErrType = 2;
7
      *pErrAddr = i;
8
      *pErrByte = b;
9
      return;
10
    }
11
  }

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

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

von der mechatroniker (Gast)


Lesenswert?

Aua! Danke!

von der mechatroniker (Gast)


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.

von der mechatroniker (Gast)


Lesenswert?

Also jetzt wie versprochen der Code: Mein dritter Test lautet jetzt
1
  // Test mit Bitmustern
2
  for (pByte=pSram, i=0; i<0x100; i++, pByte++)
3
    *pByte = (i & 0xff) ^ (i >> 8);
4
  
5
  for (pByte=pSram, i=0; i<0x100; i++, pByte++) {
6
    if ((b = *pByte) != ((i & 0xff) ^ (i >> 8))) {
7
      *pErrType = 3;
8
      *pErrAddr = i;
9
      *pErrByte = b;
10
      return;
11
    }
12
  }

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

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.