Forum: Mikrocontroller und Digitale Elektronik _delay_ms(1) ungenau!


von Alex Kuttner (Gast)


Lesenswert?

Hi!
Ich bin gerade am beginn meiner AVR Kariere.
Ich wollte kurz testen ob das Programmieren funktioniert und wollte mal 
ne Soft Pwm machen.
Erster Test: Einen Pin ein und ausschalten! Controller ist ein Atmega 
48, an den fuses hab ich nix geändert deshalb sollt er auf 1MHz laufen. 
Wenn ich direkt in der while(1) schleife pin ein und ausschalt bekomm 
ich aber ein rund 80 kHz Signal heraus! Warum ist das so? Brauchen die 
Ausgänge einige takte bis sie Stabil sind?

Zweiter Test: _delay_ms...bei 50ms ist es noch halbwegs genau 
(51,2ms)...aber bei 1ms hab ich rund 2,5ms. bei 10ms hab ich auch rund 
12ms am ausgang!
F_CPU ist natürlich gesetzt!
An was kann das liegen? Ich benutze AVR Studio 5 mit dem mySmart USB 
light.
Meine einzige erklärung ist dass der interne Oszillator viel zu ungenau 
ist...aber das find ich dann schon recht extrem! weil in 1ms vergehen ja 
immernoch 1000 Takte!

Danke für eure Hilfe!
LG Alex

von hänk (Gast)


Lesenswert?

hi
dass _dalay ungenau ist wurde hier schon oft diskutiert. an was es genau 
liegt weis ich auch nicht aber ich vermute mal, dass es auch gar nicht 
dafür vorgesehen ist genau zu sein, sondern einfach um ne kurze 
verzügerung bereit zu stellen. falls du genaue zeiten haben 
musst/willst, musst du einen timer bemühen.

gruß

von Klaus W. (mfgkw)


Lesenswert?

Wie sieht denn dein Programm aus?
Machst du nach dem Setzen der Pins evtl. gleich wieder einen Reset?

von Peter II (Gast)


Lesenswert?

>  Einen Pin ein und ausschalten! Controller ist ein Atmega
> 48, an den fuses hab ich nix geändert deshalb sollt er auf 1MHz laufen.
> Wenn ich direkt in der while(1) schleife pin ein und ausschalt bekomm
> ich aber ein rund 80 kHz Signal heraus! Warum ist das so? Brauchen die
> Ausgänge einige takte bis sie Stabil sind?
die schleife braucht auch zeit. Schau dir dem ASM-Code an, dann ist 
sieht du welche Befehle ausgeführt werden, in der Doku steht dann auch 
noch drin wie lange welcher Befehl braucht. Damit kannst du ausrechnen 
wie lange soetwas dauert-

wegen dem delay:
Hast du die Optimierung eingeschaltet?

von Krapao (Gast)


Lesenswert?

> Wenn ich direkt in der while(1) schleife pin ein und ausschalt bekomm
> ich aber ein rund 80 kHz Signal heraus! Warum ist das so?

Wieviele Takte braucht dein Schleifenkonstrukt und wieviele Takte dein 
Setzen/Löschen des Pins? Schau dir den erzeugten Assemblercode im 
Disassembler an und vergleiche die Ausführungszeiten mit der Stoppuhr im 
Debugger oder mit den Angaben im AVR Instruction Set Manual.

> _delay_ms...bei 50ms ist es noch halbwegs genau
> (51,2ms)...aber bei 1ms hab ich rund 2,5ms. bei 10ms hab ich auch rund
> 12ms am ausgang!

Das spricht dafür, dass du einen im Rahmen der Messung konstanten 
Overhead von 1,2 bis 2 ms hast. Das kann an der Messung und an dem 
Programmcode liegen (Funktionseinsprung, Schleife z.B.). Eine ungenaue 
F_CPU würde sich IMHO nicht durch einen konstanten Offset bemerkbar 
machen.

von (prx) A. K. (prx)


Lesenswert?

Krapao schrieb:

> F_CPU würde sich IMHO nicht durch einen konstanten Offset bemerkbar
> machen.

Abgeschaltete Optimierung oder eine Variable statt einer Konstanten als 
Parameter aber schon.

von Falk B. (falk)


Lesenswert?

@  Alex Kuttner (Gast)

>Ich bin gerade am beginn meiner AVR Kariere.

Dann sollte man die Bälle etwas flacher halten und nicht so naseweis 
rumposaunen.

>Erster Test: Einen Pin ein und ausschalten! Controller ist ein Atmega
>48, an den fuses hab ich nix geändert deshalb sollt er auf 1MHz laufen.

1MHz RC-Oszillator, der problemso +/-10% Toleranz hat.

>Wenn ich direkt in der while(1) schleife pin ein und ausschalt bekomm
>ich aber ein rund 80 kHz Signal heraus! Warum ist das so?

Quelltext?

> Brauchen die
>Ausgänge einige takte bis sie Stabil sind?

Nö, aber deine Schleife ist nicht unendlich schnell. 80kHz bedeutet, ~12 
Takte für die Schleife bei 1MHz, das passt ungefähr.

>Zweiter Test: _delay_ms...bei 50ms ist es noch halbwegs genau
>(51,2ms)...aber bei 1ms hab ich rund 2,5ms. bei 10ms hab ich auch rund
>12ms am ausgang!

Quelltext?

>An was kann das liegen?

An dir. _delay_ms() und delay_us() sind nahezu auf den Takt genau.

>Meine einzige erklärung ist dass der interne Oszillator viel zu ungenau
>ist...

Das ist ein Problem. Ein anderes sind nichtkonstante Argumente, die mag 
die Funktion nicht.

http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Warteschleifen_.28delay.h.29

>aber das find ich dann schon recht extrem! weil in 1ms vergehen ja
>immernoch 1000 Takte!

Ja und?

MFG
Falk

von Alexxk (Gast)


Lesenswert?

Optimierung hab ich nix verändert. Wo kann man denn diese einstellen?

1. Programm:

#define f_cpu 1000000 (habs mit ul hinten angehaengt und ohne probiert 
das aendert nix)
Include io und delay
DDRD=0b00000001;
While(1)
{
portd=0b00000001;
//_delay_ms(1);
Portd=0b00000000;
//_delay_ms(1);
}

2. Programm halt mit den delays

...

Sobald ich zuhause bin werd ich das ganze testen mit einer variable 
statt einem literal und werd mal optimierung suchen!
muss aber erstmal hier auf der uni einen bldc regler aufbaun!
Danke fuer die hilfe hier, nach nichtmal ne halben stunde soviele 
antworten ist echt top!

Lg alex

von Alexxk (Gast)


Lesenswert?

Sry fuer doppelpost: hab gegoogelt wie man optimierung aktiviert und hab 
herausgefunden das sie in studio 5 bei einem neuen projekt deaktiviert 
ist!
Danke fuer eure hilfe, ich nehm stark an das es das sein wird!
Hab auch etwas zu schnell uebers tutorial gelses denn da steht das man 
den optimierer braucht!
Lg alex

von Stefan E. (sternst)


Lesenswert?

Alexxk schrieb:
> Hab auch etwas zu schnell uebers tutorial gelses denn da steht das man
> den optimierer braucht!

Nicht nur zu schnell über's Tutorial, sondern auch zu schnell über die 
Compiler-Warnungen. Die einfach zu ignorieren, ist eine ganz schlechte 
Idee.

von Karl H. (kbuchegg)


Lesenswert?

Alexxk schrieb:

> Sobald ich zuhause bin werd ich das ganze testen mit einer variable
> statt einem literal und werd mal optimierung suchen!

Ganz schlechte Idee.

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


Lesenswert?

Falk Brunner schrieb:
> 1MHz RC-Oszillator, der problemso +/-10% Toleranz hat.

Naja, das ist ein garantierter Datenblattwert.  Den will dir nur
niemand besser garantieren, weil es Stress ist, eventuell zusätzlichen
Ausschuss zu haben, obwohl das Bauteil ansonsten völlig funktionsfähig
ist.  Die ±10 % sind daher so gelegt, dass es praktisch kein ansonsten
funktionierendes Bauteil gibt, das diesen Bereich nicht automatisch
erreichen würde. ;-)

In der Praxis wissen wir, dass alle neueren AVRs problemlos unter
Bürobedingungen (T = 25 °C ± 5 K) in der Lage sind, eine RS-232-
Kommunikation aufzubauen, d. h. sie liegen bei ±2 % oder besser.

von Falk B. (falk)


Lesenswert?

@  Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite

>In der Praxis wissen wir, dass alle neueren AVRs problemlos unter
>Bürobedingungen (T = 25 °C ± 5 K) in der Lage sind, eine RS-232-
>Kommunikation aufzubauen, d. h. sie liegen bei ±2 % oder besser.

Mir ist ja klar, dass du die AVRs loben "musst", aber sind die auch bei 
2% OHNE manuelle Kalibierung? Das es PRINZIPIELL geht ist klar.

MFG
Falk

von Rolf Magnus (Gast)


Lesenswert?

Jörg Wunsch schrieb:
> In der Praxis wissen wir, dass alle neueren AVRs problemlos unter
> Bürobedingungen (T = 25 °C ± 5 K

... und Vcc = 5V ...

> ) in der Lage sind, eine RS-232-Kommunikation aufzubauen, d. h. sie
> liegen bei ±2 % oder besser.

Falk Brunner schrieb:
> Mir ist ja klar, dass du die AVRs loben "musst", aber sind die auch bei
> 2% OHNE manuelle Kalibierung? Das es PRINZIPIELL geht ist klar.

Die sind schon vorkalibriert. Man muß nur bei manchen AVRs aufpassen. Je 
nach Version des RC-Oszillators kann es mehrere separate Oszillatoren 
für 1, 2, 4 und 8 Mhz geben, von denen jeder seinen eigenen OSCCAL-Wert 
hat. Wenn man bei denen nicht mit dem Standard-Takt von 1 Mhz arbeitet, 
muß man den passenden Wert explizit ins Register laden.

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


Lesenswert?

Falk Brunner schrieb:

> Mir ist ja klar, dass du die AVRs loben "musst",

Nö, muss ich nicht, ich will sie nur nicht schlechter machen, als
sie sind. ;-)

> aber sind die auch bei
> 2% OHNE manuelle Kalibierung?

Mit der factory calibration, d. h. mit dem Fuse-Wert, der automatisch
beim Reset ins OSCCAL geladen wird.  Seit dem "neuen" RC-Oszillator
(also bei all den AVRs, die nur noch einen statt vormals drei oder
vier verschiedenen Oszillatoren haben) kann man wirklich RS-232
problemlos "aus der Dose raus" machen, solange man im normalen
Temperaturbereich bleibt.  Das klappt selbst dann noch, wenn man die
Spannung bei einem ATmega1281 bspw. von den 5 V, für die der
Kalibrierwert gilt, auf 3 V absenkt.  Mit dem "alten" Oszillator ging
letzteres nicht, für unsere ATmega128 früher haben wir noch am OSCCAL
rumfummeln müssen, wenn wir sie mit 3 V betreiben wollten.

Dass man damit kein produktives Gerät aufbauen kann (wegen der
fehlenden Datenblattgarantie), ohne einen Kalibrierzyklus vorzusehen,
ist mir natürlich klar, aber für die typische Debug-Ausgabe während
der Softwareentwicklung oder für den durchschnittlichen Bastler zu
Hause mit einem Einzelexemplar reicht das durchaus vollkommen aus.

von Peter D. (peda)


Lesenswert?

Jörg Wunsch schrieb:
> In der Praxis wissen wir, dass alle neueren AVRs problemlos unter
> Bürobedingungen (T = 25 °C ± 5 K) in der Lage sind, eine RS-232-
> Kommunikation aufzubauen, d. h. sie liegen bei ±2 % oder besser.

Ist auch meine Erfahrung.
Eine Debug-UART auf dem ATtiny13, 25, 261 usw. ging bisher immer auf 
Anhieb.

Für fertige Anwendungen mit UART nehme ich aber trotzdem einen Quarz.


Peter

von (prx) A. K. (prx)


Lesenswert?

Rolf Magnus schrieb:

> nach Version des RC-Oszillators kann es mehrere separate Oszillatoren
> für 1, 2, 4 und 8 Mhz geben, von denen jeder seinen eigenen OSCCAL-Wert

Das sind aber m.W. nur die alten Typen, die ohnehin weniger genau sind 
als die hier betrachteten. Die neuen haben einen Oszillator mit 
Prescaler, nicht mehrere ohne.

von Rolf Magnus (Gast)


Lesenswert?

Richtig, aber z.B der Atmega8 hat die beschriebenen 4 separaten 
OSCCAL-Werte, und der ist noch ziemlich verbreitet. Der vom Fragesteller 
verwendete Atmega48 hat das allerdings nicht mehr.
Irgendwo gab's auch eine Appnote, die die ganzen Oszillator-Versionen 
beschreibt. Da gibt's nämlich gar nicht so wenige.

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


Lesenswert?

Rolf Magnus schrieb:
> Richtig, aber z.B der Atmega8 hat die beschriebenen 4 separaten
> OSCCAL-Werte, und der ist noch ziemlich verbreitet.

Ja, leider.  Ich versteh' das auch nicht, warum die Leute nicht
stattdessen auf die pinkompatiblen moderneren Versionen umsteigen
(zumal es die ja auch mit viel mehr Flash gibt, wenn man will).

von Jonathan S. (joni-st) Benutzerseite


Lesenswert?

Jörg Wunsch schrieb:
> Ich versteh' das auch nicht, warum die Leute nicht
> stattdessen auf die pinkompatiblen moderneren Versionen umsteigen

Der ATMega8 kostet weniger - aber sonst hat er nur Nachteile. Musste ich 
bei meiner Stereoanlage merken - mit ATMega88 anstatt ATMega8 bekomme 
ich viel bessere ADC-Ergebnisse und es klingt entsprechend besser.

von Rolf Magnus (Gast)


Lesenswert?

Jörg Wunsch schrieb:
> Rolf Magnus schrieb:
> Ich versteh' das auch nicht, warum die Leute nicht stattdessen auf die
> pinkompatiblen moderneren Versionen umsteigen (zumal es die ja auch mit
> viel mehr Flash gibt, wenn man will).

Ich denke, vor allem, weil es viele Tutorials und existierende Projekte 
mit dem Atmega8 gibt. Wer dann sowas nachbaut und zum ersten mal einen 
AVR verwendet, wird dann (sinnvollerweise) den gleichen Prozessor nehmen 
und nicht einen anderen. Und ich denke, daß einige dann anfangs erstmal 
bei dem Prozessor bleiben, solange sie keine Notwendigkeit sehen, auf 
einen anderen umzusteigen.

von Malignes Melanom (Gast)


Lesenswert?

Jörg Wunsch schrieb:
> In der Praxis wissen wir, dass alle neueren AVRs problemlos unter
> Bürobedingungen (T = 25 °C ± 5 K) in der Lage sind, eine RS-232-
> Kommunikation aufzubauen, d. h. sie liegen bei ±2 % oder besser.

Re: RS232 ... man kann auch einfach eine Baudratenerkennung machen. Dann 
ist das alles wurscht. Darüberhinaus ist es komfortabler wenn die 
Baudrate (im Rahmen) beliebig ist.

Es darf dann nur niemand das Fenster aufmachen :D

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.