www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik "_delay_ms" zu kurz, ATMega48


Autor: Richi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi, ich habe gesehen, dass hier im Forum schon oft über die 
delay-Funktion diskutiert wurde, aber leider habe ich immernoch keine 
Ahnung wieso es bei mir nicht funktioniert...
#include <avr\io.h>

#define F_CPU 1000000
#include <util\delay.h>


int main(void){

  DDRD   = 0xFF;

  while(1){
    PORTD = 0;
    _delay_ms(1000);
    PORTD = 255;
    _delay_ms(1000);
  }    
}  

Folgendes Problem: die Led an PortD 1 blinkt etwa 4 mal zu schnell

Verwendeter Controller: AtMega 48, 8MHz interner Oszillator, CKDIV8 
gesetzt
AVR Toolchain libc

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Richi schrieb:
> #define F_CPU 1000000

warum schreibst belügst du denn den Compiler wenn du ein 8MHz Quarz 
hast?

Autor: Johannes M. (johannesm)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du schreibst auf der einen Seite "#define F_CPU 1000000" und weiter 
unten "8MHz interner Oszillator", welches von beiden möchtest du denn ?
Hast du dir die Doku zu delay.h durchgelesen?
Da steht u.a. sowas wie "The maximal possible delay is 262.14 ms / F_CPU 
in MHz." drin.

Autor: Hc Zimmerer (mizch)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> #define F_CPU 1000000
und
> 8MHz interner Oszillator

Fällt Dir was auf?

Du wartest 2 * 1000 ms je Periode, deshalb misst Du nur das Vierfache. 
Tatsächlich läuft Dein µC 8mal so schnell.

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Johannes M. schrieb:
> Du schreibst auf der einen Seite "#define F_CPU 1000000" und weiter
> unten "8MHz interner Oszillator", welches von beiden möchtest du denn ?
> Hast du dir die Doku zu delay.h durchgelesen?
> Da steht u.a. sowas wie "The maximal possible delay is 262.14 ms / F_CPU
> in MHz." drin.

Hast du sie denn mal gelesen? Es geht mit dem Satz weiter:

The maximal possible delay is 262.14 ms / F_CPU in MHz.

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.

Autor: Richi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke schon mal für die Antwortet.

Der Compiler weiß ja nicht ob das CKDIV 8 Fuse gesetzt ist? Daher die 
1Mhz.
Ich hab mal F_CPU auf 8 MHz gesetzt und nochmal gemessen, eine Periode 
(ja an und aus) dauert jetzt 4 Sekunden.... :-(

Autor: Chris L. (kingkernel)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Welche Compileroptimierung verwendest du? Delay generiert nur mit 
eingeschalteter Optimierung genau delays. Ich verwende -Os

Autor: Richi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Christian L. schrieb:
> Welche Compileroptimierung verwendest du?

Habe ebenfalls -os aktiviert.

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Richi schrieb:
> Ich hab mal F_CPU auf 8 MHz gesetzt und nochmal gemessen, eine Periode
> (ja an und aus) dauert jetzt 4 Sekunden.... :-(
dann läuft deine CPU nicht nicht 8Mhz. Wecher wert steht denn im CLKPR 
register?

Autor: Richi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Peter schrieb:
> dann läuft deine CPU nicht nicht 8Mhz. Wecher wert steht denn im CLKPR
> register?

Das wär auch die beste Erklärung die mir einfallen würde. Wenn ich das 
richtig sehe steht in dem Register 0x91

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Richi schrieb:
> Das wär auch die beste Erklärung die mir einfallen würde. Wenn ich das
> richtig sehe steht in dem Register 0x91
kann kaum sein, denn bit 4,5 und 6 kann nur 0 sein. Laut PDF von Atmel.

Autor: Richi Abc (richiii248)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
oh jetzt ja, 0x91 war das Kalibrierbyte, von CLKPR ist nur Bit 7 un 8 
gesetzt, sollte also passen -> Teiler 1

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Richi Abc schrieb:
> oh jetzt ja, 0x91 war das Kalibrierbyte, von CLKPR ist nur Bit 7 un 8
> gesetzt, sollte also passen -> Teiler 1
kann auch nicht sein, denn der Teiler ist ein bit 0,1,2 und 3 - bit 8 
gibt es als Softwareentwickler nicht - da fängt man mit 0 an zu zählen.

Autor: DJ_Tommy (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Richi:

Du hast nichts zu den Posts von Johannes und Peter gesagt.
Sie haben Dich doch darauf hingewiesen, dass:

_delay_ms() darf maximal mit 262.14 ms verwndet werden.

mach doch mal:

_delay_ms(250);
_delay_ms(250);
_delay_ms(250);
_delay_ms(250);

Tommy

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
DJ_Tommy schrieb:
> DJ_Tommy (Gast)
> Sie haben Dich doch darauf hingewiesen, dass:
>
> _delay_ms() darf maximal mit 262.14 ms verwndet werden.

das stimmt aber nicht, lies doch bitte mal die Doku!!!

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

Autor: DJ_Tommy (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Uuups, das stimmt, nur die Genauigkeit reduziert sich dann ....
Ich leg mich lieber hin ...

Autor: Chris L. (kingkernel)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Und das auch nur bei einer alten GCC-Version. Bei einer aktuellen ist 
auch das kein Problem mehr!

Autor: Richi Abc (richiii248)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
oh mann peter du hast natürlich Recht, bin schon total verwirrt...
0x03 -> bit 0 und 1 natürlich
macht auch sinn weil der teiler ja aktiviert ist

Autor: Chris L. (kingkernel)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hast du einen Frequenzzähler oder ein Oszi? Wenn ja, dann gib den Takt 
mal direkt an einem Ausgang aus (Am bsten per Fuse, wenn das bei deinem 
Controller möglich ist) und miss mal.

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Christian L. schrieb:
> Und das auch nur bei einer alten GCC-Version. Bei einer aktuellen ist
> auch das kein Problem mehr!
sicher? Denn was hat der GCC mit der lib-avr zu tun? Das ganze liegt 
doch nicht im Compiler das es etwas ungenauer ist, sondern an der Art 
der Implemtierung.

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Richi Abc schrieb:
> oh mann peter du hast natürlich Recht, bin schon total verwirrt...
> 0x03 -> bit 0 und 1 natürlich
> macht auch sinn weil der teiler ja aktiviert ist
Ich denke nicht, das heist ja das es ein Teiler/8 ist, und 8Mhz/8 ist 
1Mhz - also läuft der Interne Takt mit 1Mhz. Oder lieg ich jetzt falsch?

Autor: Richi Abc (richiii248)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Juhuuuuu 1 Sekunde!!!
Und das nur weil ich AVR Toolchain deinstalliert und stattdessen WinAVR 
installiert habe. Sollten die Bibliotheken nicht genau gleich 
funktionieren??

Autor: Richi Abc (richiii248)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Peter schrieb:
> Richi Abc schrieb:
>> oh mann peter du hast natürlich Recht, bin schon total verwirrt...
>> 0x03 -> bit 0 und 1 natürlich
>> macht auch sinn weil der teiler ja aktiviert ist
> Ich denke nicht, das heist ja das es ein Teiler/8 ist, und 8Mhz/8 ist
> 1Mhz - also läuft der Interne Takt mit 1Mhz. Oder lieg ich jetzt falsch?

Doch du hast absolut Recht, das war der Grund wieso ich F_CPU auf 1MHz 
gesetzt habe.

Autor: David P. (chavotronic)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
#define F_CPU 8000000

for(int i=0;i<151;i++)
{
_delay_ms(33);
}

Dauert bei mir nur ein Bruchteil einer Sekunde, sollte aber +- 5 
Sekunden dauern. ES handelt sich um einen ATMEGA32 mit internen 8 MHz

Womöglich liegt es an der Compiler Einstellung, da hab ich aber nur 
0,1,2,3,s
Mit 0 ist das Problem immer noch da :(

Wenn der interne Takt mit 1 statt 8 laufen würde, sollte delay dann zu 
lang werden oder?

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.