Hallo zusammen, ich möchte an meinem ATmega 128 einen esternen SRAM Baustein(64kByte) ansteuern. Die 8 Adress/Datenleitungen sind an PortA, die Adressleitungen an PortC, WE_N an Pin PG0, RD_N an PG1 und ALE an Pin PG2. Wie müsste eine C-Funktion aussehen, um Daten in den Speicher reinzuschreiben bzw. Daten aus dem Speicher auszulesen. Ich wäre für eure Hilfe sehr dankbar! Peter
Du musst den Externen Speicher erstmal aktivieren, das machst du ganz genau so wie in ASM (siehe Datenblatt welche Register dafür verantwortlich sind). Schaue dir auch das Memory Mapping an, dann weisst du auch, welcher Speicher wo eingeblendet ist. Ein ganz klares RTFM! ;)
Oder auch: Suchen lernen mit dem suchen-Link: http://www.mikrocontroller.net/forum/forum.php?action=search&forum=1
Hallo, Danke für Eure schnelle Antwort. Ich habe bereist den externen Speicher wie folgt aktiviert. void xmem_interface_init(void) { MCUCR|=0x80; // External SRAM/XMEM Interface enable XMCRB&=0xF8; // full 60 kB space XMCRA|=0x02; //wait 2 cycles during read/write strobe } Meine Frage: Wie kann ich jetzt beispielsweise die Speicherzelle mit der Adresse 0x10 mit Daten beschreiben. Muss ich die Steuerleitungen wie RD(read strobe), WE(write strobe), ALE handeln oder macht es die XMEM interface. Wie müsste die C-Funktion dazu aussehen. Ich wäre für eure Antwort sehr dankbar. Peter
hmm... als erstes cs (cable select) selectieren (wird warscheinlich lowactiv sein). dann die write leitung selectieren (höchst warscheinlich auch lowactiv). dann die adresse anlegen und zum schluss die daten.
Nix da! Macht alles das XMEM-Interface! Mit "Speicherzelle mit der Adresse 0x10" meinst Du wahrscheinlich die Speicherstelle im externen SRAM. Leider musst Du da zur Zeit noch mit ein bißchen Pointer-Salat drauf Zugreifen! Kleines Beispiel: uint8_t *pExtSRAM = (uint8_t *) 0x1110; /* extmem start: 0x1100 */ [..] pExtSRAM[0] = 0x55; [..] Der Wert 0x1110 ergibt sich natürlich aus dem Adressoffset, der durch das interne SRAM des AVRs entsteht (OFFSET + ADR = EXTADR: 0x1100 + 0x10 = 0x1110).
Achso, noch was vergessen: CS steht hier nicht für 'Cable Select' sondern für 'Chip Select'!
Einen hab ich noch =) '//wait 2 cycles during read/write strobe' Bist Du eigentlich sicher, daß Du so lange warten willst?
Könnte ich nicht einfach meine Funktion auch so gestallten..? void XMEM_Write(unsigned char adr,unsigned char daten) { /* # define OFFSET 0x8600 unsigned int *ptr=(unsigned int *)(OFFSET+adr); *p=daten; } oder liege ich total falsch???
Wenn Dein externes SRAM erst ab Adresse 0x8600 anfängt, geht das im Prinzip schon, nur solltest Du die Sache ein wenig anders angehen: void XMEM_write_byte(uint8_t * adr, uint8_t data) { *adr = data; } void XMEM_write_int(int * adr, int data) { *adr = data; } Den offset dann bei Aufruf hinzufügen: [..] XMEM_write_byte(OFFSET + 0x10, 128); XMEM_write_int(OFFSET + 0x11, 32767); [..] etc, pp.
hi kann mir mal jemand sagen was ich hier falsch mache Ich schreibe den Wert ins externe SRAM,lese ihn dann erneut aus und gebe ihn über die serielle Schnittstelle zurück. Aber der Wert der bei der seriellen Schnittstelle am PC ankommt stimmt überhaupt nicht überein mit dem ins RAM geschriebenen. In diesem Fall kommt der Wert 4111 zurück. #define OFFSET 0x10FF //--------------------------------------------- void XMEM_wr(int *address,int data); int XMEM_rd(int* address); //--------------------------------------------- ... //--------------------------------------------- void XMEM_wr(int* address, int data) { *address=data; } int XMEM_rd(int* address) { int wert; wert= *address; return wert; } //--------------------------------------------- void main (void) { while(1) { XMEM_wr(OFFSET+0x10, 27); printf("\t%d",XMEM_rd(OFFSET+0x10)); } } mfg alex
OFFSET muss die erste externe Adresse sein, bei Dir wahrscheinlich 0x1100 (steht aber im Datenblatt). Um Fehler mit der seriellen SSt auszuschliessen würde ich 0xaa und 0xff in das externe mem schreiben und auf einem Port die gelesenen werte ausgeben. Dann kannst Du mit LEDs oder schlimmstenfalls einem Multimeter in Ruhe messen, ob alles stimmt.
Die Initialisierung erfolgt dort wo ich die ... geschrieben habe. Sie erfolgt gleich zu Beginn des Programmes und wird normalerweise natürlich in der main vor der while(1) aufgerufen. Ich habs jetzt eingefügt wie mein SRAM konfiguriert ist. Ich hab meinen RAM mit nur 1 Sector definiert und 2 die wait states als 2r/w für diesen Sektor. //SRAM Initialisierung MCUCR=0x80; XMCRA=0x02; @Wolfram: "Wo liegt dein Stack?" ...versteh die Frage leider nicht ganz, aber hab mal meine Speicher/Stack-größen angeführt Data Stack Size: 1024bytes Internal SRAM size: 4096bytes @Ingo: Stimmt, mein Fehler. Hab die Adresse des Endes des internen Speichers als OFFSET angegeben. Natürlich gehört der Beginn des externen Speichers als OFFSET mit 0x1100 angegeben.
Auch wenn das funktionieren wird, was du gerade machst. Es liegt nur daran weil der Compiler denkt du würdest ohne externes RAM arbeiten. d.h. Stack und Daten liegen unterhalb der 4KB. Solltest du das XMEM_read/rw aufgeben wollen und in der Art unsigned char array[5000]; array[5]=6; arbeiten wollen, so solltest du dir den entsprechenden Abschnitt in der avrlibc Doku durchlesen. Es ist sowieso besser das Mapping des Speichers abgeschlossen zu haben BEVOR man in main eintritt. DER COMPILER WEISS NÄMLICH NICHTS DAVON! Solltest du nicht gerade im ATMEGA103 Modus arbeiten dann möchte ich dich darauf hinweisen, dass im ATMEGA128 die ersten 4352 Byte des Datamemory intern sind. Das hast du ja auch schon mitbekommen. Ein Zugriff auf OFFSET 0x10ff geht also voll in den Stack! Bei Rücksprüngen kann sowas einen sehr interessanten Programmablauf bewirken.
Danke erstmal. Ich werde mal den betreffenden Teil der avrlibc studieren. Aber wenn ich es so schreibe: unsigned char array[5000]; array[5]=6; kann es ja passieren das der Compiler die Datei ins interne RAM legt. ICh muss ihm ja sagen dass er die VAriable array[] ins externe schreiben soll. Das jedoch machst du nicht. Wenn ich die Variable so initializiere dann legt er sie automatisch in den internen RAM. Und nein ich bin nicht im Atmega103-kompatibiltätsmodus
hi hab erst jetzt wieder den Weg zum Programmieren gefunden. Hab den Abschnitt zum externen RAM gelesen aber leider kein Wort verstanden. Naja, das Problem besteht weiterhin. Ich kann die Werte ins RAM schreiben (mit debugger kontrolliert) und sie bleiben dort auch. Nur beim Auslesen haperts. Über USART kommt immer noch 4111 und ich hab mal 0xAA ins RAM geschrieben und dann auf Port D ausgegeben aber dort liegt dann 0x0F an. Muss ich irgendein RegisterBit setzen damit /RD auch funktioniert? Weil eigentlich sollte das XMEM das ja automatisch machen. Init wie oben in älterem Post von mir bereits beschrieben mfg Alex
int XMEM_rd(int* address) { int wert; wert= address; <-- den Wert nicht die Adresse zurückgeben return wert; }
ups Fehler. Ports als output schalten DDRA=0xFF DDRC=0xFF DDRG=0x1F so läufts zumindest bei mir
>Hab den Abschnitt zum externen RAM gelesen aber leider kein Wort >verstanden Das ist schlecht, ist nämlich sehr wichtig das man weiss was man tut. Ich versuchs mal zu erklären Du willst einen externen RAM benutzen, für dein C Programm sollte das ganze vollkommen transparent sein, du hast halt mehr SRAM. Also nicht 4K sondern 64 K. Probleme: 1.Der C-Compiler muss dies mitgeteilt bekommen. Er benutzt einen Stack der liegt am Ende des Speichers, solange du ihm nicht sagst dass dein Ende des Speichers nicht mehr bei 4K liegt sondern bei 64K wird er seinen Stack weiterhin bei 4K abwärts anfangen. 2. Bevor du in main kommst hat dein Programm schon einiges gemacht Stack anlegen, Variablen mit 0 füllen ,Strings laden etc. d.h. du must vorher das Speicherinterface initialisiert haben und zwar OHNE den Stack zu benutzen(Funktionsaufrufe und lokale Variablen sind zu diesem Zeitpunkt absolut tabu!). Dazu gibt es die init Sektionen hier gibts du eine Funktion an die das Speicherinterface einschaltet. Sobald du dies getan hast, kannst du ohne weiteres im Programm schreiben unsigned char Variable[6000]; Da du einen Debugger hast (JTAG?) ,kannst du den ja sehr einfach testen ob dein externer RAM funktioniert. Assembler-Projekt in AVR-Studio laden (ohne gehts leider nicht) in IO-Register wechseln und Speicherinterface aktivieren. Dann in Speicherfenster wechseln und kontrollieren ob der Speicher funktioniert.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.