DRAM Interface für bis zu 128MByte an einem Mikrocontroller

Wenn man größere Datenmengen zwischenspeichern muss (z.B. von einer Festplatte), dann reicht der im Mikrocontroller integrierte Speicher von einigen Bytes bis max. 64kByte kaum aus. Mit dieser Schaltung kann man billige DRAM Speicher bis zu mehreren 100MByte verwenden.

Beim Ansteuern von DRAMs gibt es zwei Schwierigkeiten:
Das erste ist es der gemultiplexte Adressbus, das zweite der erforderliche Refresh alle 15us.
Für das erste gibt es mehrere Lösungen. In den ersten PC Mainboards wurde aus dem WR\ und RD\ Signal über eine Delay Line das Signal stufenweise verzögert und so alle Funktionen der Reihe nach ausgeführt. Der DRAM lässt sich wie ein SRAM ansteuern. Ich verwende dagegen eine andere Lösung: Da viele Mikrocontroller mit einem gemultiplexten arbeiten, wird vor der eigentlichen Datenübertragung bereits ein Taktsignal (meist als ALE bezeichnet) erzeugt. Dieses wird als RAS\ Signal verwendet um die Zeilenadresse im DRAM zu speichern. Wird nun WR\ oder RD\ aktiviert, werden die Adressmultiplexer umgeschaltet und legen die zweite Adresshälfte an das DRAM. Diese Spaltenadresse wird mit dem CAS\ Signal im DRAM gespeichert und die Daten werden (je nach Zustand von WE\) ausgegeben oder ins DRAM geschrieben. Mit dieser Schaltung lassen sich 8x 1MByte Speichermodule aus 386er und 486er verwenden. Mit einer kleinen Veränderung, lässt sich die Schaltung aber auch an 64k, 256k, 1MB, 4MB und 16MB Speicherbausteine anpassen. Mit 8x 16MB kommt man auf die maximalen 128MByte. Bei größeren Speicherbausteinen sind weitere Adressmultiplexer, Latches und Adressdekoder notwendig.
Nun das zweite Problem: Der Refresh. Dieses ist extrem einfach, da alle neueren DRAMs (ab 256kbit Speichern aufwärts, aber nicht bei allen 256kbit) über den CAS-before-RAS (kurz CBR) verfügen. Jedesmal wenn CAS\ vor RAS\ low wird, wird ein interner Zähler erhöht. Dieser dient als Adresse, die für den Refresh verwendet wird. Da bei 8051 Mikrocontrollern ALE bei jedem sechsten Takt aktiv ist, ist es leicht diesen Takt, der ja sowiso der RAS\ Takt ist, für den Refresh zu verwenden. Nur CAS\ muss vor RAS\ auf Low gelegt werden. Dazu wird es mit der low-high Flanke des ALE Signals synchronisiert, so dass CAS\ (für den CBR) nur dann verändert wird, wenn RAS\ high ist.
Diese Schaltung funktioniert einwandfrei. Es gibt zwar ein paar Speichermodule, bei denen einige Daten fehlerhaft sind, aber dies sind die wenigsten. Aber selbst professionelle Schaltungen haben solche Probleme: Von 8 Speichermodulen funktionieren bei meinem Laserdrucker 2 stück. Ich hatte anfangs das ALE Signal in verdacht, da RAS\ bei 70ns DRAMs mindestens 50ns High sein muss (RAS\ Precharge Time), und der 8051 uC mit 22,1184MHz laut Datenblatt nur 40ns Impulsbreite erzeugt, aber all diese Werte sind worst-case Angaben, und die Impulsbreite des 8051 liegt in der Praxis bei etwa 70ns.

Bei der Programmierung muss man nichts weitere beachten, da der DRAM wie jeder normale SRAM angesteuert wird. Man sollte nur öfters als 5-20 mal pro Sekunde das Refresh Bit kurz auf Low setzen, damit der Speicher aufgefrischt wird. Bei 22,1184MHz Takt wird RAS\ mit 1,8432MHz getaktet, so dass etwa 0,5ms für einen kompletten Refresh notwendig sind. Vor jedem Datentransfer muss das Refresh Bit wieder auf high gesetzt werden, sonst funktioniert der Datentransfer nicht.

Um die Ansteuerung zu überpüfen, habe ich die Signale mit einem selbstgebauten 32MS/s Logik Analyser aufgezeichnet. Dies ist ein Ausschnitt vom Datentransfer zwischen einer Compactflash Karte und dem DRAM. Da die Karte mit 16bit arbeitet werden imme 2 Werte gelesen und dann ins DRAM geschrieben. Die Signale RAS\, CAS\ und WE\ sind direkt vom Speichermodul entnommen. OE\ wird nur dazu benötigt, um das CE\ Signal in Form des CAS\ Signals zu erzeugen. En\ wird aus WE\ und OE\ erzeugt (Pin6 von IC5B). Da das DRAM nur die unteren 32kB des Adressraums belegt, wird nur dann ein CAS\ erzeugt, wenn A15 Low ist. Ist A15 High, dann handelt es sich um einen IO Transfer, (hier z.B. von der CF Karte). CASD\ ist das CAS\ Signal vor der Vermischung mit dem Refresh CAS\ Signal, an Pin15 von IC2. Dieses dient hier hauptsächlich als Triggerung für die Datenaufzeichnung.
Wenn man sich die Signale anschaut dann erkennt man, dass alles den DRAM Spezifikationen entspricht. Das einzige Signal, das an der Grenze ist, ist die High-Impulsbreite des RAS\ bzw ALE Signals.

Etwa 90% aller Speichermodule haben 1MByte. Es sind aber auch 256kByte, 4MByte oder (ganz selten, da damals unbezahlbar) 16MByte. Ich wollte ausprobieren, was passiert wenn ich ein 256kByte Modul verwendet. Normalerweise würde ein Bereich 4 mal beschrieben werden, und so die Daten fehlerhaft sein. Aber es passierte was anderes: Nach einigen Sekunden hängte sich der uC auf ! Oder nach dem dem Reset passierte nichts, der uC fing nichtmal an zu arbeiten ! Dies liegt an dem unüblichen Enhanced Page Mode, bei dem die Ausgänge aktiv werden, wenn RAS\ auf Low geht. Dann arbeiten die CAS\ Latches als transparent Latches, d.h. CAS\ ist high: an A0-8 anliegende Adresse wird verwendet, CAS\ geht auf Low: Adresse wird gespeichert, CAS\ ist low: die beim High-Low Übergang gespeicherte Adresse bleibt aktiv.

Irgenwann werde ich diese Schaltung in einen FPGA, CPLD o.ä. packen, um den Aufwand etwas zu reduzieren. Immerhin benötigt die Schaltung im Moment 8 HCMOSs.

Pin
Bezeichnung
1
+5V
2
CAS\
3
D0
4
A0
5
A1
6
D1
7
A2
8
A3
9
GND
10
D2
11
A4
12
A5
13
D3
14
A6
15
A7
16
D4
17
A8
18
A9
19
A10
20
D5
21
WE\
22
GND
23
D6
24
A11
25
D7
26
Parity Dout
27
RAS\
28
Parity CAS\
29
Parity Din
30
+5V

 

Zurück