Forum: Mikrocontroller und Digitale Elektronik delay Funktion in AVR Studio


von Hans (Gast)


Lesenswert?

Hi!
Ich habe auch schon die Suchfunktion benutzt, aber die hat mir bis jetzt 
nicht helfen können.

Mein kleienr Quelltext sieht so aus, ich evrwende übrigens AVRStudio.
1
int main()
2
{
3
  DDRA |= (1<<PA0); // Pin als Ausgang definieren
4
  
5
  while(1)
6
  {
7
    _delay_ms(1);
8
    PORTA ^= (1<<PA0);
9
  }
10
}

Wenn ich jetzt mit dem Oszi schaue, zeigt er mir 1,666666 kHz an anstatt 
die eingestellten 1 kHz. Woran könnte dies liegen?

Ich habe bereits mehrer Optimeirungen durchprobiert.
Eigentlich sollte sie ja auf Os sein. Habe ichschon probiert. Auch bei 
O0 bis O3 war die Frequenz immer 1.6666 KHz.

Woran könnte es denn noch liegen=?

von Armin (Gast)


Lesenswert?

richtige Oszillatorfrequenz eingestellt? Muss sehr nahe bei den 
Optimierungen sein ;)

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Du hast einen gewissen Codeoverhead durch das while() und das 
Lesen/Ändern/Schreiben des PORTA-Pins. Das Timing ist deswegen nicht 
100% genau, selbst wenn _delay_ms(1) exakt 1 ms verzögern würde.

_delay_ms(1) arbeitet nur exakt, wenn F_CPU exakt definiert ist und 
hardwaremässig exakt arbeitet. Die Hardwaregenauigkeit ist bei 
verschiedenen Taktquellen (interner RC-Oszillator, externe Oszillatoren, 
Quarz) unterschiedlich.

von Hans (Gast)


Lesenswert?

Also ich verwende den ATmega16 mit einem 14.7456 MHz Quarz.

Bei "communication Project options" hatte ich bei Frequency erst nichts 
stehen, es änderte sich aber auch nichts, als ich 14745600 
reingeschrieben habe.

von Armin (Gast)


Lesenswert?

kannst du mit deinem oszi den Quarz direkt messen?
while dürfte höchstens 1, 2 zyklen dauern. Das ist ja nurn jump-Befehl. 
Wie lange das Auslesen dauert, wei ich nicht. Kann mir aber nicht 
vorstellen, dass das so viel ausmacht...


sonst hast du keine weiteren Sachen, die währenddessen ausgeführt 
werden; beispielsweise interrupts, die etwas rechenzeit brauchen?

von Hans (Gast)


Lesenswert?

Hi ich hatte vorhin geschrieben, dass beim Oszi 1kHz herauskommen 
müsste.

Wenn ich den Pin jede jede ms toggle, müsste die Frequenz natürlich 
500Hz sein. D.h. der Fehler ist ja noch größer...

1.6 kHz anstatt 500 Hz...

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Hans schrieb:
> Also ich verwende den ATmega16 mit einem 14.7456 MHz Quarz.
>
> Bei "communication Project options" hatte ich bei Frequency erst nichts
> stehen,

Verstehe ich nicht. Es sollte dann beim Übersetzen im Build-Fenster die 
Warnung kommen, dass F_CPU undefiniert ist und auf einen Defaultwert 
gesetzt wird.

> es änderte sich aber auch nichts, als ich 14745600
> reingeschrieben habe.

Bist du sicher, dass der Atmega16 auch die 14745600 Hz Taktquelle 
benutzt? Ist da z.B. ein externer Quarz richtig angeschlossen und sind 
die AVR Fuses entsprechend gesetzt?

von Hans (Gast)


Lesenswert?

JA, den Quarz habe ich auch gemesse...das sind genau die angegebenene 
14,7456 Mhz

von Hans (Gast)


Lesenswert?

Hm also ich habe die Fuses korrekt gesetzt. Das auf jeden Fall.

Habe es so gemacht wie hier:
Beitrag "Richtige Fuses mega16 & 16mhz quarz"

Klappte dann auch alles. habe ja auch schon größere Programme 
geschrieben. Die Timer haben auch perfekt funktioniert.

Aber F_CPU habe ich nirgends definiert. Die Timer liefen dennoch 
wunderbar.
Das delay klappt aber nicht....

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Was kommt raus, wenn du
1
_delay_ms(10);
schreibst?


> Aber F_CPU habe ich nirgends definiert.
Das ist schlecht, woher soll der Compiler wissen, wieviele Zyklen er 
verplempern soll?
> Die Timer liefen dennoch wunderbar.
Die berechnest ja auch du selber.

von Hans (Gast)


Lesenswert?

Okay. Und wo muss ich dann die Frequenz definieren?
Dieses makefile wird ja von AVR Studio selbst erstellt. Wie kann ich das 
denn darin ändern?

Oder schreib ich mir in die main.h einfach hin #define F_CPU 14745600

?

von Hans (Gast)


Lesenswert?

avr-gcc.exe  -mmcu=atmega16 -Wall -gdwarf-2 -std=gnu99 
-DF_CPU=14745600UL -Os -funsigned-char -funsigned-bitfields 
-fpack-struct -fshort-enums -MD -MP -MT main.o -MF dep/main.o.d  -c 
../main.c


Hier, nur diese Meldung bekomme ich. Damit kann ich aber nichts anfangen 
:-|

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Hans schrieb:
> Okay. Und wo muss ich dann die Frequenz definieren?
> Dieses makefile wird ja von AVR Studio selbst erstellt. Wie kann ich das
> denn darin ändern?

Project -> Configuration options -> Frequency (Wert eintragen)

> Oder schreib ich mir in die main.h einfach hin #define F_CPU 14745600

Ja, Vor das #include <util/delay.h> und mit der Typkennzeichnung UL 
oder L oder in Exponentialschreibweise

#define F_CPU 14.7456E6
#include <util/delay.h>

von Hans (Gast)


Lesenswert?

Jo, es passt auf einmal.
Habe es geschafft. Ich hatte den fehler gemacht, dass in einer schleife 
irgendwo doppelt F_CPU definiert war. Sorry für den Aufruhr hier.
Dachte, dei warnings sind wegen unused variablen

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Hans schrieb:

> avr-gcc.exe  -mmcu=atmega16 -Wall -gdwarf-2 -std=gnu99
> -DF_CPU=14745600UL -Os -funsigned-char -funsigned-bitfields
> -fpack-struct -fshort-enums -MD -MP -MT main.o -MF dep/main.o.d  -c
> ../main.c

Sieht doch gut aus. F_CPU wird in der Kommandozeile übergeben 
(-DF_CPU=14745600UL).

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.