www.mikrocontroller.net

Forum: Compiler & IDEs AVR, xtern. SRAM initialisierung, xmem, makefile, .init funktionen


Autor: Mad Tulip (madtulip)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Guten Tag.

Ich bastel nun seid einigen Stunden daran meinen ATMega 162 um einen 
externen 64k sram zu erweitern. Leider will mir das trotz intensivem 
lesen der Foren und google nicht gelingen.

Ich bin der Meinung, dass ich den RAM und das Latch richtig verkabelt 
habe... es lief bisher auf dem mC ein Programm, fuer welches ich jetzt 
mehr Speicher brauche. Das Programm das bisher lief habe ich nun 
ausreichend getestet, von Fehlern am uart ist nicht auszugehen. Ich 
dimensioniere nun einen Array in einen Bereich, den der interne sram des 
mC noch aufnehmen kann, beschreibe das array und sende die daten per 
uart - das laeuft soweit.

meldung des compilers:
Data:        165 bytes (16.1% Full)
(.data + .bss + .noinit)

hier die variable aus einer header datei
#define DAT_BUFFER_SIZE  128
volatile unsigned char dat_buffer[DAT_BUFFER_SIZE];

Wenn ich nun aber DAT_BUFFER_SIZE soweit erhoehe (z.b. 2048), das der 
Inhalt des Arrays nicht mehr in das interne sram passt, dann verhält 
sich die Rueckgabe des uart (der im endeffekt nur den inhalt von diesem 
array sended) schlagartig scheinbar komplett zufällig. Es wird garnicht, 
stückweise oder falsch ausgelesen. Deshalb gehe ich davon aus, das ich 
das externe sram nicht richtig verwende.

meldung des compilers:
Data:       2085 bytes (203.6% Full)
(.data + .bss + .noinit)

Hier sehe ich schonmal ein Problem und frage mich warum der Compiler die 
64k externen speicher hier nicht beruecksichtigt.

hier ein ausschnitt aus der main.c
#include <avr/io.h> //header für die register
#include <stdint.h> //header für lesezugriffe

#include "uart.h"

#ifndef F_CPU

#warning "F_CPU war noch nicht definiert, wird nun nachgeholt mit 14745600"
#define F_CPU 14745600UL    // Systemtakt in Hz - Definition als unsigned long beachten >> Ohne ergeben Fehler in der Berechnung
#endif
 
#define BAUD 38400UL          // Baudrate

// Berechnungen uart 0
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)   // clever runden
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1)))     // Reale Baudrate
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD) // Fehler in Promille, 1000 = kein Fehler.
 
#if ((BAUD_ERROR<990) || (BAUD_ERROR>1010))
  #error Systematischer Fehler der Baudrate von uart 0 grösser 1% und damit zu hoch! 
#endif

void xram(void) __attribute__ ((naked)) __attribute__ ((section (".init1")));

//----------------------------------------------------------------------------
//
void xram(void)
{ 
  //init SRAM
//  MCUCR|=0x80;// External SRAM/XMEM Interface enable
  MCUCR |= (1<<SRE)|(1<<SRW10);    // The SRE Bit activates the memory interface, srw11 und srw10 controll mem wait states
  EMCUCR = (0<<SRL2) | (0<<SRL1) | (0<<SRL0);//Lower sector = N/A;Upper sector = 0x1100 - 0xFFFF
  SFIOR = (1<<XMBK) | (0<<XMM2) | (0<<XMM1) | (0<<XMM0);//use full 60k space and activate  memory bus keeper

}

//----------------------------------------------------------------------------
//
int main(void)
{    
  //volatile unsigned long max_bytes;



  //INITIALISIERUNG
  //COM 0
  UCSR0B |= (1<<RXEN0)|(1<<TXEN0);// UART RX und TX einschalten
  UCSR0C |= (1<<URSEL0)|(3<<UCSZ00);// Asynchron 8N1 
 
  UBRR0H = UBRR_VAL >> 8; //setzen der Baudrate
  UBRR0L = UBRR_VAL & 0xFF; //setzen der Baudrate

  sei();

  //wait until condensators are charged up
  int waittimer = 0;
  while(waittimer<30000)
  {
    waittimer++;
  }
//beschreiben einer stelle die meiner meinung nach mitten im sram liegen muesste
  uint8_t *pExtSRAM = (uint8_t *) 0x2FFF;
  uint8_t *pExtSRAMandererPointer = (uint8_t *) 0x2FFF;

    uart_write_char(pExtSRAMandererPointer[0]);

  pExtSRAM[0] = 0x60;
  uart_write_char(pExtSRAM[0]);
  uart_write_char(pExtSRAMandererPointer[0]);
//....

Ich bin mir nicht sicher, ob ich alle wichtigen Register fuer den sram 
und das xmem gesetzt habe (siehe "void xram(void)"). Ausserdem ist mir 
die zeile
void xram(void) __attribute__ ((naked)) __attribute__ ((section (".init1")));
nicht klar. Ich verstehe sie so, dass die Funktion xram geladen wird 
(und damit der speicher initialisiert) bevor andere Programmteile 
ausgefuehrt werden, damit die anderen Programmteile eben diesen Speicher 
verwenden koennen. geschiet das auch vor dem definieren einer Variable 
ueber den header wie in meinem Beispiel? Und muss das Makefile irgendwie 
bezug auf ".init1" nehmen ? Ist ".init1" an sich schon eine klar 
definierte Phase oder muss ich darum im makefile irgendwie bezugnehmen? 
Ich wundere mich wo die Stelle ".init1" definiert ist, ist dem Linker 
einfach nur durch diese Bezeichnung klar in welcher Phase des ... 
Bootvorganges diese Funktion "xram" geladen werden soll?

hier evtl nocheinmal alles von dem ich denke das es fuer das externe 
sram notwendig ist aus dem makefile:
#variables&heap;start = lowest possible; size = 64k
EXTMEMOPTS = -Wl,--section-start,.data=0x800500,--defsym=__heap_end=0x80ffff

Was habe ich übersehen ? Ich spiele schon mit dem Gedanken die Hardware 
auf Fehler zu untersuchen. Vielen Dank für eure Zeit!

Autor: Andreas Paulin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hm... da hab ich lange gesucht ;-)


"Ist ".init1" an sich schon eine klar
definierte Phase"

Guck hier: AVR-Libc Manual "8.7 Memory Sections"


Also....ich habe bei mir (ATMEGA128, 64k externes SRAM
den Heap(!) ins externe Ram gelegt, die deklarierten variablen
(.data und .bss) bleiben im internen.
Und zwar so:
-Wl,--defsym=__heap_start=0x801100
-Wl,--defsym=__heap_end=0x80ffff

Die Option

-Wl,--section-start,.data=0x800500,--defsym=__heap_end=0x80ffff

dagegen legt .data und .bss auch noch ins externe RAM

Schau mal, hier ist ne ganze Doktorarbeit übers Thema
Beitrag "Externes Speicherinterface Hintergrundwissen"
Hat mir sehr geholfen, außerdem im AVR-libc-Manual das Kapitel

8.3.16 How to use external RAM?
auf S. 195.

ACHTUNG: Variablen auf dem Heap (pointer)musst Du immer mit malloc() 
allozieren, z.B.:
uint8_t* Buffer;
Buffer = malloc(BUFSIZE * sizeof (uint8_t)

Geht auch fix, ist aber nicht schön

Zu guter letzt:

[/c] statt [/code] ;-)

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Andreas Paulin wrote:

> ACHTUNG: Variablen auf dem Heap (pointer)musst Du immer mit malloc()
> allozieren, z.B.:

Man kann aber den externen Speicher auch ganz ohne Heap benutzen.
Einfach einen Zeiger passend casten und die Verwaltung komplett
manuell vornehmen:
  uint8_t *bigarray = (uint8_t *)0x2000; /* array in XMEM, length 1024 */
  uint16_t *another = (uint16_t *)0x2400; /* another array */

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Wenn ich nun aber DAT_BUFFER_SIZE soweit erhoehe (z.b. 2048), das der
> Inhalt des Arrays nicht mehr in das interne sram passt, dann verhält
> sich die Rueckgabe des uart (der im endeffekt nur den inhalt von diesem
> array sended) schlagartig scheinbar komplett zufällig.

Hast du denn auch mal einen prüfenden Blick in den Sourcecode geworfen?
Vielleicht eine 8-Bit-Variable für den Index verwendet?

> //beschreiben einer stelle die meiner meinung nach mitten
> im sram liegen muesste

Und, funktioniert denn das, oder auch nicht?

Autor: Mad Tulip (madtulip)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jo, danke schonmal für die Antworten.

von dem Array dat_buffer habe ich nun erstmal abstand genommen, den 
schon das auslesen einzelner bytes will nicht gelingen.

Ich habe bisher erstmal die Fuse fuer das JTAG deaktiviert, die sorgte 
schonmal dafür dass der Port C teilweise schlecht belegt war. Da liegen 
gleichzeitig die JTAG und die hohen Adress Pins beim ATMega 162. Als ich 
das endlich gefunden hatte dachte ich schon das wäre es jetzt gewesen, 
wars aber nicht. Der code schaut im moment so aus : die hterm ausgabe 
habe ich unten angehaengt.
#include <avr/io.h> //header für die register
#include <stdint.h> //header für lesezugriffe

#include "cam.h"
#include "uart.h"

#ifndef F_CPU

#warning "F_CPU war noch nicht definiert, wird nun nachgeholt mit 14745600"
#define F_CPU 14745600UL    // Systemtakt in Hz - Definition als unsigned long beachten >> Ohne ergeben Fehler in der Berechnung
#endif
 
#define BAUD 38400UL          // Baudrate

// Berechnungen uart 0
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)   // clever runden
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1)))     // Reale Baudrate
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD) // Fehler in Promille, 1000 = kein Fehler.
 
#if ((BAUD_ERROR<990) || (BAUD_ERROR>1010))
  #error Systematischer Fehler der Baudrate von uart 0 grösser 1% und damit zu hoch! 
#endif


void xram(void) __attribute__ ((naked)) __attribute__ ((section (".init1")));

//----------------------------------------------------------------------------
//
void xram(void)
{ 
  //init SRAM
  MCUCSR |= (1<<JTD);// JTAG nochmals (ausser der fuse) deaktivieren
  MCUCSR |= (1<<JTD);//mindestens 2 mal hintereinander verwenden.
  MCUCSR |= (1<<JTD);//sicher ist sicher ...
  MCUCSR |= (1<<JTD);
  MCUCR |= (1<<SRE)|(1<<SRW10);    // The SRE Bit activates the memory interface, srw11 und srw10 controll mem wait states
  EMCUCR = (0<<SRL2) | (0<<SRL1) | (0<<SRL0) |(1<<SRW11);//Lower sector = N/A;Upper sector = 0x1100 - 0xFFFF
  SFIOR = (1<<XMBK) | (0<<XMM2) | (0<<XMM1) | (0<<XMM0);//use full 60k space and activate  memory bus keeper
}

//----------------------------------------------------------------------------
//
int main(void)
{    
  //INITIALISIERUNG
  //COM 0
  UCSR0B |= (1<<RXEN0)|(1<<TXEN0);// UART RX und TX einschalten
  UCSR0C |= (1<<URSEL0)|(3<<UCSZ00);// Asynchron 8N1 
 
  UBRR0H = UBRR_VAL >> 8; //setzen der Baudrate
  UBRR0L = UBRR_VAL & 0xFF; //setzen der Baudrate

  sei();
  //Kamera arbeitet nur mit einem 14,7456Mhz Quarz!
  cam_init();

  unsigned long b;
  //nen bisschen warten, wer weiss evtl sind die kondensatoren noch nicht geladen
  for(unsigned long a = 0;a>30000;a++)
  {
    UBRR0L = UBRR_VAL & 0xFF;//irgendwas machen
  }

  uint8_t *pExtSRAM = (uint8_t *)0x2000;

  uart_write_char(0x00);//testen ob der uart laeuft
  uart_write_char(0xFF);// .. tut er.

  pExtSRAM[0] = 0x00;
  uart_write_char(pExtSRAM[0]);
  pExtSRAM[0] = 0x00;
  uart_write_char(pExtSRAM[0]);
  uart_write_char(pExtSRAM[0]);
  pExtSRAM[0] = 0x00;
  uart_write_char(pExtSRAM[0]);
  uart_write_char(pExtSRAM[0]);
  uart_write_char(pExtSRAM[0]);

  pExtSRAM[0] = 0xFF;
  uart_write_char(pExtSRAM[0]);
  pExtSRAM[0] = 0xFF;
  uart_write_char(pExtSRAM[0]);
  uart_write_char(pExtSRAM[0]);
  pExtSRAM[0] = 0xFF;
  uart_write_char(pExtSRAM[0]);
  uart_write_char(pExtSRAM[0]);
  uart_write_char(pExtSRAM[0]);

//                                !     !  !
// => am hterminal: "00 FF 00 00 03 00 03 03 FF FF FF FF FF FF"

Das macht auf mich den Eindruck, als sei da ein Wackelkontakt oder ne 
induzierte Spannung und etwas dergleichen. Darauf hin habe ich die Pins 
saemtlich mit dem Auge abgesucht und nichts gefunden. benachbarte pins 
mit nem multimeter durchgemessen, nichts gefunden.

zu
uint8_t *bigarray = (uint8_t *)0x2000; /* array in XMEM, length 1024 */
Das verstehe ich noch nicht ganz. Ich dachte es handelt sich hier um 
einen Pointer auf einen Array dessen elemente jeweils vom type her 
uint8_t sind.
Mit
bigarray[0] = 0x00;
dachte ich auf Adresse 0x2000 einen uint8_t (8 bit) mit nullen zu 
füllen. Sollte ich danach
bigarray[1] = 0x00;
verwenden, so dachte ich das ich dann das zweite Element des Arrays mit 
nullen fülle - um ein Offset verschoben welches sich aus der grösse des 
Typs uint8_t ergibt. So das nun an Adresse 0x2000 und 0x2001 alle 16 
bits 0 sind. Ist das nicht richtig ? Ich bin irritiert wegen der "length 
1024". evtl liegt ja auch hier mein fehler.

Ich habe dann jetzt nochmal probiert das makefile so zu gestalten wie 
Andreas Paulin es vorgeschlagen (nur heap, malloc) hat und folgenden 
code verwendet:
  uint8_t* Buffer = malloc (2000 * sizeof (uint8_t));

  Buffer[0] = 0x00;
  uart_write_char(Buffer[0]);
  Buffer[0] = 0xFF;
  uart_write_char(Buffer[0]);
  Buffer[0] = 0x01;
  uart_write_char(Buffer[0]);
  Buffer[0] = 0x02;
  uart_write_char(Buffer[0]);
  Buffer[0] = 0x03;
  uart_write_char(Buffer[0]);
  Buffer[0] = 0x04;
  uart_write_char(Buffer[0]);
  Buffer[1800] = 0x05;
  uart_write_char(Buffer[1800]);
  Buffer[1900] = 0x06;
  uart_write_char(Buffer[1900]);

  free (Buffer);

Tja, "manchmal" waren die Werte in Ordnung, meistens waren die Werte 
falsch - Die Fehler waren ziemlich zufaellig verteilt und nicht 
haeufiger oder weniger haeufig als richtige Ergebnisse, was an sich doch 
dafür spricht, dass das Ram zumindest arbeitet, nur halt nicht so wie es 
soll. Nach mittlerweile 10 Stunden herrumprobieren liegt für mich ein 
deffekter Chip oder nen Wackelkontakt am nächsten.

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
uint8_t *bigarray = (uint8_t *)0x2000; /* array in XMEM, length 1024 */
> Ich bin irritiert wegen der "length 1024". evtl liegt ja auch
> hier mein fehler.

Das "length 1024" ist wohl als "Gedächtnisstütze" für den Programmierer 
da, denn der Ausdruck definiert nur einen Pointer (wie du richtig 
ausgeführt hast), und beinhaltet daher keine Information zur Länge des 
Array.

Mache doch mal bitte ein paar Angaben zur Hardware, also Latch und RAM 
(genaue Typenbezeichnung).

Autor: Mad Tulip (madtulip)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ah, jo :) Vielen Dank!

IC1  mC  ATMEGA 162-16DIP
http://www.reichelt.de/?;ACTION=3;LA=4;GROUP=A363;...

IC2  Latch  74AC 573
http://www.reichelt.de/?;ACTION=3;LA=4;GROUP=A225;...

IC3  SRAM  628128-70
http://www.reichelt.de/?;ACTION=3;LA=4;GROUP=A34;G...

IC4  TLL zu RS232  MAX 202 CPE
http://www.reichelt.de/?;ACTION=3;LA=4;GROUP=A217;...

Ansonsten sind die Beschriftungen der Bauteile jeweils unter dem Namen 
bei reichelt zu finden. Mir fällt es dann leichter sie wiederzufinden.

schaltplan: (als dateianhang wollte er irgendwie nicht)
http://i2.photobucket.com/albums/y45/madtulip/schaltplan.jpg

Autor: Mad Tulip (madtulip)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die AVR-Libc ist ja auch mal ab vom Thema ein sehr interessantes Papier! 
:) Vielen Dank für den Hinweis.

Autor: Dirk Broßwick (sharandac)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Kleine Anmerkung zum Schaltplan. Die Datenleitungen RxD vom MAX zum 
Controller ist nicht richtig angeschlossen :-). Und ich sehe auch gerade 
das du einen 128Kbyte RAM verwendest, schließe doch einfach A16 auch mit 
an den Controller an, dann kannst du die restlichen 64Kbyte auch noch 
nutzen über umwegen (siehe Banking). Aber nicht vergessen das du A16 
auch richtig Einstellst (Controllerpin als Output einstellen, sonst gibt 
es komische effekte :-) ).

Aber so sieht es schon mal gut aus, und sollte vom Prinzip her richtig 
sein.

Autor: Mad Tulip (madtulip)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja, Danke - das stimmt. In der Hardware ist der RX/TX auch schon richtig 
angeschlossen. Flüchtigkeitsfehler beim entwerfen des Schaltplans den 
ich erst beim löten bemerkt und in dem Moment in den dox nicht 
korrigiert habe. Den A16 schliesse ich evtl. spaeter an wenn der Rest 
laeuft. Das Ding ist, das ich mit dem Ram zwei Bilder einer Digicam 
gleichzeitig speichern will. 8 bit Graustufe auf 160*120 = 19200 oder 
320*240 = 76800. für 320*240 reichen weder 64k noch 128k und fuer 
160*120 reichen auch 64k, deswegen habe ich davon bisher abgesehen. Wenn 
dieser eine ram laeuft dann werde ich evtl. nochmal nen ganz anderes 
setup für den Ram verwenden (grösserer Stein, oder mehrere Steine) um 
2*640*480*8bit = 2*307200*8bit speichern zu können. Hier habe ich 
nämlich bei der Auslegung den dummen Fehler gemacht, den Ram um Faktor 
10 zu klein auszulegen. eigentlich waren 2*307200*8bit geplant, und das 
sollten etwas weniger als 64k sein, sind aber etwas weniger als 640k ... 
, doof das :)

Naja, aber step by step. Fürs erste möchte ich erstmal nur das vom avr 
vorgesehene setup verwenden, ohne zusätzliche Adressleitungen um Fehler 
an dieser Stelle ausschliessen zu können. Erstmal muss 1 byte des Rams 
laufen :)

Aber generell sollte ich dann das Programm so schreiben, dass ich gleich 
direkt auf die Adressen zugreife um sie zu beschreiben statt malloc zu 
verwenden oder den Variablen automatisch speicher zuweisen zu lassen, 
weil sich das dann später vermutlich einfach auf eine von xmem nicht 
unterstütze Adressbreite übertragen lässt. Das ist auch günstig für die 
Form der Daten die als serieller Stream vorliegen.

Autor: Mad Tulip (madtulip)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So, zum Stand der Dinge. Es geht noch immer nicht :) .. aber ich konnte 
einen weiteren Teil des Problems beheben. Einer der Pins am Latch oder 
Ram hatte einen Wackelkontakt mit dem Federsockel (das nächste mal kaufe 
ich keine Federsockel mehr). Aber auch das war nur ein Teil des 
Problems. Im Moment arbeite ich mit folgendem Code:
//im makefile : EXTMEMOPTS = -Wl,--defsym=__heap_start=0x800500,--defsym=__heap_end=0x80ffff

void xram(void) __attribute__ ((naked)) __attribute__ ((section (".init3")));

void xram(void)
{ 
  //init SRAM
  MCUCSR |= (1<<JTD);// JTAG nochmals (ausser der fuse) deaktivieren
  MCUCSR |= (1<<JTD);// mindestens 2 mal hintereinander verwenden.
  MCUCSR |= (1<<JTD);
  MCUCSR |= (1<<JTD);

  EMCUCR |= (1<<SRW11) | (1<<SRW00) | (1<<SRW01) | (0<<SRL2) | (0<<SRL1) | (0<<SRL0);

  SFIOR |= (0<<XMM2) | (0<<XMM1) | (0<<XMM0) | (0<<XMBK) | (1<<XMBK);//use full 60k space and activate  memory bus keeper

  MCUCR |= (1<<SRE) | (1<<SRW10);    // The SRE Bit activates the memory interface, srw11 und srw10 controll mem wait states
}

//----------------------------------------------------------------------------
//
int main(void)
{    
  //INITIALISIERUNG

  //------------------------------

  //COM 0 - PC
  UCSR0B |= (1<<RXEN0)|(1<<TXEN0);// UART RX und TX einschalten
  UCSR0C |= (1<<URSEL0)|(3<<UCSZ00);// Asynchron 8N1 
 
  UBRR0H = UBRR_VAL >> 8; //setzen der Baudrate
  UBRR0L = UBRR_VAL & 0xFF; //setzen der Baudrate
  
  //COM 1 - Camera
  UCR =(1 << TXEN1 | 1 << RXEN1 | 1<< RXCIE1);//Enable TXEN im Register UCR TX-Data Enable
  UBRR=0;//Teiler wird gesetzt 

  //------------------------------

  //warte bis die condensatoren auch sicher geladen sind
  long int C_Delay1 = 0;
  long int C_Delay2 = 0;
  for(long int a = 0; a < 30000; a++)
  {
    for(long int b = 0; b < 250; b++)
    {
      UBRR0L = UBRR_VAL & 0xFF;//mache irgendwas redundantes
      C_Delay2 = C_Delay2 +1;
    }
    C_Delay1 = C_Delay1 +1;
  }

  uart_write_char(0xAA); //teste uart
  uart_write_char(0xAA);
  uart_write_char(0xAA);
  uart_write_char(0xAA);

  //AA AA AA AA//<- teil der hterm rueckgabe zur besseren uebersicht. die gesamte rueckgabe ist am ende des codes nochmal in einem stueck.
  //hieraus ergibt sich fuer mich, dass der uart funktioniert.

  //Versuch mit malloc
  uint8_t* Buffer = malloc (19200 * sizeof (uint8_t));

  Buffer[10] = 0xAA;
  uart_write_char(Buffer[10]);
  Buffer[18000] = 0xBB;
  uart_write_char(Buffer[18000]);

  //AA BB //funktioniert

  Buffer[1] |= 0xCC;
  Buffer[2] |= 0xDD;
  uart_write_char(Buffer[1]);
  uart_write_char(Buffer[2]);

  //03 04 //funktioniert nicht

  Buffer[1] |= 0xEE;
  Buffer[2] |= 0xFF;
  uart_write_char(Buffer[2]);
  uart_write_char(Buffer[1]);

  //FF 03 //FF ist richtig, 03 nicht. wenn man den entsprechenden buffer liest bevor man eine andere komponente des arrays
  //beschreibt hat er noch seinen richtigen wert.

  Buffer[1] = 0x11;
  uart_write_char(Buffer[1]);
  uart_write_char(Buffer[1]);

  //11 03 //mehrfach hintereinander lesen fürt ab dem 2. auslesen auch zu falschen ergebnissen

  free (Buffer);

        //Versuch mit pointer
  uint8_t *pExtSRAM = (uint8_t *)0x8005;


   pExtSRAM[10] = 0xAA;
   uart_write_char(pExtSRAM[10]);
  pExtSRAM[200] = 0xBB;
   uart_write_char(pExtSRAM[200]);

  //AA BB

   pExtSRAM[10] = 0xAA;
  pExtSRAM[200] = 0xBB;
   uart_write_char(pExtSRAM[10]);
   uart_write_char(pExtSRAM[200]);

  //AA CD

   pExtSRAM[10] = 0xAA;
  pExtSRAM[200] = 0xFF;
   uart_write_char(pExtSRAM[200]);
   uart_write_char(pExtSRAM[10]);

  //FF 0F

   pExtSRAM[10] = 0xBB;
   uart_write_char(pExtSRAM[10]);
   uart_write_char(pExtSRAM[10]);

  //BB 0F //bis hier wie gehabt. schreiben, lesen laeuft. man kann nur einmal direkt nach dem dazugehoerigen schreiben lesen.
  //alles andere produziert fehler.

  //einmal schreiben, zeit verstreichen lassen, dann lesen
  Buffer[10] = 0xAA;
  int Read_Delay = 0;
  for(long int iterator_a = 0; iterator_a < 100; iterator_a++)
  {
    MCUCSR |= (1<<JTD);
    Read_Delay = Read_Delay +1;
  }
  uart_write_char(Buffer[10]);
  //AA
  //funktioniert. es liegt also nicht daran das der SRAM zwischendurch bootet oder sich anders resettet.
  //dadurch erscheint eine spannungsschwankung in der versorgung des sram unwarscheinlich

  //erst 20 mal schreiben, dann 20 mal lesen, wird nicht funktionieren,
  //gibt aber aufschluss ueber die art des faelschlich angezeigten wertes.
  for(long int a = 0;
    a < 20;
    a++)
    {
      pExtSRAM[a] = 0xCC;
    }

  for(long int a = 0;
    a < 20;
    a++)
    {
      uart_write_char(pExtSRAM[a]);
    }

  //05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18
  // es handelt sich bei dieser ausgabe um falsche werte, aber sie haben system.
  //ich habe das fuer verschiedene speicheradressen getestet. die werte sind immer die beiden low bytes der adressen.

// hterm gesamtausgabe: AA AA AA AA AA BB 03 04 FF 03 11 03 AA BB AA CD FF 0F BB 0F AA 05 06 07 08 09 0A 0B 0C 0D 0E 0F 10 11 12 13 14 15 16 17 18

So, systemattische Fehler also. Es scheint so als wuerde der ram bei 
jedem Schreib oder Lesezugriff geloescht. Es scheint mir so als haette 
der ram Standartwerte eingestellt die jeweils der low bits der 
entsprechenden Adresse entsprechen. Ich haette ja sonst vermutet das 
anfaenglich alles auf 0x00 oder 0xFF oder undefiniert steht. Oder ich 
habe den Pointerarray nicht verstanden und lese die Adresse aus die ich 
angelegt habe. Es waere gut, wenn mir jemand sagen koennte, dass der 
Code so wie er ausschaut prinzipiell funktionieren sollte - nach all den 
Fehlern bin ich mir bei den Pointern und Arrays schon nicht mehr so 
sicher.

in diesem post : Beitrag "Frage zu "sections" im ext. memory"

sah ich, das die Speicherausgabe von
Autor: OldBug (Gast)
Datum: 18.02.2005 00:02
(in der angehaengten Datei uart_log.txt das gleiche Schema enthaelt, 
naemlich die low bits der Adressen als Werte an eben diesen Adressen. 
Leider ist aus dem Code nich ersichtlich was "data" ist. Da es 
inkrementiert wird könnte es auch sein, das in diesem Post diese 
Korellation nicht besteht.

in diesem post : 
http://www.embeddedrelated.com/groups/avrclub/show/521.php
beschreibt jemand das selbe Problem auf dem selben mC. Er sagte dann 
später er habe es gelöst. Leider sagt er nicht genau wie. Die Fusebits 
seien das Problem gewesen. Ich vermute er bezieht sich hier auf den 161 
Kompatibilitätsmodus, welchen ich aber meiner Meinung nach schon 
abgeschaltet habe.

Meine Fuse Bits: alles deaktiviert (1 / kein Häkchen im ponyprog) bis 
auf BOOTSZ0=0 und BOOTSZ1=0 und SPIEN=0

Ich vermute im Moment weiterhin ein Hardwareproblem. Wenn lese oder 
schreib Zugriffe den Inhalt des Rests des Rams loeschen, dann halte ich 
die read,write oder ale Leitung für schuld. Ich konnte da aber bisher 
nichts finden. Ist es sonst evtl. möglich, dass ich zu viele oder zu 
wenige 100nF Kondensatoren angebracht habe (ich habe mal einen zwischen 
jeden IC Vcc und Grd geschaltet um die Versorgung zu glaetten) und mir 
die Spannung zwischen den schreib und lesezugriffen wegbricht? Das 
sollte ja eigentlich nur beim Einschaltvorgang zu einem Zeitproblem 
führen. Der Ram hält laut dokumentation die Daten bis 2V. Da würde wohl 
eher der mC reseten und das würde ich ja am uart sehen. Die Spannung 
nehme ich vom Pc Netzteil an den Festplattenstromsteckern (Rot,Schwarz) 
ab. Das Netzteil sollte ja eigentlich dafür gebaut sein sehr stabile 5V 
zu erzeugen.

Ich beschäftige mich nun schon sicher 20 Stunden mit dem Problem und bin 
für jede Hilfe oder Anregung sehr dankbar!

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.