Guten Morgen zusammen, da ich eine "zeitkritische" anwendung habe, aber keinen Timer verwenden möchte, nutze ich die delay funktion. (Es soll ein eierkocher werden) Auf 1 oder 2 sekunden kommt es nicht an... Leider habe ich das Problem, dass die Funktion teilweise um den Faktor 10 falsch geht. Es ist ein MEga8, mit 16mhz quarz. Die fuses wurden dazu passend gesetzt. Mit der _delay_ms(x) funktion könnte ich bei diesem takt ca. 16ms ohne "fehler" anzeigen lassen. Danach soll eine abweichung von ca. 1/10 herauskommen. (Aktuell habe ich vier mal ein 250ms delay hintereinander) Jetzt etwas komisches: Wenn ich den CPU Takt als 1,6M Hz definiere, läuft das ganze einwandfrei. Ist dies ein Fehler der Funktion? Oder sollte ich stattdessen wieder auf 16Mhz "definieren" und etwas anderes machen? Vielen Dank
A.D. schrieb: > dass die Funktion teilweise um den Faktor 10 falsch geht. Zu welchem Teil? Welche Programmiersprache? Zeig doch besser mal, was du hast und sag dann, was du erwartest, und was nicht geht. Das Stichwort dazu heißt Netiquette... :-/
Arbeitest du mit AVRStudio? Hast du die Frequenz in der Programmeigenschaft angegeben oder mit #define F_CPU 16000000UL? Hast du die Optimierungen eingeschaltet? Ich mach das Ganze immer mit: void long_delay(uint16_t ms) { for(; ms>0; ms--) _delay_ms(1); } Funktionierte bei mir bis jetzt einwandfrei...
@ A.D. (Gast) >da ich eine "zeitkritische" anwendung habe, aber keinen Timer verwenden >möchte, Warum? Timerallergie? > nutze ich die delay funktion. (Es soll ein eierkocher werden) ;-) >dass die Funktion teilweise um den Faktor 10 falsch geht. Lass mich raten? Du verwendest eine variable Verzögerungszeit? Das geht nicht. http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Warteschleifen_.28delay.h.29 >Es ist ein MEga8, mit 16mhz quarz. Genau das richtige fpr eine Eieruhr, 16 MHz POWER, yeahhh!!! >Wenn ich den CPU Takt als 1,6M Hz definiere, läuft das ganze >einwandfrei. >Ist dies ein Fehler der Funktion? Kaum. >Oder sollte ich stattdessen wieder auf 16Mhz "definieren" und etwas >anderes machen? Ja, über deine wahrscheinlich falschen AVR-Fuses. ICh tippe mal, dein AVR läuft mit internem 1MHz RC-Oszillator. MFG Falk
Also, ich habe einen USB ASP und habe den Khazama AVR Brenner, Dort habe ich bei L Fuse EXT. Crystal angegeben (high frequency). Ich schätze also, dass die Kiste auf 16Mhz läuft. Leider kann ich das quarz nicht "abhängen" um es zu testen. Programmiersprache ist C. (AVR studio mit dem GNU C Compiler). Der Takt ist über #ifndef F_CPU #define F_CPU 16000000 #endif Sowie über AVR Studio definiert. (Dort habe ich controllertyp und geschwindigkeit eingetragen). Ich habe in die Delay funktionen immer die Zeit eingetragen, keine variablen verwendet. (Ich schätze, dass der compiler dies braucht, damit die funktion korrekt arbeitet?) Wo kann man die optimierung einschalten? Ich habe das hilfe menue des AVR studio bemüht und optimize eingetippt. Dort kommt aber nur etwas zum stk 500.
A.D. schrieb: > Sowie über AVR Studio definiert. (Dort habe ich controllertyp und > geschwindigkeit eingetragen). und was hast du da eingetragen? Eine 0 zu wenig?
A.D. schrieb: > Wo kann man die optimierung einschalten? > Ich habe das hilfe menue des AVR studio bemüht und optimize eingetippt. > Dort kommt aber nur etwas zum stk 500. Im AVR-Studio gibts ein Dropdown-Menü mit so Sachen wie "-O2 -O1 -Os" usw. Da "irgendwas" einstellen, aber NICHT -O0
Hannes Jochriem schrieb: > void long_delay(uint16_t ms) > { > for(; ms>0; ms--) > _delay_ms(1); > } das schon probiert? die eingebauten delay fkt. vertragen nur ein gewisses maximum
Also das Drop Down menue habe ich nicht gefunden. Ihr dürft mich steinigen! (Also Faktor 8 Falsch, dazu noch die Tatsache, dass hochfrequenz quarz gewählt...) Ich habe mich wohl beim löten vergriffen und ein 2Mhz Quarz eingelötet :( So, jetzt habe ich den INTERNEN oszillator mit 1Mhz eingeschaltet (da ich nicht sicher bin ob 2Mhz low oder medium ist). Den Takt habe ich in AVR studio auf 1Mhz geändert. Jetzt stimmt die Zeit :)
A.D. schrieb: > Ich schätze also, dass die Kiste auf 16Mhz läuft. Leider kann ich das > quarz nicht "abhängen" um es zu testen. Macht ja nichts. Du kannst ja ein Programm schreiben um es zu testen Pseudocode:
1 | #define F_CPU 16000000
|
2 | |
3 | #include <avr/io.h> |
4 | #include <utils/delay.h> |
5 | |
6 | int main() |
7 | {
|
8 | DDR_LED = Ausgang; // wo auch immer du eine LED hast oder |
9 | // sonst irgendwas mit dm du ganz klar sagen
|
10 | // sagen kannst, ob ein Ausgang 0 oder 1 ist
|
11 | |
12 | |
13 | while( 1 ) { |
14 | |
15 | PORT_LED = aus; // deinen Indikator ausschalten |
16 | _delay_ms( 1000 ); // 1 Sekunde warten |
17 | |
18 | PORT_LED = ein; // den Indikator einschalten |
19 | _delay_ms( 1000 ); |
20 | }
|
21 | }
|
entweder dein Indikator ändert alle 1 Sekunde den Zustand (dann läuft der µC mit 16Mhz) oder er tut es nicht (dann läuft er nicht mit 16Mhz). Da es in den meisten Fällen so ist, dass die Fragestellung "16Mhz oder 1Mhz" lautet, kann man dann aus dem beobachteten Verhalten auch noch Rückschlüsse über die Fehlerursache ziehen. Zwischen 1 Sekunde und 16 Sekunden ist nun mal ein großer Unterschied, den man leicht mit freiem Auge erkennen kann :-) Ganz einfach.
A.D. schrieb: > So, jetzt habe ich den INTERNEN oszillator mit 1Mhz eingeschaltet (da > ich nicht sicher bin ob 2Mhz low oder medium ist). 2Mhz ist Low.
So ein "blinke" Programm hatte ich mir gerade ebend auch geschrieben. Mit meinem quarz ist es halt deutlich länger, als es sein sollte. (die funktion scheint ja nur nichts zu tun (abhängig vom takt))
A.D. schrieb: > So ein "blinke" Programm hatte ich mir gerade ebend auch geschrieben. > > Mit meinem quarz ist es halt deutlich länger, als es sein sollte. > > (die funktion scheint ja nur nichts zu tun (abhängig vom takt)) Ganz genau. Und der Compiler rechnet abhängig von der in F_CPU angegebenen Taktfrequenz aus, wieviele Befehle lang der AVR 'nichts tun soll'. Ist deine Angabe von F_CPU korrekt und stimmt die mit der Realität überein, so kommt dann auch das richtige raus und der µC tut tatsächlich ziemlich genau solange nichts, wie du angegeben hast. Nur wenn dein F_CPU nicht mit der Realität übereinstimmt, dann stimmen klarerweise auch die Zeiten nicht.
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.