Forum: Mikrocontroller und Digitale Elektronik Atmega 16MHz delay-Funktion


von Stefan (Gast)


Lesenswert?

Hallo zusammen,

ich verwende einen Atmega16 und betreibe ihn auf einem STK500 mit einem 
externen Quarz mit 16MHz. (Die Jumper XTAL1 und OSCSEL sind entsprechend 
eingestellt und der 16MHz Takt liegt nachgemessen am Controller an)

In einem ersten Versuch wollte ich an PortB die LED mit 1 Sekunde 
blinken lassen (siehe Programmausschnitt unten). Aus unerklärlichen 
Gründen läuft die standardmäßgie delay-funktion etwa 3mal so schnell ab 
wie sie sollte. Ich habe im Makefile und im Programm die F_CPU auf 16MHz 
eingestellt. Die Fuses ebenfalls auf "Ext. Crystal/Resonator High Freq.; 
Start-up time: 16K CK + 64ms" eingestellt.

Ich habe schon in anderen bestehenden Forenbeiträgen nach einer Lösung 
für mein Problem gesucht, leider erfolglos. Habt ihr einen Tipp für mich 
??

...
 while(1)
  {
   PORTB |= (1<<PB0);
   _delay_ms(1000);

   PORTB &= ~(1<<PB0);
   _delay_ms(1000);
   }

Gruß,
Stefan

von Tobi (Gast)


Lesenswert?

Auch daran gedacht F_CPU in der Einheit Hz anzugeben. F_CPU auch vor 
Einbinden der util/delay.h definiert?

von Stefan I. (keinwitz)


Lesenswert?

Gute Idee - beides mal Ja.

#ifndef F_CPU
#define F_CPU 16000000UL
#endif

#include <avr/io.h>
#include <stdint.h>
#include "lcd-routine.h"
#include <util/delay.h>

von Klaus W. (mfgkw)


Lesenswert?

Ein Schleifendurchlauf dauert nicht eine Sekunde lt. Quelltext, sondern 
2.

Hast du auch einen 16MHz-Quarz dran oder etwas anderes?

Compileroptionen?

von Stefan I. (keinwitz)


Lesenswert?

Die LED soll für jeweils 1 Sekunde ein/ausgeschaltet werden (reine 
Testfunktion). Die Compileroptimierung habe ich mit -0s und -01 
versucht.

16MHz Quarz ist sicher - mit Oszi nachgemessen.

von Rolf Magnus (Gast)


Lesenswert?

Stefan I. schrieb:
> Gute Idee - beides mal Ja.
>
> #ifndef F_CPU
> #define F_CPU 16000000UL
> #endif

Und es wird auch nicht schon auf der Kommandozeile mit einem anderen 
Wert definiert?

Stefan schrieb:
> Aus unerklärlichen
> Gründen läuft die standardmäßgie delay-funktion etwa 3mal so schnell ab
> wie sie sollte.

Es blinkt also ca. 1,5 mal pro Sekunde?

von Klaus W. (mfgkw)


Lesenswert?

Dann geht es auch - falls du es richtig beschrieben hast.
Im Zweifelsfall lieber das ganze Programm zeigen, Makefile und 
Fuseeinstellungen...

von Stefan I. (keinwitz)


Angehängte Dateien:

Lesenswert?

Hey,

ich hab jetzt mal quasi das gesamte projekt hochgeladen. Das 
Hauptprogramm steht in "Test.c".

Viele Dank schon mal für eure bisherige Hilfe!

von Julian B. (julinho)


Lesenswert?

Welche AVR-Version hast du?

Die älteren waren im Argument etwas beschränkt:

Siehe:

http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Warteschleifen_.28delay.h.29

von Klaus W. (mfgkw)


Lesenswert?

Hm, warum das jetzt zu langsam läuft weiß ich auch nicht.
- F_CPU scheint zu stimmen
- Optimierung ist an
- Die Fuses sind ok

Gem. Julian ist es einen Versuch wert, nicht 1000 ms zu warten
sondern lieber in einer Schleife tausendmal 1 ms.

Sonst fällt mir nicht nehr viel dazu ein.


Aber auch wenn es nicht die Ursache ist, folgender Vorschlag:
Du hast F_CPU an mehreren Stellen definiert, und kannst es
auch noch per Compileroption ändern.
Das ist mir zu fehlerträchtig; ich habe das nirgends in einem
Quelltext (schon gar nicht mir einem Defaultwert, der stillschweigend
genommen wird). Man merkt im Fehlerfall nicht, wenn mehrere Module
verschiedene Werte haben.
Stattdessen setze ich es nur per Compileroption an einer Stelle.

von Thomas E. (thomase)


Lesenswert?

Klaus Wachtler schrieb:
> Gem. Julian ist es einen Versuch wert, nicht 1000 ms zu warten
> sondern lieber in einer Schleife tausendmal 1 ms.

>Die älteren waren im Argument etwas beschränkt:

Daran hat sich auch gemäß delay.h - Library Reference nichts geändert:

void _delay_ms  ( double  __ms   )

Perform a delay of __ms milliseconds, using _delay_loop_2().

The macro F_CPU is supposed to be defined to a constant defining the CPU 
clock >frequency (in Hertz).

The maximal possible delay is 262.14 ms / F_CPU in MHz.

When the user request delay which exceed the maximum possible one, 
_delay_ms() provides a decreased resolution functionality. In this mode 
_delay_ms() will work with a resolution of 1/10 ms, providing delays up 
to 6.5535 seconds (independent from CPU frequency). The user will not be 
informed about decreased resolution.


mfg.

von Peter II (Gast)


Lesenswert?

lass das Programm noch mal im Simulator laufen und schau dir dort die 
Zeit an- Wenn sie dort stimm, dann stimmt etwas mit der Hardware nicht, 
wenn  sie dort nicht stimmt dann ist es ein Problem der Software

von Michael K. (Gast)


Lesenswert?

Lösche doch mal in lcd-routine.h bei
1
#ifndef F_CPU
2
#define F_CPU 16000000UL

das
1
#ifndef F_CPU
Dann meckert der Compiler, wenn F_CPU schon mal woanders definiert 
wurde.

42m

von Stefan I. (keinwitz)


Lesenswert?

Die Idee, das Programm mit dem Simulator zu testen war sehr gut. Bei der 
Simulation fällt auf, dass die Prozessorfrequenz 4 MHz beträgt, egal 
welche Einstellungen ich für die F_CPU im Programm oder per 
Konfiguration vornehm.

Bei 4MHz läuft auch die Funktion _delay_ms(1000) mit der richtigen Zeit 
ab. Auf welchen Fehler deutet das hin?

von Peter II (Gast)


Lesenswert?

Stefan I. schrieb:
> Bei der Simulation fällt auf, dass die Prozessorfrequenz 4 MHz beträgt
das liegt aber am simulator, das ist nur eine einstellung. Woher soll 
denn der Simaltor wissen wie schnell er laufen soll?

Wenn die Zeiten aber bei 4Mhz stimmen, dann hast du ein Fehler im 
Quellcode. Sie müssen bei 16Mhz stimmen.

von Stefan I. (keinwitz)


Lesenswert?

Ich habe mein komplettes Projekt kopiert, bei einem Freund kompiliert 
(Visual Studio 4.18, WinAVR 20100110) und auf den uC gespielt - und der 
Controller läuft mit der richtigen Frequenz. Ich verwende die gleichen 
Compiler. Wie kann das sein ???

von Klaus W. (mfgkw)


Lesenswert?

Stefan I. schrieb:
> (Visual Studio 4.18

für AVR?

von Stefan I. (keinwitz)


Lesenswert?

AVR Studio 4.18 - sorry ;-)

von Klaus (Gast)


Lesenswert?

Klaus Wachtler schrieb:
> Stefan I. schrieb:
>> (Visual Studio 4.18
>
> für AVR?

Man kann auch mit Visual Studio  AVRs Programmieren :-) Man muss halt 
win-avr als Custom build tool in VS einbinden. Das geht ziemlich gut, 
man hat dann eine richtige IDE zum Programmieren incl. Intellisense und 
so. Das ist um längen angenehmer als dieser bessere Texteditor 
AVR-Studio ;-)

von pedro (Gast)


Lesenswert?

Thomas Eckmann schrieb:
> Klaus Wachtler schrieb:
>> Gem. Julian ist es einen Versuch wert, nicht 1000 ms zu warten
>> sondern lieber in einer Schleife tausendmal 1 ms.
>
>>Die älteren waren im Argument etwas beschränkt:
>
> Daran hat sich auch gemäß delay.h - Library Reference nichts geändert:
>
> void _delay_ms  ( double  __ms   )
>
> Perform a delay of __ms milliseconds, using _delay_loop_2().
>
> The macro F_CPU is supposed to be defined to a constant defining the CPU
> clock >frequency (in Hertz).
>
> The maximal possible delay is 262.14 ms / F_CPU in MHz.
>
> When the user request delay which exceed the maximum possible one,
> _delay_ms() provides a decreased resolution functionality. In this mode
> _delay_ms() will work with a resolution of 1/10 ms, providing delays up
> to 6.5535 seconds (independent from CPU frequency). The user will not be
> informed about decreased resolution.
>
>

maximale 6.5535 sek / 16 (F_CPU in MHz) ergibt 0.41 sek

Tönt schon fast wie das von dir festgestellte 3-mal schneller Blinken, 
oder?
> mfg.

von Stefan I. (keinwitz)


Lesenswert?

** Das Wunder von Atmel **

Zunächst einmal vielen Dank für eure zahlreichen Beiträge. Nach dem klar 
war, dass mein Projekt mit einem anderen PC funktionsfähig auf den Atmel 
16 übertragen werden kann, habe ich WinAVR20100110 sowie AVR Studio 4.18 
deinstalliert und anschließend neu installiert - .... der Fehler ist 
behoben.

Für mich ist das zwar nicht nachvollziehbar aber: es läuft!

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.