Forum: Mikrocontroller und Digitale Elektronik delay funktion


von A.D. (Gast)


Lesenswert?

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

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

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... :-/

von Hannes J. (Firma: eHaJo.de) (joggl) Benutzerseite Flattr this


Lesenswert?

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...

von Falk B. (falk)


Lesenswert?

@  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

von A.D. (Gast)


Lesenswert?

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.

von Klaus W. (mfgkw)


Lesenswert?

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?

von Hannes J. (Firma: eHaJo.de) (joggl) Benutzerseite Flattr this


Lesenswert?

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

von ... .. (docean) Benutzerseite


Lesenswert?

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

von A.D. (Gast)


Lesenswert?

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 :)

von Karl H. (kbuchegg)


Lesenswert?

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.

von Karl H. (kbuchegg)


Lesenswert?

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.

von A.D. (Gast)


Lesenswert?

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))

von A.D. (Gast)


Lesenswert?

Vielen Dank für die Hilfe !!!

von Karl H. (kbuchegg)


Lesenswert?

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.

von A.D. (Gast)


Lesenswert?

Alles klar.

Danke nochmal für die Erklärung und Hilfestellung.

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.