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
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.
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)
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 ^^
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?!
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)
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)?
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..)
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.
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
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
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.
>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
Thomas Eckmann schrieb: > Das geht gar nicht. _delay_ms darf nur mit Konstanten benutzt werden. Das ist falsch. Richtig wäre "sollte".
MWS schrieb: > Das ist falsch. Richtig wäre "sollte". Richtig ist, daß dein Kommentar vollkommen überflüssig ist. mfg.
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.
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
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.
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.
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.
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.