PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Timing für SRAM 62256 (32k x 8) gesucht



vklaffehn
06.05.2007, 14:53
Moin allerseits!
Mittlerweile habe ich es doch hinbekommen, mein SRAM an einen Mega32 zu hängen, allerdings hab ich nun noch ein kleines Problem, ich vermute mit dem Timing. Zu Testzwecken habe ich eine kleine Routine geschrieben, die einfach einen Wert schreibt und anschließend wieder ausliest. Aber leider scheint das Schreiben gelegentlich fehlzuschlagen, sprich, ich schreibe an jede Speicherstelle eine '0' und lese anschließend das ganze aus, dann hab ich in den 32K so ca. 10 falsche Bytes, wiederhole ich den Spaß ein paar mal, werden die Fehler immer weniger.
Durch ändern der Timings kann ich die Fehlerrate ändern (ich habe im Moment zwischen jeder Pinänderung eine Verzögerung mit _delay_us() eingebaut), aber selbst wenn ich eine Verzögerung im ms-Bereich nehme, tauchen Fehler auf. Hat jemand einen Tipp. wo das Timing von so einem SRAM ausführlich beschrieben ist?
Danke schonmal!!

kalledom
06.05.2007, 15:29
Hallo,
auf dem SRAM sollte nach dem xxx 62256 noch eine Zahl stehen, die Zugriffszeit wie z.B. 70 = 70 ns oder 120 = 120ns oder 12 = 120ns.
µs oder ms gibt's nicht mehr, das sind Ewigkeiten.
Da stimmt im Ablauf der Ansteuerung was nicht.
Zum Lesen:
1. Adresse anlegen
2. Chip Select anlegen (oder immer auf GND)
3. RD-Signal auf Low
4. nach der Zugriffszeit Daten vom Bus einlesen
5. RD-Signal auf High

Zum Schreiben:
1. Adresse anlegen
2. Daten anlegen (kann zusammen mit der Adresse angelegt werden)
3. Chip Select anlegen (oder immer auf GND)
4. WR-Signal auf Low
5. nach der Zugriffszeit WR-Signal auf High

Das Umschalten der I/O-Pins zum Lesen = Eingänge oder Schreiben = Ausgänge nicht vergessen.

vklaffehn
06.05.2007, 15:57
Hallo!
Das RAM hat 80ns Zugriffszeit, da kann ich ja eigentlich mit meinem händischen Protokoll gar nicht zu schnell werden...
Die Verzögerungen habe ich nur zum Debuggen eingebaut.

Folgendermaßen verdrahtet:

PORTA an 2 Latches 74hc573n und an I1-I8 vom RAM
Ausgänge der Latches an A0-A14, und CS vom RAM
PB0 an Latch LE für A0-A7, OE vom Latch auf GND
PB1 an Latch LE für A8-A15, OE vom Latch auf GND
PB2 an WE vom RAM
PB3 an OE vom RAM


Das Lesen aus dem SRAM funktioniert auch wunderbar ohne irgendwelche Verzögerungen. Inzwischen habe ich auch eine art Verify eingebaut, wo er den grad geschriebenen Wert auslesen und bei Nichtübereinstimmung nochmal schreiben soll, aber irgendwie klappt das nicht. Die falschen Werte stehen auch immer mal woanders und variieren in der Anzahl...

hier der Code :


#include <memory.h>
#include <util/delay.h>
#define r 1
#define w 5

void initinterface(unsigned char value)

{
// unsigned int addr;
DDRA=0;
PORTA=0;
DDRB |= 15;
PORTB |= (1<<WE);
PORTB |= (1<<OE);
PORTB &= ~(1<<LE_low);
PORTB &= ~(1<<LE_high);

/* for (addr=0;addr<65535;addr++)
{
writemem(addr,value);
}
*/
}

void writemem(unsigned int addr, unsigned char value)
{
unsigned char check;

PORTB |= (1<<WE); //WE auf high
PORTB |= (1<<OE); //OE auf high

DDRA=0xff; //PORTA als Ausgang

PORTA = (addr >> 8); //Highbyte der Adresse ausgeben
PORTB |= (1<<LE_high); //Latch 1 input enable
_delay_us(w);
PORTB &= ~(1<<LE_high); //Latch 1 input disable
_delay_us(w);
PORTA = (addr & 255); //Lowbyte der Adresse ausgeben
_delay_us(w);
PORTB |= (1<<LE_low); //Latch 2 input enable
_delay_us(w);
PORTB &= ~(1<<LE_low); //Latch 2 input disable
_delay_us(w);
PORTB &= ~(1<<WE); //WE auf low
_delay_us(w);
PORTA = value; //Daten ausgeben
_delay_us(w);
PORTB |= (1<<WE); //WE auf high
_delay_us(w);

// check
do
{
DDRA = 0;
PORTA = 0;
PORTB &= ~(1<<OE); //OE auf low
_delay_us(w);
check = PINA; //Daten lesen nach 'value'
_delay_us(w);
PORTB |= (1<<OE); //OE auf high

if (check != value)
{
DDRA=0xff;
PORTB &= ~(1<<WE); //WE auf low
_delay_us(w);
PORTA = value; //Daten ausgeben
_delay_us(w);
PORTB |= (1<<WE); //WE auf high
_delay_us(w);
}
}
while (check != value);

}

unsigned char readmem(unsigned int addr)
{
unsigned char value;

PORTB |= (1<<WE); //WE auf high
PORTB |= (1<<OE); //OE auf high

DDRA=0xff; //PORTA als Ausgang

PORTA = (addr >> 8 ); //Highbyte der Adresse ausgeben
PORTB |= (1<<LE_high); //Latch 1 input enable
// _delay_us(r);
PORTB &= ~(1<<LE_high); //Latch 1 input disable
// _delay_us(r);
PORTA = (addr & 255); //Lowbyte der Adresse ausgeben
PORTB |= (1<<LE_low); //Latch 2 input enable
// _delay_us(r);
PORTB &= ~(1<<LE_low); //Latch 2 input disable
_delay_us(r);
DDRA = 0;
PORTA = 0;

PORTB &= ~(1<<OE); //OE auf low
_delay_us(r);
value = PINA; //Daten lesen nach 'value'
PORTB |= (1<<OE); //OE auf high
_delay_us(r);
return value;
}

kalledom
06.05.2007, 16:13
Ich kann / mag zwar kein C, sehe aber die Reihenfolge:
- WE auf low
- Daten ausgeben
- WE auf high
Die richtige Reihenfolge hatte ich im ersten Beitrag bereits angegeben:
- Daten ausgeben
- WE auf low
- WE auf high

Zum Einlesen ist die Reihenfolge richtig.

vklaffehn
06.05.2007, 16:47
Hallo!
Danke für's rüberschauen!
Oh, die Reihenfolge hatte ich zwischendurch geändert, um den Fehler einzugrenzen und das ganze so in meinem Datenblatt steht. Vorher hatte ich es richtig herum, also Adresse anlegen, Daten anlegen, WE auf LOW, WE auf HIGH, leider trat mein Fehler da auch schon auf....
Hmm, noch eine schlaue Idee?

MfG Volker

kalledom
06.05.2007, 16:54
Sind Keramik-Kondensatoren 100...220nF unmittelbar an Vcc und GND des SRAM ?
Evtl. noch einen an den D-Latch's ?

vklaffehn
06.05.2007, 16:57
Hallo!
Ups.... nö....

hab ich total vergessen :-) Hab nur einen am Controller....
Das werd ich bei gelegenheit versuchen, im Moment hänge ich grad erstmal woanders fest.

Danke für den Tipp!!

MfG Volker

vklaffehn
06.05.2007, 19:06
So, jetzt hängt auch ein Kondensator dran, allerdings passiert immer noch genau das gleiche. Und wenn ich in der Leseroutine nach dem OE=LOW kein _delay_us(1) habe, dann lese ich nicht die Daten aus dem RAM, sondern das zuletzt angelegte Adressbyte... Sind evtl. die Latches zu langsam?
Der Mega32 läuft übrigens mit 16MHz.
Ich hab auch noch ein anderes merkwürdiges Problem mit dem RAM, dazu stell ich gleich nochmal ein wenig Code und zwi 'Screenshots' ein.
Vorab schonmal :
Ich lese Bilddaten einer GB_CAM, die an einem Tiny26 hängt, blockweise ein, immer 16 Bytes pro Block, schubse ich die Daten gleich per RS232 auf den PC in mein kleines Anzeigetool, dann krieg ich ein schönes Bild, schreibe ich die Daten aber erstmal ins RAM und sende sie anschließend aus dem RAM, sieht es so aus, als würde in X-Richtung eine Art Pixelverdoppelung auftreten, wie gesagt, Bildchen kommen noch, muß nur grad erstmal was essen!!

vklaffehn
06.05.2007, 20:18
So, ich hab das ganze mal im GCC-Forum fortgesetzt, ich weiß nicht, ob es ein Software oder Hardwareproblem ist....

MfG Volker

kalledom
06.05.2007, 22:24
Das sieht jetzt aber mehr nach einem Software-Problem aus, wenn Du beim Lesen statt der Daten die Adresse zurück bekommst.
Die Latch's können nicht zu langsam sein, selbst die langsamen CMOS-Typen sind 50ns schnell. Da ist der Mega32 selbst bei 20MHz viel zu langsam.
Ich tippe auf einen Fehler beim Umschalten auf Eingang / Ausgang ?

PS: Ich lege immer erst die Daten an das Port und schalte dann das Port auf Ausgang.
Wird zuerst das Port auf Ausgang geschaltet, liegt das letzte Bit-Muster an den Ausgangspins; dann wird das neue Bit-Muster ausgegeben
Daraus ergeben sich unnötige Bus-Aktivitäten.

vklaffehn
06.05.2007, 22:36
Hmmm, alles sehr seltsam....
Ich setze die Adresse, setzt den Port auf Eingang, schreibe eine 0 nach PORTA, setze OE und lese den Eingangsport....

Und nach einem Schreibzugriff schalte ich den Port immer wieder als Eingang und schreib 0 nach Porta...

wenn ich die Reihenfolge beim Adresse anlegen (also Lowbyte zuerst und dann Highbyte) vertausche, krieg ich ohne Verzögerung immer ganz sauber das Highbyte gelesen, das gibt in meinem Bildanzeigeprogramm auf dem PC einen schicken Verlauf von Schwarz nach Grau ;-)

Also langsam dreh ich am RAD......

kalledom
07.05.2007, 09:40
Warum schaltest Du das Port immer wieder auf Eingang und schreibst dann auch noch eine 0 rein ?
Laß das Daten-Port nach Verlassen einer Aktion doch so wie es ist.
Die Steuerleitungen müssen natürlich so gesetzt sein, daß z.B. OE vom SRAM auf High ist, damit keine Daten auf den Bus gelangen.
WR und LE müssen ebenfalls High sein ..... LE .... High ??? NEIN; LE muß Low sein, weil bei High alles von den Latchs übernommen wird, was auf dem Bus ist. Der 573 ist nicht flanken-getriggert !!!

In meinem Assembler-Programm setze ich ein Flag, wenn Port = Ausgang ist und lösche dieses Flag, wenn Port = Eingang.
In meiner Schreib-Routine prüfe ich das Richtungs-Flag und schalte ggf. erst das Port auf Ausgang um, bei meiner Lese-Routine das Gleiche in grün.
Bei mir sind es allerdings nur 5 Adress-Leitungen auf PORTD bei einem PIC16F877; die Datenleitungen führen zu 4 x 4 x 74HC573 mit nachfolgenden LEDs und Relais, sowie zu 4 x 4 x 74HC541 zur Abfrage von (Kontakt-)Zuständen.

vklaffehn
07.05.2007, 10:52
Hallo!

Hab mich evtl etwas missverständlich ausgedrückt:

Der Ablauf sieht folgendermaßen aus :

OE und WE auf high, LE1 und LE2 auf low

schreiben:

PORTA auf Ausgang schalten
Lowbyte ausgeben
LE1 high
LE1 low
Highbyte ausgeben
LE2 high
LE2 low
Daten ausgeben
WE low
WE high

PORTA auf Eingang
Null schreiben (schaltet Pullups aus)

lesen:

PORTA auf Ausgang
lowbyte ausgeben
LE1 high
LE1 low
highbyte ausgeben
LE2 high
LE2 low
PORTA als Eingang
PORTA 0 schreiben (schaltet Pullups aus)
OE low
Daten von PINA lesen
OE high

eeeigentlich sollte das doch so gehen, oder nicht??

könnten evtl. Pulldownwiderstände an PORTA helfen??

MfG Volker

vklaffehn
20.05.2007, 20:55
Moin!
Ich habe bezüglich meines Problems hier mal einige Tests durchgeführt und recherchiert :

1. Selbst wenn ich den Meg32 mit 1 MHz laufen lasse und zwischen jeder (!!!) Poränderung eine ms warte habe ich immer noch Fehler....

Aber nun meine Frage : meine Latches sind 74HC573, also CMOS typen, leigt da evtl das Problem? Besser wären doch bestimmt LS oder HCT....
Oder seh ich das falsch? Leider sind meine Elektronikkenntnisse etwas beschränkt, was denn nun genau den Unterschied zwischen TTL und CMOS ausmacht, also was es für Folgen hat, wenn man mit TTL z.B. auf einen CMOS Eingang geht, der einen CMOS Ausgang schaltet, der jetzt aber wieder einen TTL Eingang schalten soll?

/edit: oder lieber gleich 74LS373 nehmen? Mir erschließt sich grad der Unterschied zwischen dem '573 und dem '373 nicht, trotz Datenblattstudium..


Fragen über Fragen....

MfG Volker

kalledom
20.05.2007, 23:37
CMOS sollte schon ok sein, denn der Mega32 ist sicher auch ein CMOS-Bauteil.
Zwischen 573 und 373 gibt es einen sehr wesentlichen Unterschied:
beim 573 sind die Eingänge auf der einen und die Ausgänge auf der anderen Seite, beim 373 ist es etwas 'durcheinander'.
Probier doch mal HCT und LS aus. Es wird Dich kostenmäßig sicherlich nicht ruinieren und die Erfahrung ist unbezahlbar.

Hatten wir eigentlich schon über 100nF Keramik-Kondensatoren am µC und SRAM gesprochen ? Diese 80ns-Dinger schalten recht schnell und hinterlassen 'Spuren' auf der Versorgungsspannung. Das stört schon mal die eine oder andere benachbarte Speicherstelle :-)

vklaffehn
21.05.2007, 08:11
Moin!
Müssen das unbedingt Keramikkondensatoren sein? Ich habe erstmal diese kleinen roten (Folienkondensatoren?) verbraucht...
Muß ich mal einen Schwung KerKos mitbestellen. Außerdem werd ich es mal mit den HCT probieren, die LS scheint Reichelt nicht zu haben....
Und dann werd ich ÜBERALL Kondensatoren dranfrickeln!!!!!!!

Und Danke für den Hinweis mit der Pinbelegung, das hab ich irgendwie total übersehen.

Ich werde berichten!!

MfG Volker

kalledom
21.05.2007, 09:45
Natürlich hat Reichelt auch 74LS-ICs, einige wenige auch in SMD.
Keramik-Vielschicht-Kondensatoren Z5U-2,5 100n solltest Du nehmen, nix mit gewickelter Folie; gewickelt = induktiv !
Nicht alles mit KerKos voll-pflastern, das bringt es nicht; 100nF am µC auf kürzestem Weg an die Versorgungsleitungen, dazu noch ein 10µF Tantal.
100nF am SRAM und an den beiden D-Latchs auf kürzestem Weg an den Versorgungsleitungen.
Eingang und Ausgang vom Spannungsregler nicht vergessen, damit der nicht anfängt zu schwingen.

vklaffehn
21.05.2007, 10:21
Moin!
Ich meinte nicht, daß Reichelt generell keine LS hat ;-)
Auch ist mir klar, daß nicht überall Kondensatoren hinsollten ... :-)
Ich hab grad mal ein paar KerKos bestellt, dann werd ich mal schauen, ob das hilft, evtl. ja zusammen mit den HCT Latches...
Das mit den induktiven Folienkondensatoren war mir bisher gar nicht bewußt, man lernt ja nie aus. So langsam verstehe ich auch, warum auf Digitalschaltungen soooviel Gedöns drumrum drauf ist...

MfG Volker

kalledom
21.05.2007, 12:45
Dann überlege mal, was ohne Kondensatoren passiert, wenn so ein digitaler Gegentakt-Ausgang umschaltet. Der eine Transistor fängt an zu leiten, der andere hört auf zu leiten. Sind beide nicht schnell genug, treffen sie sich in der 'Mitte', wo sie noch nicht sperren. Die Folge: es fließt, abhängig von der Umschaltgeschwindigkeit / Flanken-Steilheit / Impuls-Frequenz, ganz kurz ein mehr oder weniger hoher Strom. Was macht die Versorgungsspannung ? Die bricht ganz kurz ein, weil die Leiterbahnen GND und Vcc einen Widerstand haben, wo Spannung abfällt.
Der Spannungsregler sackt kurz ein, bevor er nachregeln kann.
Bei hochfrequenten / steilen Impulsen entstehen zusätzlich elektro-magnetische Wellen (jeder stromdurchflossene Leiter / Leiterbahn ist von einem Magnetfeld umgeben), die sich ausbreiten. Deshalb nichts 'Gewickeltes' oder 'Spulen-Ähnliches' anschließen, daß könnte einen Super-Schwingkreis ergeben oder bei bestimmten Bauteilen die Schwingneigung begünstigen. Auch Leiterbahnen nicht als 'Windungen' überall drumherum verlegen.
Jetzt kommen die Kondensatoren ins Spiel.
KerKos blocken steile Impulse ab (je steiler / hochfrequenter der Impuls, um so niederomiger wird der kapazitive Widerstand), damit die nicht in den Baustein können und dort alles durcheinander rütteln.
Und, sie geben kurz ihre Ladung ab, wenn die Spannung am Baustein beim Umschalten einbrechen möchte.
GND-Leiterbahnen immer besonders dick ausführen, damit dieser 'Gemeinsame' niederohmig ist und wenig Spannungsabfall entsteht, was ja alle anderen Bausteine an der gleichen GND-Leiterbahn zum 'Schweben' bringen würde.
Immer nur am letzten Baustein einer Versorgungs-Reihe einen KerKo, sonst hat man eine wunderschöne Kaskade aus C ... L (Leiterbahn) ... C ... L (Leiterbahn) ...
Ja, eine Leiterbahn ist bei hohen Frequenzen / steilen Flanken auch induktiv oder wirkt als Antenne. Schau mal in einen Fernseh- oder Satelliten-Tuner rein, da sind Spulen als Leiterbahnen ausgeführt.
Kapazitiv ist eine Leiterbahn gegenüber benachbarten Leiterbahnen ebenfalls. Störimpule können somit auch kapazitiv übertragen werden.
Deshalb: Leiterbahnen immer so kurz wie möglich, GND-Verbindungen so dick wie möglich.
Versorgungen sternförmig vom Glättungs-Elko des Netzteils oder vom Ausgang des Spannungsreglers aus verlegen, weil dort die Spannungsquelle am niederohmigsten ist.
Jetzt höre ich erst mal auf.

vklaffehn
23.05.2007, 22:53
Hallo!!
Vielen Dank an Kalledom, der letzte Eintrag ist sehr aufschlußreich!!
Außerdem habe ich jetzt mal wie beschrieben KerKos angeschlossen und die Latches durch HCT-Typen ersetzt! Jetzt funktioniert es!!!!!
Aber beim Lesen muß ich tatsächlich nach dem Wechsel von OE zwei NOP einbauen, damit es funktioniert, aber damit kann ich leben.
Nochmal danke!!!

MfG Volker