Forum: Mikrocontroller und Digitale Elektronik _delay_ms nicht richtig


von Frank (Gast)


Lesenswert?

Hallo,

ich will bei einen Atmega168 mit 14.7456MHz Quarz eine LED im 
1-sek-Rhytmus blinken lassen. Allerdings blinkt die LED im ca. 
5-sek-Rhytmus.
Im AVR-Studio ist bei den Fuses Ext.Crystal.Osc. 8.0- MHz eingestellt.
Hier der Code:

#include <avr/io.h>
#include <util/delay.h>

#ifndef F_CPU
#define F_CPU 14745600UL
#endif

#define LED PB2

int main(void)
{

  DDRB |= (1<<LED);     //PB2 (LED) als Ausgang
  PORTB &= ~(1<<LED);  //PB2 (LED) ausschalten

  while (1)
  {
    _delay_ms (1000);
    PORTB ^= (1 << LED);
  }
  return 0;
}


Kann mir jemand helfen, warum die LED ca. alle 5 sek blinkt?

Danke von Frank

von Peter II (Gast)


Lesenswert?

Frank schrieb:
> Kann mir jemand helfen
ja

#include <util/delay.h>

#ifndef F_CPU
#define F_CPU 14745600UL
#endif


der Takt muss vor den #include <util/delay.h> gekannt sein.

von Rudolph (Gast)


Lesenswert?

Warum bin ich auch nicht sicher weil ich um die Delay-Funktionen 
normalerweise einen weiten Bogen machen.
Aber die AVR-Toolchain verhält sich da aus irgendeinem Grund ganz anders 
als WinAVR und demzufolge sind die Delay-Zeiten im Wald.

---
    _delay_ms (1000);
    PORTB ^= (1 << LED);
---

Sind auch 2 Hz Blinken.

Wobei

   PINB = (1<<LED);

etwas eleganter wäre.

von Rudolph (Gast)


Lesenswert?

Quatsch, 2 Hz, alle zwei Sekunden an -> 0,5 Hz.
Wo ist der nächste Kaffee?

von Martin (Gast)


Lesenswert?

Frank schrieb:
> Im AVR-Studio ist bei den Fuses Ext.Crystal.Osc. 8.0- MHz eingestellt.

Du könntest in AVR Studio dem Compiler bei den Konfigurationsoptionen 
zum Projekt auch direkt von der IDE aus die F_CPU mitteilen, wenn du 
dort als Frequenz deine 14745600 Hz einträgst.

von Rolf Magnus (Gast)


Lesenswert?

Rudolph schrieb:
> Wobei
>
>    PINB = (1<<LED);
>
> etwas eleganter wäre.

Allerdings auch weniger portabel, da das nur auf den neueren AVRs 
funktioniert.

von mr. mo (Gast)


Lesenswert?

Würde das F_CPU auf 8000000UL stellen.

von Martin (Gast)


Lesenswert?

Rudolph schrieb:
> Quatsch, 2 Hz, alle zwei Sekunden an -> 0,5 Hz.

Wahrscheilich eher 0,5425 Hz

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Rudolph schrieb:
> Aber die AVR-Toolchain verhält sich da aus irgendeinem Grund ganz anders
> als WinAVR und demzufolge sind die Delay-Zeiten im Wald.

Ja, die war leider einem Bug in der avr-libc aufgesessen.

Gibt's da denn nicht mittlerweile eine neue Version der AVR-Toolchain
von Atmel?  Der Bug stammt aus dem Frühjahr/Sommer 2010 und wurde im
Sommer dann behoben.

mr. mo schrieb:
> Würde das F_CPU auf 8000000UL stellen.

Sehr praktisch, wenn er einen 14,7-MHz-Quarz benutzt. ;-)

von Karsten F. (Firma: von Dänemark) (bingo600)


Lesenswert?

Die delay_ms(xxx) hast einer max für xxx

http://www.nongnu.org/avr-libc/user-manual/group__util__delay.html

vielleicht
1
my_delay_ms(uint16_t ms)
2
{
3
  while(ms--)
4
  {
5
    delay_ms(1);
6
  }
7
}

/Bingo

von Peter II (Gast)


Lesenswert?

Karsten F. schrieb:
> Die delay_ms(xxx) hast einer max für xxx

nein schon lange nicht mehr, es wird nur ungenauer.

> If the user requests a delay greater than the maximal
> possible one, _delay_us() will automatically call _delay_ms()
> instead. The user will not be informed about this case.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Karsten F. schrieb:
> Die delay_ms(xxx) hast einer max für xxx

Inzwischen nicht mehr, sie fällt nun automatisch auf eine solche
Schleife zurück, wie du sie gezeigt hast.

"When the user request delay which exceed the maximum possible one, 
_delay_ms() provides a decreased resolution functionality. [...]"

Allerdings sollte man wohl, wenn man derartig lange Zeiten außerhalb
eine kleinen Test-Applikation benötigt, stattdessen die Benutzung
eines Timers in Erwägung ziehen.

greetings to DK :)

(Edit: Peter war schneller.)

von Karsten F. (Firma: von Dänemark) (bingo600)


Lesenswert?

Hallo Jörg :-) et all.

Ist das von oben (die neue delay_ms ) nicht von avr-libc 1.7.0/1.7.1 ?

Ob der OP brauchst Winavr2010 dann ist das mitfolgende avr-libc v. 1.6.8

Greetings von DK (SE)

/Bingo

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Karsten F. schrieb:
> Hallo Jörg :-) et all.
>
> Ist das von oben (die neue delay_ms ) nicht von avr-libc 1.7.0/1.7.1 ?

Diese Funktionalität ist schon etwas länger dabei:
1
r1453 | joerg_wunsch | 2007-10-29 00:25:56 +0100 (Mon, 29 Oct 2007) | 6 lines
2
3
Submitted by Florin-Viorel Petrov
4
Patch #6236: Improving _delay_us and _delay_ms
5
6
Provide fallback functionality to extend the possible argument range
7
to _delay_us(), and _delay_ms(), respectively.

von Karsten F. (Firma: von Dänemark) (bingo600)


Lesenswert?

Ahh super ...

Danke für die einführung

/Bingo

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.