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


von Richi (Gast)


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...
1
#include <avr\io.h>
2
3
#define F_CPU 1000000
4
#include <util\delay.h>
5
6
7
int main(void){
8
9
  DDRD   = 0xFF;
10
11
  while(1){
12
    PORTD = 0;
13
    _delay_ms(1000);
14
    PORTD = 255;
15
    _delay_ms(1000);
16
  }    
17
}

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

von Peter (Gast)


Lesenswert?

Richi schrieb:
> #define F_CPU 1000000

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

von Johannes M. (johannesm)


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.

von Hc Z. (mizch)


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.

von Peter (Gast)


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.

von Richi (Gast)


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

von Chris L. (kingkernel)


Lesenswert?

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

von Richi (Gast)


Lesenswert?

Christian L. schrieb:
> Welche Compileroptimierung verwendest du?

Habe ebenfalls -os aktiviert.

von Peter (Gast)


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?

von Richi (Gast)


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

von Peter (Gast)


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.

von Richi A. (richiii248)


Lesenswert?

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

von Peter (Gast)


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.

von DJ_Tommy (Gast)


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

von Peter (Gast)


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

von DJ_Tommy (Gast)


Lesenswert?

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

von Chris L. (kingkernel)


Lesenswert?

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

von Richi A. (richiii248)


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

von Chris L. (kingkernel)


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.

von Peter (Gast)


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.

von Peter (Gast)


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?

von Richi A. (richiii248)


Lesenswert?

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

von Richi A. (richiii248)


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.

von David P. (chavotronic)


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?

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.