Guten Abend zusammen.
In meinem aktuellen Projekt möchte ich eine Sinustabelle im ERAM des
at89c51ac3 (8051 derivat) ablegen. Dazu habe ich das Array beim
Deklarieren auch gleich initialisiert. Compiler ist der sdcc.
Ich habe nun bemerkt, dass aber die Daten nach der Initialisierung
falsch im Array abgelegt werden. Habe mir nämlich das Array mal über
UART vom µC an den PC senden lassen. hier das Ergebnis:
128 134 140 146 152 158 165 170 176 182 188 193 198 203 208 213 218 222
226 230 234 237 240 243 245 248 250 251 253 254 254
255 255 255 254 254 253 251 250 248 245 243 240 237 234 230 226 222 218
213 208 203 198 193 188 182 176 170 165 158 152 146
140 134 128 121 115 109 103 97 90 85 79 73 67 62 57 52 47 42 37 33 29 25
21 18 15 12 10 7 5 [[[0 0 4 96 8 0 16 16 8 0 16 0 1 2
0 2 0 0 0 0 0 0 66 0 0 17 0 0 0 32 0 80 4 2 132 20 0]]]
Die in [[[...]]] dargestellten Zahlen sind im Vergleich zu
Initialisierung also falsch.
Testweiße habe ich dann das Array mal mit __code deklariert, so dass es
im Code Speicher abgelegt wird, und es dann innerhalb der
main()-Funktion mittels einer for-Schleife auf das jetzt leere Array im
xdata-Speicher kopiert. Und siehe da...die Werte stehen nun korrekt im
Array.
Es scheint mir also so, als ob es hier ein Problem mit dem
Initialisieren von "großen" Arrays im ERAM des Controllers gibt. Nach
dem Konsultieren des sdcc-Manuals und vielem googlen denke ich dass es
etwas mit den Begriffen
- startup code
- MPAGE SFR at 0x92
- crtxinit.asm und DUAL_DPTR = 1
zu tun haben muss.
Bitte hierzu auch diesen Link beachten:
http://develissimo.com/forum/topic/2993/?page=1#post-8933
Jetzt ist es aber so, dass ich nicht unbedingt zu tiefst bewandert bin,
was Compiler und Assembler angeht. Daher möchte ich hiermit eure
Unterstützung bei diesem Problem erfragen.
Vielen Dank und grüße
Markus
Hmmm danke für die Antwort, aber den Abschnitt aus dem Handbuch kenne
ich schon...doch wie gesagt....Assembler und Compiler sind nun eben
nicht gerade meine Muttersprache.
Also, das RAM kann erst zur Laufzeit initialisiert werden. Es gibt das
auf S. 46 beschriebene Stück Code, das genau dies tut. Aber das RAM ist
in verschiedene Bereiche aufgeteilt. Neben Stack und Co. gibt es den
initialisierten Bereich und nicht initialisierten Bereich für Variablen.
Das Ganze muss dem Compiler bzw. dem Linker mitgeteilt werden.
Ok, danke für diese Erklärung. Jedoch passt dazu meine Beobachtung
nicht, dass die Initialisierung problemlos funktioniert, wenn das Array
mit nur 64 Elementen deklariert wird:
Wie groß ist Xdata bei diesem MC?
Ist es nach Reset schon auf maximaler Größe oder muß man im Startup-Code
noch was initialisieren?
Was steht im Map-File, wo dac_values[] angelegt wurde?
blabla schrieb:> gibt es den> initialisierten Bereich und nicht initialisierten Bereich für Variablen.> Das Ganze muss dem Compiler bzw. dem Linker mitgeteilt werden.Markus B. schrieb:> Jedoch passt dazu meine Beobachtung> nicht, dass die Initialisierung problemlos funktioniert, wenn das Array> mit nur 64 Elementen deklariert wird
Warum nicht? Das passt doch wie die Faust aufs Auge. Der Bereich mit
Initialisierung ist einfach zu klein gewählt.
Der MC hat eine XRAM größe von 2048 Byte. Laut dem Datenblatt ist dieser
Speicherbereich nach einem Reset mit seiner vollen größe aktiviert.
Hier der Auszug aus dem map-file:
Area Addr Size Decimal
Bytes (Attributes)
-------------------------------- ---- ---- -------
----- ------------
XISEG 00000065 000000C0 = 192.
bytes (REL,CON,XDATA)
Value Global Global Defined In
Module
----- -------------------------------- ------------------------
0D: 00000065 _data_example2 test
0D: 000000A5 _dac_values test
ASxxxx Linker V02.00 + NoICE + sdld, page 17.
Hexadecimal [32-Bits]