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
#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.
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 */ [..]
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
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
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?
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
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...
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!?
@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
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...
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.
Naja, typischer Fall von "missunderstood" ;) Nagut, ich sehs ein! F_CPU beträgt allerdings 14745600Hz...
Ich hab' nur den Wert aus dem ersten Posting genommen ... da steht 7.irgendwas MHz.
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.
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? :-)
Also: ich habs einfach nur falsch verstanden. Vielleicht wäre da ein kleines (ausführlicheres) Rechenbeispiel angebracht!?
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.
@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
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.
> #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?
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.
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
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...
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 ?
> oder gibts da eine elegantere Lösung ?
Ja, siehe Abschnitt "Timer" im Datenblatt.
> 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.
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:
1 | /**
|
2 | \ingroup util_delay
|
3 | |
4 | Perform a delay of \c __ms milliseconds, using _delay_loop_2().
|
5 | |
6 | The macro F_CPU is supposed to be defined to a
|
7 | constant defining the CPU clock frequency (in Hertz).
|
8 | |
9 | The maximal possible delay is 262.14 ms / F_CPU in MHz.
|
10 | |
11 | When the user request delay which exceed the maximum possible one,
|
12 | _delay_ms() provides a decreased resolution functionality. In this
|
13 | mode _delay_ms() will work with a resolution of 1/10 ms, providing
|
14 | delays up to 6.5535 seconds (independent from CPU frequency). The
|
15 | user will not be informed about decreased resolution.
|
16 | */
|
17 | void
|
18 | _delay_ms(double __ms) |
19 | {
|
20 | uint16_t __ticks; |
21 | double __tmp = ((F_CPU) / 4e3) * __ms; |
22 | if (__tmp < 1.0) |
23 | __ticks = 1; |
24 | else if (__tmp > 65535) |
25 | {
|
26 | // __ticks = requested delay in 1/10 ms
|
27 | __ticks = (uint16_t) (__ms * 10.0); |
28 | while(__ticks) |
29 | {
|
30 | // wait 1/10 ms
|
31 | _delay_loop_2(((F_CPU) / 4e3) / 10); |
32 | __ticks --; |
33 | }
|
34 | return; |
35 | }
|
36 | else
|
37 | __ticks = (uint16_t)__tmp; |
38 | _delay_loop_2(__ticks); |
39 | }
|
(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 ;)
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.