Hallo,
ich benutze die util/delay.h in meinem Code.
Sieht so aus:
#define delayms 1
void waitms (uint16_t ms){
for(ms;ms>0;ms--)_delay_ms(delayms);
}
Aufruf im Programm:
waitms(100);
Wieso verdammt funktioniert die waitms Schleife nicht richtig?!?
Wenn ich nur z.B:_delay_ms(10); benutze geht es ja auch...(im zulässigen
rahmen von 16mhz F_CPU)
Ich verstehe nicht wie es sein kann, dass ich nicht einfach 100 mal eine
milli Sekunde warten kann. 1 milli Sekunde wird ja voll von dem Makro in
der delay.h abgedeckt...
Hat da vielleicht einer eien Tipp?
Danke schonmal
Grüße Daniel
>_delay_ms(delayms);
_delay_ms() funktioniert nur mit Konstanten.
Mit Variablen gibt es unangenehme Nebeneffekte.
Nur so geht das:
void waitms (uint16_t ms){
for(ms;ms>0;ms--)_delay_ms(1);
}
@ holger (Gast)
>_delay_ms() funktioniert nur mit Konstanten.>Mit Variablen gibt es unangenehme Nebeneffekte.
Guten Morgen. delayms ist eine Konstante über #define.
Das Problem liegt woanders. Vollständiger Quelltext wäre hilfreich.
MFG
Falk
So definiere ich F_CPU
#define F_CPU 16000000
#include <util/delay.h>
Quelltext als Anhang.
Äh wieso kann ich keine zip Datei anhängen?!?
Mann, klappt auch garnix grad !
Na ja, also der ganze Controller bleibt irgedwie hängen, als wenn das
delay einfach mal so 3-10 Sekunden braucht, sehr seltsam...
also denke schon,
da wenn ich z.B. _delay_ms(10); benutze,
alles funktioniert, der ADC der USART und die Ports...
Also eigentlich sollte der Code doch funktionieren oder?
@ Daniel Rau (zerrome)
>Also eigentlich sollte der Code doch funktionieren oder?
Ein paar Anmerkungen.
sei() als ersten Befehl in main ist sehr gewagt. ZUERST muss man alles
initialisieren, sei() kammt dann am Schluss! Kurz vor der Endlosschleife
von main(). Ausserdem bin ich nicht ganz sicher, wie der Compiler das
statement ms interpretiert. Die Variable Warteschleife im Tutorila ist
anders. Nämlich so.
1
voidwaitms(uint16_tms){//waitms bis max 65535 ms wegen uint16_t
Falk Brunner wrote:
> Ausserdem bin ich nicht ganz sicher, wie der Compiler das> statement ms interpretiert.
Ich würde vermuten, dass er beim Einschalten aller Warnungen etwas
von sich gibt wie "Statement has no effect". Stört aber auch nicht.
Daniel, wenn du schreibst, dass _delay_ms(10) funktioniert: hast du
die Zeit dabei auch nachgemessen? Oder könnten das auch 160 ms
sein?
Ich fürchte einfach mal, dein AVR läuft noch mit 1 MHz und du hast
jeweils schon vor Ablauf von 16 Sekunden (ist eine verdammt lange
Zeit, wenn man auf etwas wartet ;-) kalte Füße bekommen und gesagt:
,,Geht nicht!''.
Hallo,
1.
also der AVR läuft auf jeden fall mit externem 16mhz Quarz, die fuses
sind so gesetzt und der uart funktioniert, was für mich eigentlich auch
ein Beweis dafür ist, dass die 16 mhz eingestellt sind (die Baudrate
errechnet sich ja anhand des Taktes).
2.
nein hab die 10 ms nicht gemessen, da ich kein Oszi oder Frequenz-messer
habe, sind mehr gefühlte 10 ms (160ms wären ja schon weniger als 10 hz
das könnte man mit ner led sogar sehen, was eideutig nicht so ist)
3.
sei() an anderer Stelle macht schon mehr sinn,
wenn man mal drüber nachdenkt :)
4.
hab die waitms schleife mal auf
1
for(;wms>0;wms--)_delay_ms(delay1ms);
geändert.
Wenn ich jetzt in der Eendlosschleife der main
1
waitms(15);
schreibe, macht der Controller einen totalen reset,
was sehr seltsam ist !
Bin ziemlich ratlos!
@ Daniel Rau (zerrome)
>schreibe, macht der Controller einen totalen reset,>was sehr seltsam ist !
Hast du im AVR-Studio den richtigen Prozessortyp eingestellt? Das klingt
nach Stackproblemen.
MfG
Falk
Hab grade was rumprobiert,
wenn ich in der waitms Schleife die übergebene Variable nochmal quasi
lokal in der Funktion speichere macht der Controller keinen reset,
kleiner Vortschritt...
Ich vermute, dein RAM ist einfach zu voll.
Das Runterzählen des Parameters (statt einer lokalen Variable) muss
auch funktionieren. Ich staune sogar, dass der Compiler nicht
überhaupt gleichen Code aus beiden generiert.
Hab mich da an eine lang vergangene c Programmier Stunde erinnert, es
ist wegen was auch immer, wohl ein Unterschied ob die Variable übergeben
wird oder übergeben wird und nochmal gespeichert (außer dem
verschwendeten Platz)...
Kann man irgendwie rausfinden wie voll der Ram ist? Oder muss ich
variablen zählen?
Daniel Rau wrote:
> Hab mich da an eine lang vergangene c Programmier Stunde erinnert, es> ist wegen was auch immer, wohl ein Unterschied ob die Variable übergeben> wird oder übergeben wird und nochmal gespeichert (außer dem> verschwendeten Platz)...
Nein, ein Funktionsparameter ist effektiv eine lokale Variable
innerhalb der Funktion. Hier der Vergleich:
1
#include<stdint.h>
2
3
#define F_CPU 16000000UL
4
#include<util/delay.h>
5
6
void
7
delay_ms(uint16_tms){
8
while(--ms)_delay_ms(1);
9
}
Generierter Code:
1
.global delay_ms
2
.type delay_ms, @function
3
delay_ms:
4
/* prologue: frame size=0 */
5
/* prologue end (size=0) */
6
movw r18,r24
7
rjmp .L2
8
.L3:
9
ldi r24,lo8(4000)
10
ldi r25,hi8(4000)
11
/* #APP */
12
1: sbiw r24,1
13
brne 1b
14
/* #NOAPP */
15
.L2:
16
subi r18,lo8(-(-1))
17
sbci r19,hi8(-(-1))
18
brne .L3
19
/* epilogue: frame size=0 */
20
ret
21
/* epilogue end (size=1) */
22
/* function delay_ms size 14 (13) */
Und mit:
1
#include<stdint.h>
2
3
#define F_CPU 16000000UL
4
#include<util/delay.h>
5
6
void
7
delay_ms(uint16_tms){
8
uint16_tcopy=ms;
9
while(--copy)_delay_ms(1);
10
}
ergibt sich:
1
.global delay_ms
2
.type delay_ms, @function
3
delay_ms:
4
/* prologue: frame size=0 */
5
/* prologue end (size=0) */
6
movw r18,r24
7
rjmp .L2
8
.L3:
9
ldi r24,lo8(4000)
10
ldi r25,hi8(4000)
11
/* #APP */
12
1: sbiw r24,1
13
brne 1b
14
/* #NOAPP */
15
.L2:
16
subi r18,lo8(-(-1))
17
sbci r19,hi8(-(-1))
18
brne .L3
19
/* epilogue: frame size=0 */
20
ret
21
/* epilogue end (size=1) */
22
/* function delay_ms size 14 (13) */
...auffällig dasselbe.
> Kann man irgendwie rausfinden wie voll der Ram ist?
avr-size
Daniel Rau wrote:
> Ich werd jetzt mal sehn ob ich nicht einfach nen timer nehme...
Das ist ultimativ sowieso die beste Methode, hilft aber auch nicht
gegen zu vollen RAM. ;-)