Forum: Mikrocontroller und Digitale Elektronik Speicher des Microcontrollers


von Nase1987 (Gast)


Lesenswert?

Nabend zusammen,
ich bin gerade dabei mir LED Equipment zum Jonglieren zu programmieren. 
Also eigentlich relativ simpel 2 RGB LED´s und 4 Taster.

Einlesen und Ausgeben klappt alles. Nur nachdem ich jetzt 2h 
Programmiert habe funtzt es plötzlich nicht mehr. Meine Vermutung ist 
das ich den Speicher des ATMega16 voll habe.

Woran kann ich das erkennen das er voll ist?

Gruß
Nase

P.S: Ich porgrammiere mit dem AVR Studio und PonyProg über die Serielle 
Schnittstelle meines PC´s

von Timmo H. (masterfx)


Lesenswert?

Bei AVR Studio siehst du nach dem Kompilieren normalerweise eine 
Zusammenfassung wieviel Flash und RAM verwendet wird und dazu noch die 
Prozentuale Angabe bezogen auf den verfügbaren Speicher.
Solange alles unter 100% ist, ist es ok. Jedoch ist die RAM-Nutzung ohne 
Stacknutzung. Das heisst es kann je nach Programm dennoch passieren, 
dass der Stack überläuft und dir andere Werte im RAM zerstört.

von Thomas B. (nichtessbar)


Lesenswert?

Welcher Speicher? Programmspeicher? Datenspeicher? Verwendest du 
mallocs?

Beim Compilieren wird dir im Ausgabefenster des AVR-Studio die Größe des 
compilierten Programms angegeben (Sowohl Programmspeicherbedarf als auch 
Datenspeicherbedarf)

von Timmo H. (masterfx)


Lesenswert?


von Fabian B. (nase1987)


Lesenswert?

Besten dank für die Hinweise. Habe es zwar nicht gefunden wo es stehen 
soll, musste aber feststellen das meine Programmierweise sehr 
Speicherschluckend war. Über nacht alles nochmal umgeschrieben und 
mithilfe von 2 Variablen ca. auf 1/10 gebracht, jetzt passt alles drauf 
^^

von Thomas B. (nichtessbar)


Lesenswert?

Mit deinem Vorhaben solltest du weit weg davon sein, die 16k Flash 
(Programmspeicher) und das RAM des Mega16 auch nur ansatzweise 
vollzubekommen. Was hast du denn für Optimierung gewählt? 
(Projektoptionen)

Ich glaub irgendwie dass du in deinem Workflow den Hund begraben hast... 
Aufgrund dessen dass du nicht weißt wie die nachschaun kannst wie viel 
Speicher von was benötigt wird denk ich nicht dass du mit Sicherheit auf 
ein Speicherproblem schließen kannst ;)

Ähm, wie meinst du das, mit 2 Variablen?!

von Fabian B. (nase1987)


Lesenswert?

So, habe gerade festgestellt das ich noch mit dem AVR Studio4 arbeite.. 
nachdem ich aber bei AVR5.1 nach kopieren meines Codes fehler bekommen 
habe das angeblich die "delay.h" Bibliothek fehler hat, werde ich wohl 
doch bei AVR 4 bleiben ^^

Ok, wie ich jetzt festgestelklt habe, habe ich keine Optimierung 
verwendet. Also O0..

Mit dem programmspeicher voll, denke ich weil man es bei Ponyprog auch 
sehen kann. Je nachdem welchen Mikrokontroller man einstellt entspricht 
ja die ANzahl an zeilen, die dargestellt werden (was ja die einzelnen 
Bytes sind), wenn noch Bytes frei sin ("FF") in der letzten Zeil, dann 
ist das Programm nicht zu lang ^^

Also mit 2 Variablen meine ich folgendes:

Anfangs habe ich die Ports für die RGB einzeln an und ausgeschlatet

bsp:
1
 PORTB |= 0x09
hier musste ich aber jede Kombination einzeln porgrammieren ^^

jetzt habe ich 2 variablen eingeführt

mode_o für die 1. RGB (die ersten 3 Pins PB0-PB2)
mode_u für die 2. RGB (4-6 Pin also PB3-PB5)

mode_o wurde durch taster1 um +1 erweitern
mode_u durch taster2 um +8 erweitert

a = mode_o +mode_u

und dann halt
1
 PORTB |= a

somit kurzer Programmierungstext, und trotzdessen beide LED´s unabhängig 
voneinander einstellbar

EDIT: Gerade mit mit Os Optimiert ausgeführt... ca die hälfte des 
vorrigen Speicher (laut Ponyprog)

von Thomas B. (nichtessbar)


Lesenswert?

wie viel Speicher brauchst du denn jetzt? Hab so das Gefühl du weißt 
nicht so wirklich was du da mit was tust und welches Programm was 
erzeugt.

In 16k Programmspeicher solltest du einige tausend Zeilen Code 
unterbringen. So ein PORTB |= 0x01 braucht ein paar Byte im Speicher, du 
hast aber 16kB davon.... Poste mal deinen Code... oder den Output 
(unterstes Fenster im AVR-Studio, da wo sich was rührt wenn du auf 
übersetzen klickst) anschaun.

Und die delay.h ist nicht kaputt sondern arbeitet ohne Optimierung und 
definiertes F_CPU Symbol nicht (richtig)

Was verwendest du für einen Programmer (Hardware)?

von Thomas B. (nichtessbar)


Lesenswert?

Noch mehr würd dein Mapfile evtl. Listfile helfen, aber ich denke du 
weißt nicht was das ist oder? Könntest bei den Projektoptionen 
einstellen dass das erzeugt wird.

Denke jetzt - ohne dass ich deinen Fehler weiß - du solltest dich ein 
bisschen mit den Grundlagen von Mikroprozessoren, Entwicklungstools und 
Compilation Toolchain auseinandersetzen... (AVR-Tutorial hier ist gut 
geeignet dafür..)

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Fabian Bade schrieb:

> Ok, wie ich jetzt festgestelklt habe, habe ich keine Optimierung
> verwendet. Also O0..

Benutze -Os. Dann klappt das auch mit delay.h. Ausserdem wird der vom 
Compiler erzeugte Code auf ca. die Hälfte schrumpfen.

von Fabian B. (nase1987)


Lesenswert?

Ich benutze das Atmel Evaluationboard V2.01

Der Code
1
#include<avr/io.h>
2
#include<util/delay.h>
3
4
5
int mode_o = 1; //Variable fuer obere LED - Farbmodus
6
int mode_u = 8; //Variable fuer untere LED - Farbmodus
7
8
int blink = 0; //Variable fuer den Blinkmodus
9
10
int fest = 0;  //Variable für Zuweisung welche LED Blinkt
11
12
int n1 =10; //Variable fuer An1
13
int m1 =0; //Variable fuer Pause1
14
15
int n2 =10; //Variable fuer An2
16
int m2 =0; //Variable fuer Pause2
17
18
int b= 9;  //Durchlaufvariable für Farbverlauf
19
20
int a;
21
22
int main(void)
23
{  
24
  DDRD = 0x00;
25
    DDRB = (1<<DDB0) | (1<< DDB1) | (1 << DDB2) | (1<<DDB3) | (1<< DDB4) | (1 << DDB5);  
26
27
  PORTB &= 0x00;
28
  
29
  while (1)
30
    {
31
32
      //loop_until_bit_is_set(PIND, PD4);
33
34
      if((PIND & 0x20)) //Mode_o - taster 4
35
      {
36
        PORTB &= 0x00;
37
        _delay_ms(500);
38
        mode_o += 1;
39
        if (mode_o >= 9)  
40
        {
41
          mode_o = 1;
42
        }
43
  
44
    
45
      }
46
47
      if ((PIND & 0x04)) //Mode_u - taster 1
48
      { 
49
          PORTB &= 0x00;
50
          _delay_ms(500);
51
          mode_u += 8;
52
          if(mode_u > 64)
53
          {
54
            mode_u = 8;
55
          }
56
      }
57
58
      if((PIND & 0x08))  //Festlegung Blink -Taster2
59
      {
60
        PORTB &= 0x00;
61
        _delay_ms(500);
62
        blink += 1;
63
        if(blink >= 6)
64
        {  blink = 0;    }
65
66
        if ( blink ==0)
67
        {  n1 =6;
68
          m1 =3;
69
          n2 =6;
70
          m2 =3;
71
                }
72
        if (blink ==1)
73
        {  n1=100;
74
          m1=50;
75
          n2 =100;
76
          m2 =50;
77
                }
78
        if (blink ==2)
79
        {  n1=200;
80
          m1=200;
81
          n2 =200;
82
          m2 =200;
83
                }
84
        if (blink ==3)
85
        {  n1=200;
86
          m1=300;
87
          n2 =100;
88
          m2 =300;
89
                }    
90
        if (blink ==4)
91
        {  n1=500;
92
          m1=200;
93
          n2 =200;
94
          m2 =500;
95
                }
96
        if (blink ==5)
97
        {  n1=1000;
98
          m1=500;
99
          n2 =1000;
100
          m2 =500;
101
                }
102
      }
103
104
105
      if((PIND & 0x10))  //Festlegung Fest - Taster 3
106
      {
107
          PORTB &= 0x00;
108
          _delay_ms(400);
109
          fest += 1;
110
          if(fest >= 3)
111
          {
112
            fest = 0;
113
          }
114
      }
115
    
116
      a = mode_o +mode_u;
117
  
118
//_______________________________________________________________
119
    if( mode_u <=63)
120
    {  
121
      if (mode_o <=7)
122
      {
123
        if (fest ==0) //beide das gleiche Blinken
124
        {   PORTB |= a;
125
          _delay_ms(n1);
126
          PORTB &= 0;
127
          _delay_ms(m1);
128
          PORTB |= a;
129
          _delay_ms(n2);
130
          PORTB &= 0;
131
          _delay_ms(m2);
132
        }
133
134
        if (fest ==1) //obere blinkt
135
        {  PORTB |= a;
136
          _delay_ms(n1);
137
          PORTB &= mode_o;
138
          _delay_ms(m1);
139
            PORTB |= a;
140
          _delay_ms(n2);
141
          PORTB &= mode_o;
142
          _delay_ms(m2);
143
        }
144
145
        if (fest ==2) //untere blinkt
146
        {  PORTB |= a;
147
          _delay_ms(n1);
148
          PORTB &= mode_u;
149
          _delay_ms(m1);
150
          PORTB |= a;
151
          _delay_ms(n2);
152
          PORTB &= mode_u;
153
          _delay_ms(m2);
154
        }
155
      }
156
    }
157
//___________________________________________________________________
158
159
    if (mode_o >=8) //obere durchlaufen
160
    {  if (mode_u <=56) // obere durchlaufen /untere dauerfarbe
161
      {
162
        b = 1 + mode_u;
163
        while (b<=6+mode_u)
164
        {
165
          PORTB |= b;
166
          _delay_ms(n1);
167
          PORTB &= 0;
168
          _delay_ms (m1);
169
          b += 1;
170
  
171
          PORTB |= b;
172
          _delay_ms(n2);
173
          PORTB &= 0;
174
          _delay_ms (m2);
175
          b += 1;
176
        }
177
      }
178
    }
179
180
    if (mode_u == 64) //untere durchlaufend
181
    {
182
      if (mode_o >= 8) // beide durchlaufend
183
      {
184
        b = 9;
185
        while (b<= mode_o+ 56)
186
        {   
187
          PORTB |= b;
188
          _delay_ms(n1);
189
          PORTB &= 0;
190
          _delay_ms (m1);
191
          b += 9;
192
      
193
          PORTB |= b;
194
          _delay_ms(n2);
195
          PORTB &= 0;
196
          _delay_ms (m2);
197
          b += 9;
198
        }
199
      }
200
      if (mode_o <=7)    //untere durchlaufen / obere dauerfarbe
201
      {
202
        b = mode_o + 8;
203
        while (b<=mode_o + 56)
204
        {
205
          PORTB |= b;
206
          _delay_ms(n1);
207
          PORTB &= 0;
208
          PORTB |= mode_o;
209
          _delay_ms (m1);
210
          b += 8;
211
      
212
          PORTB |= b;
213
          _delay_ms(n2);
214
          PORTB &= 0;
215
          PORTB |= mode_o;
216
          _delay_ms (m2);
217
          b += 8;
218
        }
219
      }
220
221
      
222
    }
223
  }
224
  
225
while (1);  
226
227
return 0;
228
}

und ja ihr habt beide recht ^^ ... habe mapefile und listfile mit 
erstellt... wo finde ich die denn jetzt??? bzw. welche endung haben 
sie...

habe halt erst angefangen mit microcontroller programmieren... hatte 
gehofft das mit mein 1 Semester einführung in C++ etwas weiterhilft, 
aber das war eher ein trugschluss :D

Gruß
Fabian

P.S: Danke für die Hilfe

von oldmax (Gast)


Lesenswert?

Hi
Also, wenn das bisschen Code es schafft, den Speicher von einem Atmega16 
vollzurammeln, dann werd ich sofort vergessen, das ich mit dem Gedanken 
gespielt hab, ein wenig C zu lernen.....
Da läuft etwas anderes schief. Könnte es sein, das hier Bibliotheken 
eingebunden werden, die nicht erforderlich sind? Selbst dann ist es mir 
ein Rätsel, wie mit so wenig Code ein Speicher voll werden kann.
Gruß oldmax

von Thomas E. (thomase)


Lesenswert?

Fabian Bade schrieb:
> _delay_ms (m2);
Das geht gar nicht. _delay_ms darf nur mit Konstanten benutzt werden.

Und dann poste deinen Code mal als Anhang.
Kompilierbar, 0 Errors, 0 Warnings.

mfg.

von Oliver (Gast)


Lesenswert?

>c:\programme\atmel\avr tools\avr 
>toolchain\bin\../lib/gcc/avr/4.4.3/../../../../avr/include/util/delay.h :12>0: 
error: __builtin_avr_delay_cycles expects an integer constant.

Man sollte die Fehlermeldungen des Compilers schon ernst nehmen.

delay geht NUR mit einer Konstante, ansonsten explodiert dein 
Speicher...

Oliver

von MWS (Gast)


Lesenswert?

Thomas Eckmann schrieb:
> Das geht gar nicht. _delay_ms darf nur mit Konstanten benutzt werden.

Das ist falsch. Richtig wäre "sollte".

von Thomas E. (thomase)


Lesenswert?

MWS schrieb:
> Das ist falsch. Richtig wäre "sollte".
Richtig ist, daß dein Kommentar vollkommen überflüssig ist.

mfg.

von MWS (Gast)


Lesenswert?

Thomas Eckmann schrieb:
> Einzig richtig ist, daß dein Kommentar vollkommen überflüssig ist.

Nö, ist er nicht. Woher sollst Du sonst wissen, wie's richtig ist ? :D
Ja, stimmt, lesen der Doku würd' helfen.

von Fabian B. (nase1987)


Lesenswert?

Also liegt der ausgenutzte Speicher nur daran das ich im _delay_ms eine 
variable verwende, anstatt eine Konstante ?!? Weil laufen tut das 
Programm ja, nur das ich ( vor dem anschalten der optimierung) zu wenig 
speicherplatz hatte... was sich jetzt ja auch erledigt hat  dank eurer 
hilfe

von Peter II (Gast)


Lesenswert?

Fabian Bade schrieb:
> Weil laufen tut das
> Programm ja

aber vermutlich nicht mit den richtigen Zeiten. Die wartenzeiten werden 
damit nicht eingehalten.

schreibt dir selber eine funktion wie:

void delay_ms( ms unsigned int ) {
   while ( ms-- )
      _delay_ms( 1 )
}

dann kann du sie mit einer variable aufrufen, und dein Programm wird 
noch mal viel kleiner. Der Nachteil der dadurch ensteht ist das das 
delay_ms immer etwas (ein paar µs ) länger derauert als vorgegeben, 
sollte aber bei dir egal sein.

von Thomas E. (thomase)


Lesenswert?

MWS schrieb:
> Ja, stimmt, lesen der Doku würd' helfen.
Deine Kommentare werden leider immer überflüssiger.

Hilfreich wäre es aber, die aktuellen Tools zu benutzen, die bei 
Verwendung einer Varaiablen eine Fehlermeldung ausgeben:

:28: error: __builtin_avr_delay_cycles expects an integer constant.

mfg.

von MWS (Gast)


Lesenswert?

Thomas Eckmann schrieb:
> Hilfreich wäre es aber die aktuellen Tools zu benutzen, die bei
> Verwendung einer Varaiablen eine Fehlermeldung ausgeben:

Ach, wenn Du etwas weniger eingebildet wärst und dem TO erklärt hättest, 
warum der von ihm compilierbare Code nicht gehen soll, das wäre 
hilfreich gewesen.

Und wenn Du schon meinst, er solle aktuelle Tools benutzen, warum 
schreibst Du ihm das dann nicht einfach ?

Dicke Hose machen und nix dahinter.

Tatsächlich war der Code für den TO compilierbar und die variable 
Zeitangabe hat ihm die Fließkommalibrary mit reingewurstelt und seinen 
Code aufgebläht. Und dass der TO jetzt nicht der Profi ist, ohne das 
abwertend zu meinen, sieht man doch bereits an der Codegestaltung. Wie 
soll er da die Problematik des als Variablen übergebenen Parameters in 
der _delay_ms kennen ?

Nimm Dir 'n Beispiel an Peter II, der hat wenigstens was konstruktives 
gepostet.

von Thomas E. (thomase)


Lesenswert?

MWS schrieb:
> Dicke Hose machen und nix dahinter.
Du läufst ja richtig zur Hochform auf.

MWS schrieb:
> Das ist falsch. Richtig wäre "sollte".
Vergiss' aber bitte nicht, daß du mit dieser kleinkarierten Kacke 
angefangen hast.

mfg.

von MWS (Gast)


Lesenswert?

Thomas Eckmann schrieb:
> Vergiss' aber bitte nicht, daß du mit dieser kleinkarierten Kacke
> angefangen hast.

Nö, ist doch nicht kleinkariert.
Kleinkariert ist's dem TO zu sagen "darf nicht" und zu verschweigen 
warum.

Denn in der Version des TO ging's offensichtlich, da würd' ich mich an 
dessen Stelle auch fragen, "Wieso? Geht doch"

Also wurdest Du doch nur so behandelt, wie Du andere behandelt hast. Und 
das ist ok so.

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
Noch kein Account? Hier anmelden.