mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Frage zu delay (wie bekomme ich genau 1 Sekunde)


Autor: Thomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo, habe ml eine ganz simple frage und zwar gibt es ja für delay 
einmal

delay_ms  für millisekunden und
delay_us  für mikrosekunden

richtig??

Wenn ich jetzt aber im Programm delay_ms(1000) benutze müsste das ja 
quasi 1Sekunde bedeuten. Ist es aber nicht. Ich verwende einen Atmega 32 
mit den internen 4MHz Quarz oder hat das auch was mit der eingestellten 
Taktfrequenz was zu tun ?

Gruß Thomas

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Thomas schrieb:
> Ist es aber nicht.
Was ist es denn?

> Ich verwende einen Atmega 32 mit den internen 4MHz Quarz
> oder hat das auch was mit der eingestellten Taktfrequenz was zu tun ?
Du hast ja 4 MHz eingestellt.
Nur mußt du das jetzt im C-Code auch noch angeben (einstellen tust du 
da nichts!). Das passiert mit F_CPU. Und denk daran, die Optimierung auf 
-Os zu stellen...

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@  Thomas (Gast)

>delay_ms  für millisekunden und
>delay_us  für mikrosekunden

>richtig??

Ja.

>Wenn ich jetzt aber im Programm delay_ms(1000) benutze müsste das ja
>quasi 1Sekunde bedeuten.

Ist auch so.

> Ist es aber nicht.

Dann ist was falsch eingestellt. Entweder die AVR Fuses oder dein 
F_CPU define im Quelltext.

> Ich verwende einen Atmega 32
>mit den internen 4MHz Quarz

Es gibt keinen internen Quarz, nur einen internen RC-Oszillator. Und der 
ist nur mäßig genau, so 1..5%.

MfG
Falk

Autor: Thomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok ich hab da jetzt mal ein
#define F_CPU 4000000

eingefügt aber wenn ich jetzt 10sec einstellen möchte mit delay macht 
der da höchstens 3 raus oder gibt es einen maximalen wert dür delay_ms ?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Thomas schrieb:
> Ok ich hab da jetzt mal ein
> #define F_CPU 4000000

Und?
Hast du deinen µC auch auf 4Mhz eingestellt (per Fuse)?


Bei F_CPU kannst du hinschreiben was du willst! Das ist einfach nur eine 
Zahl mit der gerechnet wird, nichts weiter. Nur weil du dort 8Mhz 
hinschreibst, heißt das noch lange nicht, dass dein µC auch tatsächlich 
mit 8Mhz arbeitet.

Auf einen Trabbi Tacho kann ich auch als Höchstgeschwindigkeit 320km/h 
hinschreiben. Hinschreiben kann ichs und der Fahrer kann das auch auf 
dem Tacho ablesen. Aber fahren, fahren wird der Trabbi weiterhin mit 80, 
solange ich nicht den Motor tausche.

> eingefügt aber wenn ich jetzt 10sec einstellen möchte mit delay macht
> der da höchstens 3 raus

Dann arbeitet dein µC nicht mit 4Mhz
So einfach ist das.

F_CPU ist eine Information für den Compiler. Und du solltest besser 
sicherstellen, dass diese Information mit der Realität übereinstimmt.

Autor: Thomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hab die Fuses grade noch mal ausgelesen also stehen definitiv auf

int Rc Osz. 4MHz; Start up Time: 6CK+ 4ms

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Thomas schrieb:
> hab die Fuses grade noch mal ausgelesen also stehen definitiv auf
>
> int Rc Osz. 4MHz; Start up Time: 6CK+ 4ms


dann zeig dein Programm

Es gibt 3 Dinge zu beachten:

* #define F_CPU 4000000
  bevor delay.h includiert wird!

* Den Optimizer vom Compiler einschalten

* Obergrenze der Zeit beachten (weis nicht auswendig wie hoch die liegt)
  steht aber in der Doku


Gegen vergessenen Optimizer kann man nicht viel tun. Aber wenn F_CPU 
nicht rechtzeitig definiert ist, ist delay.h so geschrieben, dass der 
Compiler eine Warnung ausgibt. Siehst du eine Warnung?

Autor: AKKS (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
http://www.mikrocontroller.net/articles/AVR-GCC-Tu...

_delay_ms() kann mit einem Argument bis 6553,5 ms (= 6,5535 Sekunden) 
benutzt werden

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> eingefügt aber wenn ich jetzt 10sec einstellen möchte mit delay macht
> der da höchstens 3 raus oder gibt es einen maximalen wert dür delay_ms ?
Bedieungsanleitung lesen:
http://de.wikibooks.org/wiki/C-Programmierung_mit_...
  _delay_ms() kann mit einem Argument bis 6553,5ms (= 6,5535 Sekunden) benutzt werden.
Und 10sec - 6,5sec = 3,5sec. Passt also.

EDIT: Pech, Zweiter...  :-/

Autor: Thomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hier ist der Codeausschnitt, den ich meine nach lade Eingaenge sollten 
das 10s sein nach delay
#include <stdio.h>
#include <stdlib.h>


#include "lc7981.h"
#include "graphics.h"
#include "touch.h"
#include "images.h"
#include "windows.h"

#define F_CPU 4000000

void print_start()
{

char str_koord[30];
char str_button_pressed[17];
  uint16_t x,y;
  str_koord[0] = '\0';
  str_button_pressed[0] = '\0';

while(1)
      {
  g_draw_string(1,1, "lade Eingaenge..");
//  _delay_ms(1500);
  g_draw_string(1,1, "lade Eingaenge....");
//  _delay_ms(1500);
  g_draw_string(1,1, "lade Eingaenge......");
//  _delay_ms(1500);
  g_draw_string(1,1, "lade Eingaenge........");
//  _delay_ms(1500);
  g_draw_string(1,1, "lade Eingaenge........ok");
  _delay_ms(10000);
  g_draw_string(1,10, "setze Ausgaenge..");
//  _delay_ms(1500);
  g_draw_string(1,10, "setze Ausgaenge....");
//  _delay_ms(1500);
  g_draw_string(1,10, "setze Ausgaenge......");
//  _delay_ms(1500);
  g_draw_string(1,10, "setze Ausgaenge......ok");
  _delay_ms(1500);
  g_draw_string(1,20, "hole Sensoren..");
//  _delay_ms(1500);
  g_draw_string(1,20, "hole Sensoren....");
//  _delay_ms(1500);
  g_draw_string(1,20, "hole Sensoren....ok");
  _delay_ms(1500);
  g_draw_string(1,30, "starte Menue..");
//  _delay_ms(1500);
  g_draw_string(1,30, "starte Menue....");
//  _delay_ms(1500);
  g_draw_string(1,30, "starte Menue......");
//  _delay_ms(1500);
  g_draw_string(1,30, "starte Menue........");
//  _delay_ms(1500);
  g_draw_string(1,30, "starte Menue........ok");
  _delay_ms(1500);
  
  g_draw_rectangle(8, 48, 33, 11);
  g_draw_string(10,50, "RESET");
  g_draw_rectangle(68, 48, 33, 11);
  g_draw_string(70,50, "START");

  x = touch_readX();
  y = touch_readY();

Autor: Thomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok dann könnte das ja doch passen, wenn ca6 s mx sind und ich hab
#include <util/delay.h> vergessen seh ich grade wohl

Autor: Thomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Aber demnach müsste das dann doch mit einem zweifachem aufruf klappen 
oder ?

delay_ms(5000);
delay_ms(5000);

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Thomas schrieb:
> Aber demnach müsste das dann doch mit einem zweifachem aufruf klappen
> oder ?
>
> delay_ms(5000);
> delay_ms(5000);

Sicher.
Du kannst aber auch
void delay_sec( uint8_t sec )
{
  while( sec-- )
    _delay_ms( 1000 );
}


int main()
{

  ...

  delay_sec( 20 );   // 20 Sekunden warten

  ...
}


Meistens ist es besser, wenn man irgendwelche Beschränkungen in 
Funktionen verpackt, und die Funktionen so schreibt, dass die 
Beschränkung umgangen wird.

In einem halben Jahr fragst du dich nämlich dann, warum du da
  delay_ms(5000);
  delay_ms(5000);
geschrieben hast und nicht die beiden delay zu einem einzigen 
zusammengefasst hast :-)

Autor: Thomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok super danke für die schnelle Hilfe und Tipps ;-)

Autor: Pete K. (pete77)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Immer wieder das delay.h Thema...

Vielleicht wäre es an der Zeit, in der delay.h mal ein Makro delay_sec() 
anzubieten.
Oder eine Warnung ausgeben, wenn die Obergrenze des Arguments 
überschritten wird (defensives Programmieren).

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Pete K. schrieb:
> Immer wieder das delay.h Thema...
>
> Vielleicht wäre es an der Zeit, in der delay.h mal ein Makro delay_sec()
> anzubieten.
> Oder eine Warnung ausgeben, wenn die Obergrenze des Arguments
> überschritten wird (defensives Programmieren).

Na, ja.
Das eigentliche Problem ist ja, dass man derartig lange Wartezeiten ganz 
einfach nicht mit einerm _delay realisiert.

* entweder man blockiert sich die Maschine für lange Zeit damit
* oder man erledigt alles zwischendurch in Interrupts, dann stimmen
  aber wiederrum die delay Zeiten nicht

Bis auf wenige Ausnahmen (ganz kurze delay Zeiten um ein Timing 
einzuhalten), kann man sagen:

Kommt in einem Programm ein _delay_ms vor, hat man meistens eine 
unglückliche Designentscheidung getroffen.

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger schrieb:
> Kommt in einem Programm ein _delay_ms vor, hat man meistens eine
> unglückliche Designentscheidung getroffen.
Ich würde das ein wenig relativieren:
Bei der Initialisierung von (externen) Komponenten mag ein _delay_ms 
noch angehen. Kommt aber in der Hauptschleife eines Programms ein 
_delay_ms vor, hat man meistens mindestens eine unglückliche 
Designentscheidung getroffen.
Aber auch bei der Initialisierung sollte man die Grenzen von _delay_ms 
nie zu spüren bekommen...

Autor: Klaus Wachtler (mfgkw)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@KHB:
So pauschal würde ich das nicht sagen.

Ich kann mir schon Situationen vorstellen, wo man alles Schnelle
in Interrupts erledigt (wenn es nicht viel Aufwand macht) und im
Hauptprogramm nur alle paar Sekunden etwas zu kontrollieren ist.

Unbedingt verwerflich muß es nicht sein, ein paar Sekunden zu warten.

Edit: ok, zweiter.

Aber er redet ja auch von "meistens"

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Klaus Wachtler schrieb:

> Ich kann mir schon Situationen vorstellen, wo man alles Schnelle
> in Interrupts erledigt (wenn es nicht viel Aufwand macht) und im
> Hauptprogramm nur alle paar Sekunden etwas zu kontrollieren ist.

...

> Aber er redet ja auch von "meistens"

Eben. Keine Regel ohne Ausnahme.


Ne, ist schon klar. Natürlich gibt es immer wieder Ausnahmen, bei denen 
das ok ist. Auch die Initialisierungsphase ist oft extra.
(welchen Sinn es haben soll auf einem µC, der nach dem Einschalten 
sofort da ist, einen PC mit Bootprozedur zu simulieren indem man gefakte 
Messages auf ein LCD schreibt mit Wartezeiten dazwischen, lass ich mal 
dahingestellt)

Autor: U.R. Schmitt (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Karl heinz Buchegger schrieb:
> Messages auf ein LCD schreibt mit Wartezeiten dazwischen, lass ich mal
> dahingestellt)

Na ja er will seine Nachrichten halt lesen...
Ohne delay müsste er dazu wohl Schnellleseweltmeister sein :-)

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
U.R. Schmitt schrieb:
> Karl heinz Buchegger schrieb:
>> Messages auf ein LCD schreibt mit Wartezeiten dazwischen, lass ich mal
>> dahingestellt)
>
> Na ja er will seine Nachrichten halt lesen...
> Ohne delay müsste er dazu wohl Schnellleseweltmeister sein :-)

Wenn ich den Smily nicht gesehen hätte, hätte ich gesagt: Wozu die 
Meldungen?

Aber da ich den :-) gesehen habe, sag ich jetzt nichts.

(Vor einiger Zeit war hier im Forum ein Programm zu bewundern, das 
ähnliches machte.
Am LCD: 1. Zeile    "Booting"
        2. Zeile    eine Punktzeile die länger wurde
während die Punktzeile aufgebaut wurde, hat das Programm nichts anderes 
gemacht als zu warten. Hätte er sich das gespart, hätte es nicht so cool 
ausgesehen, allerdings wäre der µC sofort einsatzbereit gewesen.
Soll ich noch ergänzen, dass das so ziemlich die einzige Funktionalität 
im Programm war, die funktioniert hat?)

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.