mikrocontroller.net

Forum: Compiler & IDEs Delay -Problem


Autor: Walter M. (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich bin neu hier. Nach stundenlangem Suchen hier im Forum, habe ich
keine Antwort auf meinem Problem gefunden.

Ich bin von Bascom auf WinAVR umgestiegen. In dem Programm benutze ich
die "_delay_ms(50)"-Funktion. Aber ich kann machen was ich will, die
Zeiten stimmen nie. Auch eine Änderung von "#define F_CPU 7372800"
(Quarz und Fusbits sind korrekt) hat keinen Einfluss. Egal was ich
angebe, es ändert sich nichts.

Ich habe lange gesucht und weiß jetzt nicht mehr weiter. Jetzt bitte
ich hier um Rat.

Danke und schöne Grüße
Walter

Autor: zonk (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
#include <avr/delay.h>
#define FCLK 16e6
#define Delay_us(t) _delay_loop_2((uint16_t)(((t)*1e-6*FCLK)/4))

so hab ichs gemacht.sind allerdings us.

Autor: OldBug (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bei aktuellem WinAVR geht das ganze auch so:

#define F_CPU 14745600     /* Clock in HZ  */
#include <avr/delay.h>

[..]
    _delay_ms(25.5);       /* delay 25.5ms */
[..]

Autor: seacrash (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Walter,

ich benutze CodeVisonAVR und hatte mal das gleiche Problem.
Bei mir war´s eine falsche Einstellung der Clock-Frequenz in der
Entwicklungsumgebung. Ich weiß nicht, ob es diese Einstellung bei
WinAVR auch gibt, aber es wäre eine Fehler - Möglichkeit. An sonsten,
so wie OldBug def. bzw. dek., dann sollte es gehn.

Schreib mal ob du es hinbekommen hast.

Gruß
seacrash

Autor: Walter M. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke, erstmal für die Antworten.

ich habe das Problem vorerst mit einer Schleife gelöst. Später möchte
ich es aber eleganter lösen.
Ich meine, ich kann überall meine verwendete F_CPU = 7372800 eintragen
und es ändert sich nichts. Auch nicht, wenn ich nur 1MHz eintrage.
_delay_ms(200) entspricht momentan ca. 50ms.
Ich habe alles durchsucht.
Vielleicht hat jemand mal das gleiche Problem mal gehabt. Bitte
melden.

Grüße
Walter

Autor: Jörg Wunsch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Seltsam.  Du bist der Erste, der sowas erzählt.

Nur für alle Fälle: das ist auf einem realen Chip, nicht bloß im
Simulator, ja?

Autor: Walter M. (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo und danke,

ich hänge mal die "delay.h" dran. Es ist die, die im WinAVR mit
installiert wird.
Folgende Versionen sind dabei mit installiert worden:
- GCC: 3.4.3.
- avr-libc: 1.2.3.
Ich weiß nicht, ob es wirklich die aktuellen Versionen sind, die
Angaben habe ich aus der "WinAVR-user-manual.txt"-Datei.

Bitte verzeiht, ich mache gerade meine ersten Gehversuche mit GCC.

Walter

Autor: OldBug (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hm, Jörg:
Ich habe gerade mal Dein ledgame.c ausprobiert, und wollte da mal eine
echte RGBA-Leiste anklemmen. Habe da beim Starten einfach mal alle
Farben geschaltet und wollte dazwischen ein bißchen Pause machen
(q&d).

Ich habe die Zeiten jetzt nicht gemessen, aber 2 x _delay_ms(255) ist
viiiiieeeel zu flott...

Ich versuche mal, da genaueres rauszufinden...

Autor: OldBug (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hier mal ein kleines Testprogramm.
Ich habe mal _delay_ms(128.5) und _delay_ms(255) ausprobiert: für mich
sieht der erzeugte Code absolut identisch aus!?

Autor: Volkmar (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@OldBug:

Wenn ich mir die header-Datei anschaue und Deine Taktfrequenz
berücksichtige, dann komme ich auf maximal 17.777778ms. Beide von Dir
angegebenen Zeiten liegen darüber, also wird der Max-Wert genommen.
Daher ist der erzeugte Code gleich.

Volkmar

Autor: OldBug (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die Aussage versteh ich nicht ganz, denn laut avr/delay.h:

   Perform a delay of \c __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.


Sollte man maximal 262.14ms "einstellen" können...

Autor: Rufus T. Firefly (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du hast die Lösung des Problemes selbst zitiert:
  "  The maximal possible delay is 262.14 ms / F_CPU in MHz.

  Sollte man maximal 262.14ms "einstellen" können..."

Wenn F_CPU 1 MHz beträgt.
Du aber arbeitest mit 7.3728 MHz, also resultieren aus der Division
etwa 35 msec.

Autor: OldBug (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Naja, typischer Fall von "missunderstood" ;)

Nagut, ich sehs ein!

F_CPU beträgt allerdings 14745600Hz...

Autor: Rufus T. Firefly (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich hab' nur den Wert aus dem ersten Posting genommen ... da steht
7.irgendwas MHz.

Autor: Walter M. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielen Dank für die ganz Mühe.
Jetzt habe ich es auch gelesen. Es steht ja dabei.
Sorry. Beim nächsten mal muss ich es genau durchlesen.

Autor: Jörg Wunsch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Schade, dass man aus einer inline function nicht auch noch ein #error
(oder #warning) schmeißen kann, sonst hätte ich das gern getan, um all
diejenigen, die die Beschreibung nicht richtig lesen, mit der Nase
drauf zu drücken. ;-)

Ich hab's aber vorsätzlich nicht mit Präprozessor-Mimik gemacht,
damit
man auch Gleitkommaausdrücke benutzen kann.  Vielleicht hätte ich ja
bei Überlauf statt des Maximalwertes jeweils um 42 Takte verzögern
sollen, damit es den Leuten besser auffällt? :-)

Autor: OldBug (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also: ich habs einfach nur falsch verstanden.
Vielleicht wäre da ein kleines (ausführlicheres) Rechenbeispiel
angebracht!?

Autor: Tobi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bei meinem AT90S2323 habe ich genau das selbe Problem mit dem
_delay_ms() - Befehl.
Egal was ich im Makefile bei F_CPU oder bei #define F_CPU eingebe, die
delay-Zeiten sind nur bei einem Takt von 1 MHz korrekt.
Wenn ich z.B. einen Quarz mit 10 MHz anschliese und im Makefile
10000000 Hz eingebe, die delay-Zeiten sind trotzdem viel zu schnell.

Autor: Volkmar (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Tobi:

- Welches delay möchtest Du denn erreichen?
- In welcher Reihenfolge hast Du F_CPU definiert und die
Include-Anweisung?
- Hast Du noch andere defines für F_CPU?

Volkmar

Autor: Tobi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Volkmar,
zu 1:
Die delay-Zeiten bewegen sich zwischen 1 ms und 250 ms.
(bzw. mehrere _delay_ms (250) hintereinander um einige Sekunden zu
errreichen oder in einer Schleife mit einer bestimmten Anzahl von
Durchläufen.) Wie schon gesagt bei 1 MHz Takt stimmen die
delay-Zeiten.

zu 2:
F_CPU wird nur im Makefile definiert. Testweise hatte ich einmal F_CPU
im Makefile gelöscht und im Programm folgendes zuerst geschrieben:
#define FCPU = 10000000
#include <avr\delay.h>

zu 3:
Die Variable F_CPU verwende ich im gesamten Programm nicht.

Autor: Jörg Wunsch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> #define FCPU = 10000000

Ohne Gleichheitszeichen und F_CPU mit Unterstrich.  Sollte sich sonst
aber gar nicht compilieren lassen.

> #include <avr\delay.h>

<avr/delay.h> bitte, auch auf Windows.  (Windows hat kein Problem mit
einem Vorwärtsstrich als Verzeichnistrenner, nur command.com und
cmd.exe haben eins.)

Irgendwas musst du mit diesen Makros in der Tat versaut haben (ich
vermute mal, das oben waren nur Schreibfehler im Posting).  Kannst ja
mal den generierten Assemblercode ansehen.

Das 1 MHz ist der default-Wert in avr/delay.h.  Wenn der greift,
bekommst du aber auch eine Compilerwarnung gespuckt.  Hast du das mal
verifiziert?

Autor: Tobi (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Jörg,
sorry hatte den Text vorhin etwas zu schnell getippt.
<avr/delay.h>
Im Code stehts richtig, sonst würde der Compiler einen Fehler bringen.

Ich weiß, echt nicht mehr weiter !

Compiler Meldung: siehe Anhang
Schein mal alles in Ordnung zu sein.

Autor: Jörg Wunsch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
"make rgb.s"

Was steht dann da drin?

Autor: Volkmar (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Tobi,

Du hast geschrieben:
> Die delay-Zeiten bewegen sich zwischen 1 ms und 250 ms.
> (bzw. mehrere _delay_ms (250) hintereinander um einige Sekunden zu
> errreichen oder in einer Schleife mit einer bestimmten Anzahl von
> Durchläufen.) Wie schon gesagt bei 1 MHz Takt stimmen die
> delay-Zeiten.

sowie

> #define FCPU = 10000000

D.h. Du hast einen 10MHZ-Takt?

Aus dem Header-File:

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

D.h. Du kommst bei 10MHz auf maximal 26ms, die Du verwenden kannst. Wie
hoch sind denn die Delay-Zeiten, die Du erreichst?

Volkmar

Autor: Jörg Wunsch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Umm, ja, nachgerechnet hatte ich noch gar nicht...

26 ms wenn 250 gewünscht sind -- das klingt natürlich gut so,
als würde ein Takt von 1 MHz angenommen. ;-)

Ich hatte nicht erst gerechnet, weil Tobi so tat, als ob auch
die kürzeren Delays zu kurz geworden wären, aber wahrscheinlich
hat er die gar nicht erst nachgemessen...

Autor: tobi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Soll das also heißen, dass bei höherer Taktfrequnz die max. delay-Zeit
automatisch kleiner wird.
Also sind es bei 1 MHz noch 255 ms, dann sind es bei 10 MHz nur noch 25
ms ???
Dann muss ich nun wohl, um delay-Zeiten von mehreren 100 ms zu
erreichen wieder Schleifen mit 25 ms programmieren, oder gibts da eine
elegantere Lösung ?

Autor: Chris (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> oder gibts da eine elegantere Lösung ?

Ja, siehe Abschnitt "Timer" im Datenblatt.

Autor: Jörg Wunsch (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Soll das also heißen, dass bei höherer Taktfrequnz die
> max. delay-Zeit automatisch kleiner wird.

Klar, logisch, wie denn sonst?  Du hast halt maximal 64K Zyklen, die
diese kleinen Schleifen durchlaufen können.  Die sind zwanghaft bei
höherer Taktfrequenz dann schneller vorbei.

Autor: mru (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ungern wärme ich diesen Thread wieder auf, aber etwas Senf möchte ich 
doch dazugeben.

Diese Tage hatte ich eine Diskussion über util/delay.h - und über diesen 
Artikel. Eine Suche auf mikrocontroller.net mit "avr delay" liefert 
diesen Artikel als ersten Eintrag.

Ich kopiere aus meiner avr/delay.h:
/**
   \ingroup util_delay

   Perform a delay of \c __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.
 */
void
_delay_ms(double __ms)
{
  uint16_t __ticks;
  double __tmp = ((F_CPU) / 4e3) * __ms;
  if (__tmp < 1.0)
    __ticks = 1;
  else if (__tmp > 65535)
  {
    //  __ticks = requested delay in 1/10 ms
    __ticks = (uint16_t) (__ms * 10.0);
    while(__ticks)
    {
      // wait 1/10 ms
      _delay_loop_2(((F_CPU) / 4e3) / 10);
      __ticks --;
    }
    return;
  }
  else
    __ticks = (uint16_t)__tmp;
  _delay_loop_2(__ticks);
}

(avr-libc: 1:1.6.8-2, ubuntu)

Also:

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.



Hoffe den in Zukunft Suchenden etwas geholfen zu haben, und über sowas 
nicht mehr diskutieren zu müssen ;)

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.