Forum: Mikrocontroller und Digitale Elektronik define_ms() und F_CPU


von Durokh (Gast)


Lesenswert?

Hi Leute,
auch auf die Gefahr hin, dass ich mich nun lächerlich mache...

Delay_ms() läuft bei mir ca. 4x langsamer, wie ich es eigentlich erwarte 
und ich habe keine Ahnung, woran es liegt.
1
#include <avr/io.h>
2
#include <avr/delay.h>
3
#define F_CPU 1000000UL
4
5
int main(void)
6
{
7
  DDRB |= (1<<PINB1);     // LED AN
8
    
9
  uint8_t loops = 100;  // Zähler
10
    
11
    while(1)
12
    {
13
    while (loops--)
14
    _delay_ms(10);
15
    
16
    PORTB ^= (1<<PINB1);  // Toggle LED    
17
    loops = 100;      // Zähler reset        
18
    }
19
}

Im AVR Studio (6) habe ich Internen Oszillator, 1MHZ, 64 ms 
Verzögerung(Default) eingestellt. (Kann man mit dem AVR Studio auch die 
Fusebits genau anschauen und nicht nur alles als Option auswählen?)

Ich habe nun alle möglichen Foren gewälzt, aber ich weiß nicht, woran es 
scheitert.
Fusebits müssen ja richtig sein, kann ich ja nur stumpf auswählen. Die 
F_CPU ist korrekt und delay_ms erhält keinen zu höhen Wert.


Was für einen Fehler mache ich?
Gruß,
Durokh

von Fabian O. (xfr)


Lesenswert?

Du musst F_CPU definieren bevor Du delay.h einbindest.

von Durokh (Gast)


Lesenswert?

Das hat bei mir keine Auswirkungen.

von Fabian O. (xfr)


Lesenswert?

Compiler-Optimierung eingeschaltet?

von Michael (Gast)


Lesenswert?

Durokh schrieb:
> Das hat bei mir keine Auswirkungen.

Trotzdem ist es Mist, mitten im Programm eine (evtl. andere) 
CPU-Frequenz festzulegen.

Was hast du im Compiler als Optimierungsstufe festgelegt?
Ohne Optimierung macht delay_ms() nur Müll. Gibt der Compiler 
irgendwelche Warnungen raus?

von Durokh (Gast)


Lesenswert?

Klar, gebe ich dir Recht, habe ich auch eher "verpennt".

Die Stufe ist O1.

Ansonsten meckert er maximal hier und das verstehe ich nun nicht so 
wirklich.
1
d:\programme\atmel\atmel studio 6.0\extensions\atmel\avrgcc\3.4.0.65\avrtoolchain\bin\../lib/gcc/avr/4.6.2/../../../../avr/include/avr/delay.h(36,2): 
2
#warning "This file has been moved to <util/delay.h>." [-Wcpp]
3
    Building file: .././LED-Controler-Test.c
4
5
6
7
Target "PreBuildEvent" skipped, due to false condition; ('$(PreBuildEvent)'!='') was evaluated as (''!='').

von troll (Gast)


Lesenswert?

Durokh schrieb:
> Die Stufe ist O1.
Os ist besser.

> Ansonsten meckert er maximal hier und das verstehe ich nun nicht so
> wirklich.
Einfach statt avr/delay.h util/delay.h schreiben.

von Durokh (Gast)


Lesenswert?

Das interessiert ihn leider auch nicht. :(

von Michael (Gast)


Lesenswert?

Durokh schrieb:
> Das interessiert ihn leider auch nicht. :(

Wenn die Warnung trotzdem noch auftaucht, compilierst/editierst du den 
falschen Code.

von Durokh (Gast)


Lesenswert?

Sorry, dann habe ich mich falsch ausgedrückt.
Die Warnung ist weg, aber das Delay_ms funktioniert dennoch nicht.

von Durokh (Gast)


Lesenswert?

Was mir bei der ganzen Sache nicht einleuchtet:
Wenn ich auf einen externen Quartz mit 16 mhz einstelle und dort einen 
Timer/Counter starte, macht der alles wie er es soll.

Delay_ms() hingegen macht was es will und läuft in diesem Falle sogar 
viel zu schnell....

von Andreas B. (andreasb)


Lesenswert?

Durokh schrieb:
> Was mir bei der ganzen Sache nicht einleuchtet:
> Wenn ich auf einen externen Quartz mit 16 mhz einstelle und dort einen
> Timer/Counter starte, macht der alles wie er es soll.

Der Timer / Counter ist direkt vom Quarz abhängig, und ist 
hardwaremässig.
Dieser stimmt daher immer "mit der Quarzfrequenz überein".

>
> Delay_ms() hingegen macht was es will und läuft in diesem Falle sogar
> viel zu schnell....

Dies ist Softwaremässig, und damit es funktioniert musst du F_CPU 
korrekt definiert haben.
Es handelt sich dabei um Zählschleifen, welche je nach F_CPU öfter oder 
weniger oft durchlaufen um die vorgegebene Zeit zu "verbraten".



mfg Andreas

von Georg G. (df2au)


Lesenswert?

Du hast 1MHz Takt deklariert. Aber was für ein Quarz hängt wirklich an 
dem Chip?

von Durokh (Gast)


Lesenswert?

Ich habe 2 Sachen getestet. Ein Mal mit interner clock und ein Mal mit 
externem quartz(16mhz).In beiden Fällen klappt der Counter, aber nicht 
das delay.
An sich wäre mir das ja egal,da ich eh nur den counter nutzen möchte. 
Aber da stimmt anscheinend etwas Grundsätzliches nicht....
Und da ich später noch mit der seriellen Schnittstelle arbeiten möchte 
...das wird dann ja mal gar nicht klappen,kann ich mir vorstellen.

von Durokh (Gast)


Lesenswert?

Nachtrag:Natürlich habe ich bei 16mhz extern die Deklaration auch 
geändert.

von Ralf G. (ralg)


Lesenswert?

Durokh schrieb:
> Delay_ms() läuft bei mir ca. 4x langsamer, wie ich es eigentlich erwarte
> und ich habe keine Ahnung, woran es liegt.

Durokh schrieb:
> Wenn ich auf einen externen Quartz mit 16 mhz einstelle und [...]
> Delay_ms() [...] läuft in diesem Falle sogar
> viel zu schnell....

4x zu schnell??

Durokh schrieb:
> Nachtrag:Natürlich habe ich bei 16mhz extern die Deklaration auch
> geändert.

Vor oder nach dem '#include <avr/delay.h>'?
Optimierung 'Os' eingestellt?

von Durokh (Gast)


Lesenswert?

ich meinte 4 x zu langsam.
Habe die Frequenz vor dem include definiert und os habe ich eingestellt 
:(

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Schau mal bitte in die Projekt Einstellungen und gib da den richtigen 
Prozessor und die effektive Taktfrequenz an. Das gesonderte definieren 
von F_CPU ist bei AS normalerweise nicht nötig, da im Makefile dann 
-DF_CPU XXXXXXX aus den Projekteinstellungen übernommen wird.

von Durokh (Gast)


Lesenswert?

Den Prozessor habe ich bereits ausgewählt. Die Taktfrequenz scheine ich 
nicht ändern zu können -- ist aber als '0' angegeben.

Die "fehlerhafte" Geschwindigkeit ändert sich auch mit unterschiedlichen 
F_CPU Einstellungen.

Wenn ich bspw. 1 MHZ internal Clock angebe und einstelle, läuft 
delay_ms() zu langsam. Stelle ich 2 MHZ internal Clock ein, ist es 
fast zeitgenau. Bei 8 MHZ ist er dann bspw. zu schnell...obwohl ich 
alles anpasse.

von Klaus (Gast)


Lesenswert?

Durokh schrieb:
> Stelle ich 2 MHZ internal Clock ein

Wie machst du denn das?

von Michael H. (michael_h45)


Lesenswert?

Beitrag "Re: _delay_ms() läuft 4 Mal schneller als erwartet"
Da ist allerdings von 4x zu schnell die Rede. Zusammen mit einem 
Taktteiler 8 wäre das dein Fehler.

von Durokh (Gast)


Lesenswert?

Oh Gott, habe den Fehler gefunden. Als ich mir gestern die delay.c File 
angeschaut habe, habe ich anscheinend aus versehen ein 'define f_cpu... 
' eingefügt, das noch in der Zwischenablage lag, und somit lief das Ding 
natürlich immer in diesem Takt und hat die von mir in der Hauptdatei 
angegebene Geschwindigkeit überschrieben.

Oh man. Na gut, Problem nun gelöst.

von Pete K. (pete77)


Lesenswert?

Das #define F_CPU gehört in die Projekteinstellungen vom AVR-Studio, wo 
Du auch den Prozessor einstellt.
In den .c und .h Files hat es nichts zu suchen.

von Michael (Gast)


Lesenswert?

Durokh schrieb:
> Oh Gott, habe den Fehler gefunden. Als ich mir gestern die delay.c File
> angeschaut habe, habe ich anscheinend aus versehen ein 'define f_cpu...
> ' eingefügt

Und ich sag noch:
Michael schrieb:
> Trotzdem ist es Mist, mitten im Programm eine (evtl. andere)
> CPU-Frequenz festzulegen.

von Markus (Gast)


Lesenswert?

...sinnigerweise gibt es im Studio 6 keinen direkten Punkt wo man die 
Frequenz festlegen kann.

Mann muss sowohl es bei den Toolchain-Einstellungen sowohl für den 
Compiler als auch Assembler als Symbol definierenl...

Grüße
Markus

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.