mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Mal wieder: _delay_ms() Zeit stimmt nicht


Autor: Holger K. (zaldo)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,

nun habe auch ich das Problem, dass _delay_ms() nicht zum gewünschten 
Ergebnis führt, allerdings in einer Größenordnung, welche ich hier per 
Sufu, pardon, Suchfunktion in keinem anderen Beitrag gefunden habe.

Eine 60 Sekunden Zeitschleife läuft in nur etwa 51 Sekunden durch, dabei 
ist es egal ob ich diese mit _delay_ms(1000) oder _delay_ms(100) 
aufbaue. Das ganze läuft auf einem tiny861, interner OSC mit 8 MHz, 
Kalibrierung habe ich gemacht und im Flash gespeichert (richtig gemacht 
hoffe ich), Code Optimization ist eingeschaltet (-O3), F_CPU korrekt auf 
800000UL gesetzt. Verwenden tue ich Studio 7.0, libc Version ist 
1.8.0svn

Wenn ich F_CPU auf 940000UL setze, dann stimmt die Zeit in etwa. Das 
könnte man jetzt auf diese Weise feintunen, aber das ist ja nicht Sinn 
der Sache.

Jemand eine Idee woran es liegen könnte? Oder liegt die Genauigkeit des 
internen OSC so weit daneben? Welchen Sinn erfüllt dann die 
Kalibrierung?

Beste Grüße
Holger

Autor: Wolfgang A. (Gast)
Datum:

Bewertung
-1 lesenswert
nicht lesenswert
Holger K. schrieb:
> Oder liegt die Genauigkeit des internen OSC so weit daneben?
> Welchen Sinn erfüllt dann die Kalibrierung?

Eine Kalibrierung stellt nur Messfehler fest, ohne irgendetwas daran zu 
ändern.

https://de.wikipedia.org/wiki/Kalibrierung

Was meinst du mit "Kalibrierung"?

Autor: Flo (Gast)
Datum:

Bewertung
1 lesenswert
nicht lesenswert
Holger K. schrieb:
> Jemand eine Idee woran es liegen könnte?


Du musst den Wert in deinem Programm selber laden und ins richtige 
Register schreiben.

Gruß
Flo

Autor: Matthias S. (Firma: matzetronics) (mschoeldgen)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Holger K. schrieb:
> Code Optimization ist eingeschaltet (-O3)

Im Allgemeinen ist -Os die richtige Optimierung für util/delay.h

Autor: t15 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sicher, dass die Fuses richtig gesetzt sind? Oftmals ist bei 
fabriksneuen AVRs ein Prescaler vom Faktor 8 eingestellt, so dass der 
Chip nur auf 1 MHz läuft; versuchs mal mit
#define F_CPU 1000000UL

wär nur eine Idee

Autor: hope (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Holger K. schrieb:
> Kalibrierung habe ich gemacht und im Flash gespeichert (richtig gemacht
> hoffe ich)

Ja, hoffe ich auch.

Autor: Holger K. (zaldo)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wow, so viel Input in so kurzer Zeit, Ihr seid klasse!

Also Wolfgang A. gemeint ist die OSC Calibration unter "Device 
Programming"

Flo Das könnte gut möglich sein, ich bin davon ausgegangen das er das 
alleine verwertet. Muß ich noch ein bisschen lesen, vorallen was der 
Wert den er ausgibt, 0xB3 für eine Größe darstellt...

Matthias Sch. Mit -Os verhält er sich exakt genauso wie mit -O3

t15 Meinst Du CKDIV8? Ja die ist gesetzt. Wenn ich die rausmache läuft 
meine Schleife statt in 51 Sekunden in nur Rund 5 Sekunden durch. Das 
Display-Timing stimmt dann auch nicht mehr.

Autor: Jakob (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Schau dir doch erstmal den Wert beim fabrikfrischen
µC an. Und das Datenblatt.

Für 3,3 V Vcc werden +/-10% angegeben, das wären 54..66 s.
Bei 5 V kommt noch was dazu...

Der Abgleich mit OSCCAL bei konstanter Temperatur auf 1% ist
eine Variante. Bei veränderlicher Temperatur werden es aber
schnell 2%.

Will man es genauer haben, ist ein Piezo, oder Quarz
unumgänglich.

Ausnahme: Man KANN eine externe Referenz (z.B. sind mit 50 Hz
aus dem Stromnetz auch 0,1% möglich) auswerten und zum
Nachsteuern von OSCCAL nutzen.
Erfordert aber µC-Resourcen: Port-Pin, Timer, Interrupt,
Programm-Code und Gehirnschmalz.

Autor: Flo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Holger K. schrieb:
> Flo Das könnte gut möglich sein, ich bin davon ausgegangen das er das
> alleine verwertet

Tut er aber leider nicht. Du musst das Byte aus dem Flash laden und dann 
ins OSCCAL Register schreiben.

Dann klappt das auch mit dem delay. Testweise einfach den Kalibrierwert 
mal direkt in deinem Programm setzen.

Gruß
Flo

Autor: Thomas E. (Firma: Thomas Eckmann Informationst.) (thomase)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Holger K. schrieb:
> F_CPU korrekt auf 800.000UL gesetzt.
> Wenn ich F_CPU auf 940.000UL setze...

Ich hab da mal Punkte reingesetzt. Du bist sicher, daß du das so 
angegeben hast?

Dann würde das nämlich ziemlich gut passen:

t15 schrieb:
> Sicher, dass die Fuses richtig gesetzt sind? Oftmals ist bei
> fabriksneuen AVRs ein Prescaler vom Faktor 8 eingestellt, so dass der
> Chip nur auf 1 MHz läuft; versuchs mal mit
> #define F_CPU 1000000UL
> wär nur eine Idee

Autor: Holger K. (zaldo)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Thomas E. schrieb:
> Holger K. schrieb:
>> F_CPU korrekt auf 800.000UL gesetzt.
>> Wenn ich F_CPU auf 940.000UL setze...

Also, ich habe bei aktivierter CKDIV8 Fuse F_CPU auf 800000UL (8 mit 5 
Nullen) gesetzt. Dann läuft mein Delay 51 Sekunden statt 60

Nehme ich CKDIV8 raus, muss ich F_CPU auf 8000000UL (8 mit 6 Nullen) 
setzen (und selbige Änderung auch in der lcd.c machen), dann läuft mein 
Delay 1:04 Minuten anstatt 60 Sekunden.

Den Teufel mit dem Beelzebub ausgetrieben würde ich sagen.

Autor: Planlos (Gast)
Datum:

Bewertung
-1 lesenswert
nicht lesenswert
Welcher AVR ist es denn eigentlich?

Es gibt auch welche, deren int. Osc.auf 9.6 MHz laufen kann, z.b Tiny13 
als kleinstes Beispiel.

Autor: Wolfgang (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Holger K. schrieb:
> Nehme ich CKDIV8 raus, muss ich F_CPU auf 8000000UL (8 mit 6 Nullen)
> setzen (und selbige Änderung auch in der lcd.c machen), dann läuft mein
> Delay 1:04 Minuten anstatt 60 Sekunden.

F_CPU stellt man gewöhnlich zentral an einer Stelle in der IDE ein oder 
in einem einzigen Headerfile. Dafür wird nicht in jedem File 
rumgefummelt. Sonst ist da etwas komisch am Quellcode.

Autor: Frank M. (ukw) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Holger K. schrieb:
> Also, ich habe bei aktivierter CKDIV8 Fuse F_CPU auf 800000UL (8 mit 5
> Nullen) gesetzt.

Das ist falsch.

Mit aktivierter CKDIV8-Fuse rennt Dein µC mit 1MHz. In diesem Fall musst 
Du F_CPU auf 1000000UL (1 mit 6(!) Nullen) setzen.

Wenn Du die CKDIV8-Fuse wegnimmst (wozu ich Dir raten würde), dann läuft 
Dein µC mit 8MHz. In diesen Fall ist F_CPU auf 8000000UL (8 mit 6 
Nullen) anzugeben.

> Dann läuft mein Delay 51 Sekunden statt 60

Klar: Du hast definiert: "Mein µC läuft mit 800kHz". Er läuft aber mit 
1MHz, also 20 Prozent schneller. Daher schafft er die 60 Sekunden in 51 
Sekunden.

Autor: he? (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Achtung bei delay_ms mit größeren werten (so ab 200) kann es probleme 
geben. ICh mach dann lieber
delay_ms(200); delay_ms(200); delay_ms(200); delay_ms(200); 
delay_ms(200);

Gruß J

Autor: Frank M. (ukw) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Holger K. schrieb:
> Nehme ich CKDIV8 raus, muss ich F_CPU auf 8000000UL (8 mit 6 Nullen)
> setzen (und selbige Änderung auch in der lcd.c machen), dann läuft mein
> Delay 1:04 Minuten anstatt 60 Sekunden.

Definiere F_CPU im Projekt und nicht in jedem C-Modul. Das ist sonst zu 
fehlerträchtig. 64 Sekunden sind schon ziemlich nah dran.

Jetzt fragt sich natürlich noch, wo die 4 Sekunden verbraten werden. Zum 
Beispiel könnten das Zeiten sein, die in ISRs "verbraucht" werden. Die 
kann nämlich _delay_ms() überhaupt nicht mitzählen. Hinzu kommen noch 
Abweichungen des Oszillators - und natürlich: Deine Schleife selbst.

Zeig mal den Code dazu.

Autor: m.n. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die Probleme mit delay() finde ich richtig gut.
Spätenstes jetzt sollte klar werden, daß man halbwegs genaue 
Verzögerungen mit Timern erledigt, auch wenn man dazu einmalig den Kopf 
benutzen muß.

Autor: Holger K. (zaldo)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Planlos: Steht im EP

Wolfgang, Frank M: Diese zentrale Stelle im IDE bzw. im Projekt habe ich 
noch nicht gefunden (habe aber auch noch nicht wirklich danach gesucht). 
das F_CPU in der lcd.c habe ich einfach so übernommen. Ja, vielleicht 
kein sauberer Stil, ich lerne ja noch.

Frank M: Klingt einleuchtend. Den Code an der Stelle ist nicht 
weltbewegend _delay_ms(500) zweimal hintereinander, dazwischen wird ein 
Port getoggelt. Allerdings gibt es eine ISR für einen 
Incrementaldrehgeber. Die dürfte aber, solange man nicht dran dreht, 
kaum zum tragen kommen.

he?: Hatte ich geschrieben, kein Unterschied

m.n.: Wenn der OSC nicht genau ist, ist es der Timer auch nicht.

Danke für den vielen Input :-)
Gruß
Holger

Autor: Frank M. (ukw) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Holger K. schrieb:
> Allerdings gibt es eine ISR für einen
> Incrementaldrehgeber. Die dürfte aber, solange man nicht dran dreht,
> kaum zum tragen kommen.

Kommt drauf an, ob es sich hierbei um eine ISR mit Timer oder INT0 bzw. 
PCINT handelt. Bei ISRs mit Timern spürst Du schon das Sichern und 
Wiederherstellen der Register (push/pop) in "Zeitmessungen" per delay. 
Du kannst ja mal probeweise die Interrupts komplett abstellen.

> m.n.: Wenn der OSC nicht genau ist, ist es der Timer auch nicht.

Aber schon genauer als Schleifen von delay-Calls. Die Timer arbeiten in 
Echtzeit, die Delay-Calls zählen einfach NOPs und können daher den 
Overhead, den Du mit der Schleife oder in ISRs erzeugst, nicht erfassen.

: Bearbeitet durch Moderator
Autor: Pete K. (pete77)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Holger K. schrieb:
> Diese zentrale Stelle im IDE bzw. im Projekt habe ich
> noch nicht gefunden (habe aber auch noch nicht wirklich danach gesucht).
> das F_CPU in der lcd.c habe ich einfach so übernommen. Ja, vielleicht
> kein sauberer Stil, ich lerne ja noch.

Nicht einfach alles übernehmen. Die Deklaration von F_CPU gehört in das 
Makefile, bzw. in die Projekteigenschaften vom Studio, das dann diese 
Angabe ins Makefile schreibt.

F_CPU gehört NIE in .c oder .h Files!

Warum nicht? Nun ja, es muss garantiert werden, dass alle Files im 
Makefile mit dem gleichen F_CPU übersetzt werden.

Autor: Ralf G. (ralg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Holger K. schrieb:
> Diese zentrale Stelle im IDE bzw. im Projekt habe ich
> noch nicht gefunden (habe aber auch noch nicht wirklich danach gesucht).

Ich begnüge mich noch mit AVR-Studio 4, deshalb kann ich dir die exakte 
Stelle nicht sagen. Aber irgenwo in der Nähe, wo du auch den verwendeten 
µC auswählst, kannst du die Taktfrequenz eintragen.

Um Programmierfehler/ -ungenauigkeiten in der Berechnung der Verzögerung 
auszuschließen, kannst du vor und nach dem Programmteil einen Breakpoint 
setzen und das ganze mal im Simulator laufen lassen. Der zeigt dir dann 
auf jeden Fall die korrekte Zeit an (Welche rauskommen müsste.). (Dauert 
allerdings!!)

: Bearbeitet durch User
Autor: Erwin D. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ralf G. schrieb:
> Ich begnüge mich noch mit AVR-Studio 4, deshalb kann ich dir die exakte
> Stelle nicht sagen. Aber irgenwo in der Nähe, wo du auch den verwendeten
> µC auswählst, kannst du die Taktfrequenz eintragen.

Project -> Configuration Options -> General -> Frequency

Bei Custom Options ist im rechten Fenster der Wert dann eingetragen
(z.B. "-DF_CPU=16000000UL")

Autor: Flo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich widerhole es noch ein mal:

Das OSCCAL Register muss mit dem Wert der Kalibrierungsroutine aus dem 
Programm heraus gesetzt werden. Sonst steht dort der Factory Programmed 
Wert drin. Mit diesem kann aber die Frequenz um +-10% abweichen, 
allerdings auch nur bei 3V garantiert. Was bei vermutlich verwendeten 5V 
noch wieder ganz anders sein kann.

ALSO:
In der Schaltung kalibrieren und den Wert in EEPROM/FLASH schreiben 
(lassen) und am Anfang deines Programmes den Wert auslesen und in OSCCAL 
setzen.

Dann stimmt auch dein delay!!!

F_CPU gehört gescheit ins Makefile, oder je nach IDE in das richtige 
Feld, wobei es dann letztendlich auch im Makefile landet!
Aber das eigentlichen Problem des TO ist das OSCCAL nicht korrekt 
gesetzt ist.

Gruß,
Flo

Autor: Flo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sorry, ich "wiederhole"....

Autor: m.n. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Flo schrieb:
> Das OSCCAL Register muss mit dem Wert der Kalibrierungsroutine aus dem
> Programm heraus gesetzt werden. Sonst steht dort der Factory Programmed
> Wert drin. Mit diesem kann aber die Frequenz um +-10% abweichen,

Dann lies auch bitte das Datenblatt! Die +/- 10% kannst Du knicken. 
Erfahrungsgemäß weicht der interne Takt ca. 1-2% vom Sollwert ab.

Autor: Flo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
m.n. schrieb:
> Dann lies auch bitte das Datenblatt! Die +/- 10% kannst Du knicken.

Ach was. Was meinst du wo ich den Wert her habe?

Hier ein Auszug aus dem Datenblatt:

Factory Calibration: 8.0 MHz bei 3V und 25°C±10%

Table 19-2 auf Seite 189.

m.n. schrieb:
> Erfahrungsgemäß weicht der interne Takt ca. 1-2% vom Sollwert ab

Erfahrung geht also über Datenblatt... Na denn...

Gruß,
Flo

Autor: Axel S. (a-za-z0-9)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Flo schrieb:
> Aber das eigentlichen Problem des TO ist das OSCCAL nicht korrekt
> gesetzt ist.

Nein.

Sein Problem ist, daß er F_CPU mit 800kHz angegeben hat,
obwohl sein µC mit 1MHz läuft:

Holger K. schrieb:
> ich habe bei aktivierter CKDIV8 Fuse F_CPU auf 800000UL (8 mit 5
> Nullen) gesetzt. Dann läuft mein Delay 51 Sekunden statt 60

Der Fehler von 800kHz angegeben zu 1000kHz real enstpricht ziemlich 
genau dem beobachteten Zeitunterschied von 60s geplant zu 51s real.

Es müßte aber (ohne CKDIV8) eine 8 mit 6 (sechs!) Nullen sein - für 8MHz 
Taktfrequenz. Oder eine 1 mit 6 Nullen für 1MHz bei gesetzter CKDIV8 
Fuse. Der Fehler durch die fehlende Kalibrierung kommt noch oben drauf.

: Bearbeitet durch User
Autor: Flo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ah, dann sind es zwei Fehler. Hab den hier übersehen:

Holger K. schrieb:
> Also, ich habe bei aktivierter CKDIV8 Fuse F_CPU auf 800000UL (8 mit 5
> Nullen) gesetzt. Dann läuft mein Delay 51 Sekunden statt 60

Dennoch, das von mir geschriebene stimmt ansonsten trotzdem.

Gruß,
Flo

Autor: Erwin D. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Flo schrieb:
> Erfahrung geht also über Datenblatt... Na denn...

Wenn ihr beide mal nicht nur einen Teil gelesen hättet, würdet ihr 
bemerken, daß ihr beide recht habt.
Factory calibration: 8MHz      3V         25°C          +/-10%
User calibration: 7.3-8.1MHz   1.8-5.5V   -40 - +85°C   +/-1%

Autor: Flo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Erwin D. schrieb:
> Wenn ihr beide mal nicht nur einen Teil gelesen hättet, würdet ihr
> bemerken, daß ihr beide recht habt.

In wie fern. Dort steht doch das die Abweichung +-10% betragen kann bei 
factory calibration. Also wenn man OSCCAL nicht auf einen selbst 
bestimmten Kalibrierungswert setzt.

Das der viel genauer sein kann wenn OSCCAL richtig gesetzt ist bestreite 
ich doch gar nicht.

Dennoch gebe ich zu einen Beitrag nur teilweise gelesen zu haben. Dafür 
entschuldige ich mich natürlich. Kommt davon wenn man immer mal 
zwischendurch mit dem Smartphone drauf guckt was es neues gibt und so 
schnell drüber wischt :-)

Gruß,
Flo

Autor: Erwin D. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Flo schrieb:
> In wie fern. Dort steht doch das die Abweichung +-10% betragen kann bei
> factory calibration. Also wenn man OSCCAL nicht auf einen selbst
> bestimmten Kalibrierungswert setzt.
Deswegen schrieb 'm.n' ja auch:
m.n. schrieb:
> Erfahrungsgemäß weicht der interne Takt ca. 1-2% vom Sollwert ab.
Er schrieb nicht "bei factory calibration" :-)
>
> Das der viel genauer sein kann wenn OSCCAL richtig gesetzt ist bestreite
> ich doch gar nicht.
Das habe ich aber so verstanden, daß du mit der Aussage von m.n. nicht 
einverstanden warst:
Flo schrieb:
> m.n. schrieb:
>> Dann lies auch bitte das Datenblatt! Die +/- 10% kannst Du knicken.
>
> Ach was. Was meinst du wo ich den Wert her habe?

Aber nun gut. Wir wissen jetzt: Factory +-10% / User +-1%
Einverstanden? :-)

Autor: Flo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Erwin D. schrieb:
> Aber nun gut. Wir wissen jetzt: Factory +-10% / User +-1%
> Einverstanden? :-)

Na Klar! War wohl ein Missverständnis.

Mir ging es nur darum, das die Genauigkeit, ohne das OSCCAL mit 
korrektem Wert gesetzt wurde, nicht so gut ist wie erwartet.
Und das der TO das eben selber machen MUSS in seinem Programm. Die 
Kalibrierungsroutine speichert den errechneten Kalibrierungsfaktor 
nämlich nur im Flash oder EEPROM, weiß ich spontan nicht so genau wo.

Alles ist gut :-)

Gruß,
Flo

Autor: Mitlesa (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ach ist das schön wenn man sich hier in einem Thread mal
im Friede-Freude-Eierkuchen-Gefühl trennt.

Autor: Erwin D. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mitlesa schrieb:
> Ach ist das schön wenn man sich hier in einem Thread mal
> im Friede-Freude-Eierkuchen-Gefühl trennt.

Klar, warum nicht? Macht doch keinen Sinn, daß man sich wegen einem 
Mißverständnis die Köppe einschlägt, oder? :-)

Autor: Flo (Gast)
Datum:

Bewertung
1 lesenswert
nicht lesenswert
Mitlesa schrieb:
> Ach ist das schön wenn man sich hier in einem Thread mal
> im Friede-Freude-Eierkuchen-Gefühl trennt.

Genau! Man muss nur an das Gute im Forum glauben...  ;-)

Autor: Flo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Erwin D. schrieb:
> Klar, warum nicht? Macht doch keinen Sinn, daß man sich wegen einem
> Mißverständnis die Köppe einschlägt, oder? :-)

Natürlich nicht. Passiert aber dennoch oft genug hier glaube ich :-)

Autor: Holger K. (zaldo)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Flo schrieb:

>speichert den errechneten Kalibrierungsfaktor
> nämlich nur im Flash oder EEPROM, weiß ich spontan nicht so genau wo.

Das kannst Du Dir aussuchen, nebst Deiner Wunschadresse. Sie muß nur 
frei sein, sonst gibts Mecker beim Programmieren.

Ich meine irgendwo hier gelesen zu haben, dass die ATMega den Wert 
selbsttätig beim Reset einlesen, bin mir aber nicht ganz sicher. Aber 
egal, jetzt weiß ich ja woran es hängt, und werde bei der Gelegenheit 
gleich den Code um F_CPU bereinigen.

Besten Dank euch allen!

Autor: Thomas E. (Firma: Thomas Eckmann Informationst.) (thomase)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Flo schrieb:
> Erfahrung geht also über Datenblatt... Na denn...

Allemal. Aber man muß das Datenblatt auch verstehen.

Factory Calibration wird bei 3V/25°C gemacht. Bei dieser Spannung und 
bei dieser Temperatur beträgt die Toleranz +-1-2%. Über den gesamtem 
zulässigen Spannungs-und Temperaturbereich beträgt die Toleranz +-10%. 
D.h. zwischen 1,8V und 5,5V sowie zwischen -40°C und 85°C. Betreibt man 
den Controller also in der Wüste wird die Frequenz zwischen Tag und 
Nacht kräftig schwanken. Bei User Calibration passt man den Takt immer 
an die jeweiligen Bedingungen an. Damit bleibt er dann auch in der 
Sahara rund um die Uhr auf +-1-2% konstant.

Das lässt sich auch sehr schön nachmessen. Dazu brauchst du ein 
Labornetzteil, einen Frequenzzähler, einen Föhn und eine Dose 
Kältespray.

: Bearbeitet durch User
Autor: Flo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Thomas E. schrieb:
> Factory Calibration wird bei 3V/25°C gemacht. Bei dieser Spannung und
> bei dieser Temperatur beträgt die Toleranz +-1-2%

Sorry, da lese ich im Datenblatt aber was anderes:

Accuracy at given voltage & temperature: +-10%

Bei factory calibration.

Liest sich für mich ziemlich eindeutig.
Erleuchtet mich wenn ich was übersehen haben sollte.

Gruß
Flo

Autor: Flo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ist sogar noch eine Fußnote dran:

Accuracy of  oscillator frequency  at  calibration  point (fixed 
temperature and  fixed  voltage).

Also nix über den gesamten VCC und Temperaturbereich.

Gruß
Flo

Autor: Codix (Gast)
Datum:

Bewertung
-3 lesenswert
nicht lesenswert
Warum wird hier über _delay_ms() diskutiert?
_delay_ms() kann und wird nie und nimmer die Genauigkeit erreichen, die 
ein
vernünftig programmierter Timerinterrupt erzeugen kann.
Da der TO nicht einmal weiss, dass man F_CPU fest auf den Wert der 
Ozillators setzt (inter oder extern ist hierbei wurscht), bringt dieser 
Thread eigentlich keine vernünftigen Erkenntnisse.
_delay_ms() ist nur eine Krücke, aber keine Timingfunktion wenn es um 
die Einhaltung einer definierten Zeit geht.
Wenn man hier die Suchfunktion richtig benutzt, sein Hirn dabei vorher 
einschaltet, dann findet man hier massig Infos zu dem Thema.

Autor: Flo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hier wird doch gar nicht über _delays_ms() diskutiert. Hier wird über 
die Genauigkeit des internen Oszillators diskutiert. Mit und ohne 
Kalibrierung.
Der TO weiß im übrigen auch das er F_CPU richtig setzen muss. Steht im 
ersten Beitrag. Hast du offenbar nicht richtig gelesen. Er konnte nur 
offenbar nur nicht die 8MHz korrekt eintragen. Es fehlte eine Null.
Auch ob _delays_ms() an der vom TO verwendeten Stelle sinnvoll verwendet 
wird wissen wir gar nicht.

Also warum schimpfst du so?

Im übrigen, der Timer geht mit fehlender Kalibrierung genau so falsch.

Gruß
Flo

Autor: Thomas E. (Firma: Thomas Eckmann Informationst.) (thomase)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Flo schrieb:
> Sorry, da lese ich im Datenblatt aber was anderes:

Nicht mein Problem

Autor: Carl D. (jcw2)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Flo schrieb:
> Hier wird doch gar nicht über _delays_ms() diskutiert. Hier wird über
> die Genauigkeit des internen Oszillators diskutiert. Mit und ohne
> Kalibrierung.

Gemessen wird die Frequenz aber indirekt über die Laufzeit von 
_delay_ms(1000), oder?
Und diese Laufzeit ist mindestens F_CPU Takte (bei 1000ms), falls nicht 
ein Interrupt noch weitere Takte verbraucht.
Das meint Codix (vermutlich) mit seiner Aussage zu _delay_ms().

Autor: Flo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Thomas E. schrieb:
> Nicht mein Problem

Warum so angepisst? Ich schrieb doch extra erleuchtet mich. Was ist denn 
das nun für eine Art und Weise?

Autor: Flo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Thomas E. schrieb:
> Factory Calibration wird bei 3V/25°C gemacht. Bei dieser Spannung und
> bei dieser Temperatur beträgt die Toleranz +-1-2%

Aus der application note AVR057:

The ATtiny4/5/9/10/20/40 devices feature  an internal 8MHz RC oscillator 
with prescalar and calibration register (OSCCAL). The internal RC 
oscillator  of these devices is factory calibrated for ±10% accuracy at 
3V supply voltage and at 25°C. But most of the applications needs more 
accurate clock as their basic requirement. For such applications AVR® 
offers a way to calibrate the internal RC oscillator. The internal RC 
oscillator can be  user calibrated to ±1% accuracy by modifying the 
OSCCAL register

Autor: M. K. (sylaina)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also wenn mir Zeiten bei einem Projekt wichtig wären würde ich nicht auf 
den internen Oszi setzen.
Eine Quick&Dirty-Lösung: Man weiß ja jetzt, dass _delay_ms() um 
100-51/60*100 Prozent daneben liegt, also einfach in _delay_ms() den 
gewünschten Wert mit 60/51 multiplizieren. Führt vielleicht zu einem 
Ergebnis, dass den eigenen Anforderungen genügt.

: Bearbeitet durch User
Autor: Rolf M. (rmagnus)
Datum:

Bewertung
1 lesenswert
nicht lesenswert
Codix schrieb:
> _delay_ms() ist nur eine Krücke, aber keine Timingfunktion wenn es um
> die Einhaltung einer definierten Zeit geht.

Nö. _delay_ms() ist hochgenau, sofern man keine Interrupts an hat und 
Optimierung eingeschaltet ist. Man muss nur wissen, wie man es korrekt 
nutzt. Und um irgendwo an einer Stelle im Programm mal ein Delay zu 
haben, bei dem der µC sonst eh nix macht, wäre es ziemlich umständlich, 
extra den Timer anzuwerfen und eine ISR zu schreiben, nur um sich den 
Aufruf von _delay_ms() zu sparen.

Thomas E. schrieb:
> Betreibt man den Controller also in der Wüste wird die Frequenz zwischen
> Tag und Nacht kräftig schwanken. Bei User Calibration passt man den Takt
> immer an die jeweiligen Bedingungen an. Damit bleibt er dann auch in der
> Sahara rund um die Uhr auf +-1-2% konstant.

Durch die Kalibrierung eleminiert man doch nicht den Einfluss der 
Temperatur.

Autor: M. K. (sylaina)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Rolf M. schrieb:
> Nö. _delay_ms() ist hochgenau, sofern man keine Interrupts an hat und
> Optimierung eingeschaltet ist. Man muss nur wissen, wie man es korrekt
> nutzt. Und um irgendwo an einer Stelle im Programm mal ein Delay zu
> haben, bei dem der µC sonst eh nix macht, wäre es ziemlich umständlich,
> extra den Timer anzuwerfen und eine ISR zu schreiben, nur um sich den
> Aufruf von _delay_ms() zu sparen.

Naja, sooo umständlich ist eine Timer-ISR nun auch wieder nicht aber ja, 
das _delay_ms() ist noch einen Tacken einfacher.

Rolf M. schrieb:
> Durch die Kalibrierung eleminiert man doch nicht den Einfluss der
> Temperatur.

Das zum einem aber auch eine Uhr, die nur auf 1-2% genau geht ist doch 
sehr ungenau.

: Bearbeitet durch User
Autor: Thomas E. (Firma: Thomas Eckmann Informationst.) (thomase)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Rolf M. schrieb:
> Durch die Kalibrierung eleminiert man doch nicht den Einfluss der
> Temperatur.

Was ist daran eigentlich so schwer zu verstehen? Daß eine einmalig 
vorgenommene Kalibrierung den Temperatureinfluß nicht eliminiert, ist 
eine ziemlich triviale Anmerkung.

Mit der Kalibrierung wird der Takt auf die gerade vorliegenden oder zu 
erwartenden Bedingungen eingestellt. Schwanken diese sehr stark, muß 
ständig nachgeregelt werden. Z.B. mit empfangenen Daten als Referenz. 
Oder mit einer abgespeicherten Temperaturkurve.

Autor: Ralph (Gast)
Datum:

Bewertung
-2 lesenswert
nicht lesenswert
m.n. schrieb:
> Die Probleme mit delay() finde ich richtig gut.
> Spätenstes jetzt sollte klar werden, daß man halbwegs genaue
> Verzögerungen mit Timern erledigt, auch wenn man dazu einmalig den Kopf
> benutzen muß.

Das war die erste sinnvolle Antwort!!!!

Autor: Arduino Fanboy D. (ufuf)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ralph schrieb:
> auch wenn man dazu einmalig den Kopf
> benutzen muß.
Das?

Wenn man den Kopf benutzt kommt man fix darauf, dass dieses einen großen 
Kern Wahrheit enthält.:
Flo schrieb:
> Im übrigen, der Timer geht mit fehlender Kalibrierung genau so falsch.

: Bearbeitet durch User
Autor: Ralf G. (ralg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
m.n. schrieb:
> Spätenstes jetzt sollte klar werden, daß man halbwegs genaue
> Verzögerungen mit Timern erledigt, auch wenn man dazu einmalig den Kopf
> benutzen muß.
Ralph schrieb:
> Das war die erste sinnvolle Antwort!!!!

Ihr schmeißt wegen einer (einmaligen) Initialisierung eines LCDs einen 
Timer an? Zum Takte verbraten? ^^

Autor: Erwin D. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ralf G. schrieb:
> Zum Takte verbraten? ^^

Das ist genau der Punkt. Takte "verbrät" man mit nop-Schleifen, auch 
delay genannt. Mit Timern hingegen nicht. Und da man meist sowieso 
einen Takt benötigt, um verschiedene Dinge regelmäßig anzustoßen, kann 
man den auch statt der delays benutzen.

Autor: Flo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ralf G. schrieb:
> Ihr schmeißt wegen einer (einmaligen) Initialisierung eines LCDs einen
> Timer an? Zum Takte verbraten? ^^

Bestimmt. Weil _delay_ms() ist die Ausgeburt des Teufels und abgrundtief 
böse. :-)

Ich sagte ja auch bereits: Wir wissen gar nicht recht was der TO mit dem 
delay überhaupt macht. Deswegen ist es doch völlig fehl am Platze sich 
darüber zu streiten ob das nun falsch verwendet wird oder nicht.

Mir geht's immer noch um die Genauigkeit der Factory Kalibrierung. Aber 
da erwarte ich inzwischen auch keine vernünftige Antwort mehr, wieso die 
+-10% bei 3V und 25°C nicht stimmen sollten. Denn Datenblatt und 
Application Note stimmen mir ja eigentlich zu, also warum weiter Zeit 
damit vergeuden.

Thomas E. schrieb:
> Factory Calibration wird bei 3V/25°C gemacht. Bei dieser Spannung und
> bei dieser Temperatur beträgt die Toleranz +-1-2%.

Flo schrieb:
> The internal RC
> oscillator  of these devices is factory calibrated for ±10% accuracy at
> 3V supply voltage and at 25°C

In der Application Note steht was anderes wie ich bereits postete. Ja 
die ist eigentlich für andere Tinys, aber in deren Datenblättern ist die 
gleiche Tabelle mit genau den gleichen +-10% und der RC Oszillator ist 
mit Sicherheit sowieso der gleiche...

Gruß,
Flo

Autor: M. K. (sylaina)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ralf G. schrieb:
> Ihr schmeißt wegen einer (einmaligen) Initialisierung eines LCDs einen
> Timer an? Zum Takte verbraten? ^^

_delay_ms() verbrät auch Takte ;), mehr sogar als ein Timer. Und bei 
_delay_ms() muss man warten bis die Takte verbraten sind, beim Timer 
kann man nebenbei noch was anderes machen. ;)

Autor: Ralf G. (ralg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
M. K. schrieb:
> beim Timer
> kann man nebenbei noch was anderes machen. ;)

Dann kannst du dich ja mal hier...
https://www.mikrocontroller.net/articles/AVR-Tutorial:_LCD#Routinen_zur_LCD-Ansteuerung_im_4-Bit-Modus
...um ein paar sinnvolle Erweiterungen kümmern, die nebenbei mit einem 
Timer erledigt werden können! [ auch: ;-) ]
-----
Ralf G. schrieb:
> ... Initialisierung eines LCDs ... Takte verbraten? ^^

Autor: Holger K. (zaldo)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also an dieser Stelle wird nichts weiter gemacht als eine Uhr 
runtergezählt. Jede Sekunde das LCD aktualisiert, jede halbe Sekunde 
eine LED getoggelt. Sonst nichts. Die CPU hat derweil ohnehin absolut 
nichts zu tun, sie kann so viel Zeit verNOPpen wie sie will.

Ja, könnte man auch mit einem Timer machen, aber wozu der Aufwand? 
Hochgenau muß die Zählung ohnehin nicht sein.

Autor: M. K. (sylaina)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Holger K. schrieb:
> Also an dieser Stelle wird nichts weiter gemacht als eine Uhr
> runtergezählt. Jede Sekunde das LCD aktualisiert, jede halbe Sekunde
> eine LED getoggelt. Sonst nichts. Die CPU hat derweil ohnehin absolut
> nichts zu tun, sie kann so viel Zeit verNOPpen wie sie will.

Eine CPU, die nichts zu tun hat, gehört ins Bett (Stichwort: Sleep 
Modes).

Autor: genau (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Holger K. schrieb:
> Ja, könnte man auch mit einem Timer machen, aber wozu der Aufwand?
> Hochgenau muß die Zählung ohnehin nicht sein.

Dann hast Du ja auch kein Problem. Ansonsten nimm einen Quarz resp. ext. 
Quarzoszi als Takt, und ggf. einen AVR, wo Du den anschließen kannst.

Autor: Thomas E. (Firma: Thomas Eckmann Informationst.) (thomase)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Erwin D. schrieb:
> Ralf G. schrieb:
>> Zum Takte verbraten? ^^
>
> Das ist genau der Punkt. Takte "verbrät" man mit nop-Schleifen, auch
> delay genannt. Mit Timern hingegen nicht. Und da man meist sowieso
> einen Takt benötigt, um verschiedene Dinge regelmäßig anzustoßen, kann
> man den auch statt der delays benutzen.

Aber nicht für ein paar hundert Nanosekunden. Wie z.B. 
Displayinitialisierung oder Ansteuerung von WS2812. Dafür braucht man 
ein Delay. Und zwar _delay_us() oder ein paar asm volatile ("nop"). 
Benutzt man hingegen _delay_ms() ist man auf dem falschen Weg und fast 
immer mit einem Timer besser bedient.

Holger K. schrieb:
> Ja, könnte man auch mit einem Timer machen, aber wozu der Aufwand?

Das ist überhaupt kein Aufwand. Und spätestens wenn du noch einen Taster 
abfragen willst, hast du mit deinen Delays die berühmte Karte, die mit A 
anfängt und mit rschkarte endet. Dann versuchst du dein Programm 
irgendwie zum Laufen zu bringen und kriegst es am Ende doch nur mit 
Timer hin. Das ist Aufwand. Also mach es gleich richtig.

Autor: Thomas E. (Firma: Thomas Eckmann Informationst.) (thomase)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Flo schrieb:
> In der Application Note steht was anderes wie ich bereits postete.

Du verstehst es nur nicht, hast es noch nie nachgemessen und hast von 
Elektronik allgemein keine Ahnung. Ich habe dir doch schon gestern 
geschrieben, wie das zusammenhängt. Ich diskutiere das nicht mit dir. 
Such dir dafür jemand anders.

: Bearbeitet durch User
Autor: Erwin D. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Thomas E. schrieb:
> Aber nicht für ein paar hundert Nanosekunden. Wie z.B.
> Displayinitialisierung oder Ansteuerung von WS2812. Dafür braucht man
> ein Delay. Und zwar _delay_us() oder ein paar asm volatile ("nop").
> Benutzt man hingegen _delay_ms() ist man auf dem falschen Weg und fast
> immer mit einem Timer besser bedient.

Das ist mir schon klar. Ich schrieb das, weil Holger von einer Uhr 
sprach, in der er die Sekunden mit delay_ms(1000) bzw. delay_ms(100) 
erzeugen wollte.

Holger K. schrieb:
> Eine 60 Sekunden Zeitschleife läuft in nur etwa 51 Sekunden durch, dabei
> ist es egal ob ich diese mit _delay_ms(1000) oder _delay_ms(100)
> aufbaue.

Für eine Display-Initialisierung und ähnliche Sachen kann man schon ohne 
schlechtes Gewissen delay_us() benutzen. Sehe ich genauso.

Autor: Flo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Thomas E. schrieb:
> Du verstehst es nur nicht, hast es noch nie nachgemessen und hast von
> Elektronik allgemein keine Ahnung. Ich habe dir doch schon gestern
> geschrieben, wie das zusammenhängt. Ich diskutiere das nicht mit dir.
> Such dir dafür jemand anders.

Keinen Auftrag bekommen Freelancer? Oder warum so schlechte Laune?

Wenn im Datenblatt UND in der Appnote steht +-10% bei 3V und 25°C gehe 
ich davon aus das das im schlimmsten Fall auch so ist und verlasse mich 
nicht auf "Erfahrungen" das es meistens besser ist. Da kann ich auch 
10000 mal gemessen haben das es besser ist.
Wenn du das so machst, viel Spaß! Spätestens wenn dir ein Projekt um die 
Ohren fliegt und man sieht das du dich nicht ans Datenblatt gehalten 
hast dann mal gute Nacht. Da kannst du dann lange erklären das es Deiner 
Erfahrung nach sonst immer ging!

Wenn du nicht in der Lage bist vernünftig mit anderen Menschen zu reden, 
dann lass es eben. Aber beleidige hier nicht einfach irgendwelche 
Menschen die du nicht kennst!

Autor: M. K. (sylaina)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Erwin D. schrieb:
> Für eine Display-Initialisierung und ähnliche Sachen kann man schon ohne
> schlechtes Gewissen delay_us() benutzen. Sehe ich genauso.

Da schließe ich mich an, sehe ich ähnlich. Die delay.h ist nicht 
generell schlecht und kann an der richtige Stelle schon ein wenig 
eigenen Gehirnschmalz sparen.

Autor: Erwin D. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Flo schrieb:
> Wenn im Datenblatt UND in der Appnote steht +-10% bei 3V und 25°C gehe
> ich davon aus das das im schlimmsten Fall auch so ist und verlasse mich
> nicht auf "Erfahrungen" das es meistens besser ist.

Nein, das hatten wir doch schon. Die 10% beziehen sich NUR auf die 
Factory Calibration. Wenn du den Wert des Calibration Byte selbst 
ermittelst, kannst du SICHER davon ausgehen, daß du auf 1% kommst. Denn 
das steht ausdrücklich im Datenblatt!
Den Wert für die Factory Calibration sehe ich als "Pi mal Daumen" an, 
damit man ohne eigene Calibrierung "ungefähr" die 8MHz bei 3V und 25°C 
hat und damit gleich loslegen kann. Wenn man es genauer braucht, macht 
man eine User Calibration und kommt damit auf 1%. Wenn man das nicht 
sicher erreichen würde, stünde es garantiert nicht im Datenblatt. Die 
schießen sich doch nicht ins eigene Knie!

Autor: Flo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Erwin genauso meine ich es doch auch.
Du kaufst 100000 Tinys und wirst bei default Factory Calibration +-10% 
Fehler feststellen bei der RC Frequenz.
Bei fester Temperatur und Spannung.
GENAU DAS MEINTE ICH
Drücke ich mich so undeutlich aus?

Gruß
Flo

Autor: Erwin D. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Flo schrieb:
> Erwin genauso meine ich es doch auch.

Na dann bin ich wieder beruhigt. Hatte schon das dumme Gefühl, daß du 
wieder was durcheinander bringst.
Also alles gut :-)

Autor: Flo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Erwin D. schrieb:
> Also alles gut :-)

Alles gut. Ich glaube wirklich ich drücke mich manchmal etwas undeutlich 
aus.
Aber deswegen muss man ja nicht gleich ausfallend werden so wie andere 
User hier...

Schönen Abend noch,
Flo

Autor: Erwin D. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Flo schrieb:
> Alles gut. Ich glaube wirklich ich drücke mich manchmal etwas undeutlich
> aus.

Kann schon sein :-)
Du hattest geschrieben:
Flo schrieb:
> Wenn im Datenblatt UND in der Appnote steht +-10% bei 3V und 25°C
Und da du kein Wort davon schriebst, daß die Werte nur bei Factory 
Calibration gelten, mußte ich annehmen, du meinst generell 10%. Deswegen 
hatte ich nochmal auf die User Calibration hingewiesen mit 1%.
Aber jetzt ist's wirklich gut! :-)

Flo schrieb:
> Schönen Abend noch
Ebenso!

Autor: Flo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Erlaube mir noch einen Nachtrag Erwin

Flo schrieb:
> Mir geht's immer noch um die Genauigkeit der Factory Kalibrierung. Aber
> da erwarte ich inzwischen auch keine vernünftige Antwort mehr, wieso die
> +-10% bei 3V und 25°C nicht stimmen sollten.

Flo schrieb:
> Sorry, da lese ich im Datenblatt aber was anderes:
>
> Accuracy at given voltage & temperature: +-10%
>
> Bei factory calibration.

Ich habe es also schon mindestens 2 mal so geschrieben und auch die 
Appnote zitiert.

Aber egal, wir sind uns einig und alles ist richtig so.

Gruß
Flo

Autor: Dieter F. (jim_quakenbush)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Erwin D. schrieb:
> Wenn du den Wert des Calibration Byte selbst
> ermittelst, kannst du SICHER davon ausgehen, daß du auf 1% kommst.

Ja, wenn Du genau liest bei definierter Temperatur UND Spannung. Sobald 
sich einer der beiden Parameter ändert sind die 1 % nicht mehr 
garantiert.

Datenblatt S. 189 - Note 1 zur Tabelle:

Accuracy of oscillator frequency at calibration point (fixed temperature 
and fixed voltage).

mit Bezug auf die +/- 1%

Autor: Marcus H. (Firma: www.harerod.de) (lungfish) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
he? schrieb:
> Achtung bei delay_ms mit größeren werten (so ab 200) kann es probleme
> geben. ICh mach dann lieber
> delay_ms(200); delay_ms(200); delay_ms(200); delay_ms(200);
> delay_ms(200);

Ohne jetzt Deinen Compiler zu kennen - treten die Probleme so vielleicht 
ungefähr ziemlich genau ab 256 auf? Noch dazu in Zusammenhang mit einer 
Compilerwarnung?

Autor: Erwin D. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dieter F. schrieb:
> Ja, wenn Du genau liest bei definierter Temperatur UND Spannung. Sobald
> sich einer der beiden Parameter ändert sind die 1 % nicht mehr
> garantiert.

Richtig, genauso ist es.

Autor: Rolf M. (rmagnus)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
M. K. schrieb:
> Ralf G. schrieb:
>> Ihr schmeißt wegen einer (einmaligen) Initialisierung eines LCDs einen
>> Timer an? Zum Takte verbraten? ^^
>
> _delay_ms() verbrät auch Takte ;), mehr sogar als ein Timer.

Nur wenn man länger warten will. ;-)

> Und bei _delay_ms() muss man warten bis die Takte verbraten sind, beim
> Timer kann man nebenbei noch was anderes machen. ;)

Ja. Wenn man aber an der Stelle eh nix zum machen hat und warten muss, 
bis die Zeit rum ist, steht da nachher eine Schleife, die einfach nur 
mit maximaler Geschwindigkeit ein Flag abfragt, das von der ISR nach 
Ablauf der Zeit gesetzt wird. Klar könnte man jetzt zusätzlich noch den 
Prozessor schlafen legen, aber das hat nur in wenigen Fällen wirklich 
einen nennenswerten Vorteil.
Und das nur, um die Verwendung von _delay_ms() zu vermeiden. Ich 
behaupte nicht, dass es generell besser ist, sondern dass beides seine 
Anwendungsfälle hat. In manchen ist das eine sinnvoller, in manchen das 
andere. Nur ist eben die Timer-ISR häufiger sinnvoll als das 
_delay_ms(). Deshalb würde ich aber nicht sagen, dass man krampfhaft 
jedes Auftreten von _delay_ms() durch die Nutzung von Timern ersetzen 
muss.

Thomas E. schrieb:
> ein Delay. Und zwar _delay_us() oder ein paar asm volatile ("nop").
> Benutzt man hingegen _delay_ms() ist man auf dem falschen Weg und fast
> immer mit einem Timer besser bedient.

Du weißt aber, dass man mit _delay_ms() auch nur z.B. 0,1 ms warten 
kann?

Flo schrieb:
> Wenn du nicht in der Lage bist vernünftig mit anderen Menschen zu reden,
> dann lass es eben. Aber beleidige hier nicht einfach irgendwelche
> Menschen die du nicht kennst!

Er scheint ja nicht nur in der Hinsicht Defizite zu haben. Auch mit dem 
Verständnis von Datenblättern scheint es nicht zu klappen, obwohl ihm 
zumindest bewußt ist, dass dieses Verständnis eigentlich erforderlich 
ist.

Autor: Thomas E. (Firma: Thomas Eckmann Informationst.) (thomase)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Rolf M. schrieb:
> Du weißt aber, dass man mit _delay_ms() auch nur z.B. 0,1 ms warten
> kann?

Rolf M. schrieb:
> Er scheint ja nicht nur in der Hinsicht Defizite zu haben. Auch mit dem
> Verständnis von Datenblättern scheint es nicht zu klappen, obwohl ihm
> zumindest bewußt ist, dass dieses Verständnis eigentlich erforderlich
> ist.

Mein Verständnis von Datenblättern ist ein sehr gutes und dem eines 
flogastes oder deinem weit überlegen. Und wenn sich irgendwer beleidigt 
fühlt, weil ich nicht auf seine sinnlose Diskussion, die aus nichts 
anderem herrührt, als daß er nichts verstanden hat, eingehe, ist das 
sein Problem.

Rolf M. schrieb:
> Du weißt aber, dass man mit _delay_ms() auch nur z.B. 0,1 ms warten
> kann?

Diese Anmerkung hättest du uns bei besserem Kenntnisstand auch ersparen 
können.


Denn ich weiß, daß man mit _delay_us() auch 0.1µs warten kann.

  __builtin_avr_delay_cycles(__ticks_dc);
 28e:  00 00         nop
   _delay_us(0.1);


Kompiliert mit 10MHz.

  __builtin_avr_delay_cycles(__ticks_dc);
 2a0:  00 c0         rjmp  .+0        ; 0x2a2 <main+0x1e>
   _delay_us(0.1);


Kompiliert mit 20MHz.

: Bearbeitet durch User
Autor: M. K. (sylaina)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Rolf M. schrieb:
> Ja. Wenn man aber an der Stelle eh nix zum machen hat und warten muss,
> bis die Zeit rum ist, steht da nachher eine Schleife, die einfach nur
> mit maximaler Geschwindigkeit ein Flag abfragt,
Ich würde das ja mit Interrupts machen, da wird weder Schleife noch Flag 
mit maximaler Geschwindigkeit abgefragt.
Rolf M. schrieb:
> Klar könnte man jetzt zusätzlich noch den
> Prozessor schlafen legen, aber das hat nur in wenigen Fällen wirklich
> einen nennenswerten Vorteil.

Also Energie sparen hat keinen nennenswerten Vorteil? Interessant.

Rolf M. schrieb:
> Ich
> behaupte nicht, dass es generell besser ist, sondern dass beides seine
> Anwendungsfälle hat.
> ...

Das sehe ich auch so, hab ich oben doch auch schon geschrieben gehabt ;)

Rolf M. schrieb:
> Du weißt aber, dass man mit _delay_ms() auch nur z.B. 0,1 ms warten
> kann?

steht ja auch in der Lib, ist das jetzt wirklich was Neues?

Autor: Uwe K. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Thomas E. schrieb:
> Mein Verständnis von Datenblättern ist ein sehr gutes und dem eines
> flogastes oder deinem weit überlegen. Und wenn sich irgendwer beleidigt
> fühlt, weil ich nicht auf seine sinnlose Diskussion, die aus nichts
> anderem herrührt, als daß er nichts verstanden hat, eingehe, ist das
> sein Problem.

Deine Überheblichkeit ist dermaßen zum kotzen, das hält ja keiner aus

Uwe

Autor: Jörg W. (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
1 lesenswert
nicht lesenswert
Flo schrieb:
> Du kaufst 100000 Tinys und wirst bei default Factory Calibration +-10%
> Fehler feststellen bei der RC Frequenz.

Sehr wahrscheinlich wirst du diese Fehler nicht feststellen, sondern
viel geringere.

Die ±10 % sind ein reiner Garantiewert, damit niemand Atm^H^H^HMicrochip
verklagen kann, wenn der vorprogrammierte OSCCAL-Wert doch mal etwas
stärker abweicht als üblich.  Die Praxis zeigt, dass der von Haus aus
mitgelieferte Wert in aller Regel sehr viel besser ist.

Insofern ist das ganz gewiss erstmal nicht das Problem des TEs (was
sich ja auch anderweitig dann gezeigt hat), sondern eher, dass die
von ihm behauptete CPU-Frequenz (die _delay_ms als Basis für die
Rechnung benutzt) einfach nicht mit dem realen Wert übereinstimmt.

Autor: Flo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jörg W. schrieb:
> Flo schrieb:
>> Du kaufst 100000 Tinys und wirst bei default Factory Calibration +-10%
>> Fehler feststellen bei der RC Frequenz.
>
> Sehr wahrscheinlich wirst du diese Fehler nicht feststellen, sondern
> viel geringere.

Da hast du natürlich Recht Jörg, wahrscheinlich wird die Toleranz nicht 
ausgereizt sein. Da ist ja sicher auch noch einiges an Reserve drin. Ich 
hab das etwas zu überzogen beschrieben um zu auszusagen was der Wert im 
Datenblatt quasi bedeutet.
Aber ich darf micht doch niemals darauf verlassen das der Wert 
normalerweise immer nur +-1-2% daneben liegt.
Im Zweifelsfall hat man aber die Arschkarte wenn man sich auf sowas 
verlässt und der Wert doch mal mehr streut. Mehr wollte ich doch damit 
gar nicht sagen.

Was den TO angeht, das er die Frequenz tatsächlich als 800kHz angegeben 
hat, hatte ich tatsächlich beim lesen übersehen. Das schrieb ich ja auch 
schon.

Des weiteren wollte ich ihn nur darauf hinweisen, das er eben OSCCAL 
selber mit dem Kalibrierwert beschreiben muss, damit die RC Frequenz 
besser passt. Das macht der Controller nicht von alleine. Per Default 
landet der Factory Calibration Wert in OSCCAL.

Das die User Calibration dann auch nur bei der kalibrierten Temperatur 
und VCC stimmt, sollte wohl jedem klar sein.

Gruß,
Flo

Autor: gustav (Gast)
Datum:
Angehängte Dateien:

Bewertung
-1 lesenswert
nicht lesenswert
M. K. schrieb:
> steht ja auch in der Lib, ist das jetzt wirklich was Neues?

Das ist ja auch der Grund, warum ich wohl oder übel lieber direkt in 
Assembler "programmiere".
Die Libraries enthalten eben oft nicht das, was tatsächlich hinterher 
auch funktioniert.
(Siehe LCD-Initialisierung. Da heißt es dann: "Ist wohl ein 
Timing-Problem...oder so...")
Es gibt aber auch viele Freaks, die einen am liebsten steinigen, wenn 
man einmal etwas Kritisches zum Thema Compiler oder Programmbibliotheken 
sagt.(...und dann noch "Sketche", igitt, was ist das ?(Scherzmachgrins).

Assemblersprache ist aber auch (manchmal) sehr mühevoll, da muss man 
halt durch.

Ein Lösungsbeispiel für Zeitschleife in Assembler lautet dann zum 
Beispiel so:
siehe Anhang

Vielleicht lässt sich das noch einbinden in den Code.

in diesem Sinne
gustav

Autor: Joachim B. (jar)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Uwe K. schrieb:
> Deine Überheblichkeit ist dermaßen zum kotzen

[ironie] so isser halt, stets hilfsbereit und konstruktiv [/ironie]

Autor: Jörg W. (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
1 lesenswert
nicht lesenswert
Flo schrieb:

> Da hast du natürlich Recht Jörg, wahrscheinlich wird die Toleranz nicht
> ausgereizt sein.

Bei weitem nicht.

> Aber ich darf micht doch niemals darauf verlassen das der Wert
> normalerweise immer nur +-1-2% daneben liegt.

Verlassen kannst du dich darauf natürlich nicht, aber bis zum
Beweis des Gegenteils kannst du in erster Näherung davon ausgehen,
dass diese Toleranz erreicht wird, und man kann solche Fehler
getrost erstmal woanders suchen.

> Per Default
> landet der Factory Calibration Wert in OSCCAL.

Das ist aber nicht irgendein stur daherkommender Wert, sondern etwas,
was während der letzten Testphase als Ergebnis einer Messung am
realen Bauteil in eine Fuse geschrieben wird.  Da ist das Bauteil
bereits fix und fertig im Gehäuse, also ziemlich genau im gleichen
Zustand, in dem du es zu Hause auspackst. ;-)

Daher passt der Wert eben auch normalerweise sehr viel besser als
garantiert.

> Das die User Calibration dann auch nur bei der kalibrierten Temperatur
> und VCC stimmt, sollte wohl jedem klar sein.

Die Vcc-Abhängigkeit wurde über die Jahre allerdings massiv reduziert,
und bei den neueren ATtinys ist auch die Temperaturabhängigkeit
nochmal drastisch reduziert worden.

gustav schrieb:
> Das ist ja auch der Grund, warum ich wohl oder übel lieber direkt in
> Assembler "programmiere".

Ach, und das hilft dagegen, eine falsche Anzahl von Wartezyklen zu
berechnen?

Die Wahrscheinlichkeit, dass sich der Compiler bei der Ermittlung
der Anzahl der Wartezyklen verrechnet, dürfte geringer sein als die,
dass sich der geneigte Assemblerprogrammierer an dieser Stelle
vertut, und wenn du gar keine Ahnung hast, wie _delay_ms() intern
implementiert ist, dann könntest du dich mit den Ratschlägen auch
etwas zurückhalten.

Autor: Frank M. (ukw) (Moderator) Benutzerseite
Datum:

Bewertung
1 lesenswert
nicht lesenswert
gustav schrieb:
> Ein Lösungsbeispiel für Zeitschleife in Assembler lautet dann zum
> Beispiel so:
> siehe Anhang

Sorry, diese "Lösung" ist funktional noch viel schlechter als 
_delay_xx() und daher überhaupt kein Gewinn. Deine Warteschleife 
berücksichtigt überhaupt nicht den CPU_Takt und muss für jeden 
abweichenden Takt angepasst werden. Ausserdem berücksichtigt Deine 
Schleife den Overhead der Schleife selbst nicht, was _delay_ms() und 
_delay_us() sehr wohl machen. Außerdem ist der Code wesentlich größer 
als der Assembler-Output, den der C-Compiler aus _delay_ms() bzw. 
delay_us() generiert.

gustav schrieb:
> Vielleicht lässt sich das noch einbinden in den Code.

Du hast das Problem überhaupt nicht verstanden. Warum sollte der TO 
diesen Code einbinden?

gustav schrieb:
> Das ist ja auch der Grund, warum ich wohl oder übel lieber direkt in
> Assembler "programmiere".

Dein Beispiel ist eher ein Grund, in C statt Assembler zu programmieren.

Autor: Holger K. (zaldo)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
M. K. schrieb:
> Also Energie sparen hat keinen nennenswerten Vorteil? Interessant.

Nicht um jeden Preis, nein. Ich fürchte, mein PC verbrät in den 5 
Minuten in denen ich das programmiere mehr Strom, als dieser Timer in 
100 Jahren einsparen würde, wenn ich die CPU in den Zählpausen schlafen 
schicke.

Autor: Holger K. (zaldo)
Datum:

Bewertung
1 lesenswert
nicht lesenswert
gustav schrieb:
> Das ist ja auch der Grund, warum ich wohl oder übel lieber direkt in
> Assembler "programmiere".

Das erste, einzigste und vermutlich auch letzte das ich in ASM 
programmiert habe war eine 6502 CPU. Und das war zu einer Zeit als die 
noch 'in' war :-)

Autor: Holger K. (zaldo)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Flo schrieb:
> Was den TO angeht, das er die Frequenz tatsächlich als 800kHz angegeben
> hat, hatte ich tatsächlich beim lesen übersehen. Das schrieb ich ja auch
> schon.
>
> Des weiteren wollte ich ihn nur darauf hinweisen, das er eben OSCCAL
> selber mit dem Kalibrierwert beschreiben muss, damit die RC Frequenz
> besser passt. Das macht der Controller nicht von alleine. Per Default
> landet der Factory Calibration Wert in OSCCAL.

Okay, aber damit mal wieder zurück zu den Anfängerfragen. (Ich 
überspringe mal den Punkt 
"Laden_des_Calibration_Wertes_aus_dem_Flash_oder_EEPROM")

Man vergebe mir bitte falls ich mal wieder etwas grundsätzlich falsch 
mache, aber:

Egal ob ich zu Beginn nun OSCCAL=0x00; oder OSCCAL=0xff; setze, es 
ändert sich rein garnichts ?!

Autor: Wolfgang (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
gustav schrieb:
> Die Libraries enthalten eben oft nicht das, was tatsächlich hinterher
> auch funktioniert.
> (Siehe LCD-Initialisierung. Da heißt es dann: "Ist wohl ein
> Timing-Problem...oder so...")

Wenn du irgend eine HD44780 Controller Library für für die Ansteuerung 
irgendeines LCD mit irgendeinem (mehr oder weniger) HD44780-kompatiblen 
Controller verwendest, ohne auf das Busy-Signal des Controllers zu 
achten, kann es schon mal passieren, dass ein evtl. knappes 
Steuer-Timing in der Library mit einem höheren Zeitbedarf für die 
Befehlsausführung im Conroller nicht harmoniert. Ob das in Assembler, 
Hex- oder C programmiert ist, ist völlig schnuppe.

Autor: c-hater (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Holger K. schrieb:

> Egal ob ich zu Beginn nun OSCCAL=0x00; oder OSCCAL=0xff; setze, es
> ändert sich rein garnichts ?!

Das kann eigentlich nur bedeuten, dass der Controller nicht mit dem 
internen Oszillator als Taktquelle läuft.

Und übrigens: man sollte niemals stumpf OSCCAL auf so extreme Werte 
setzen. Der Controller könnte dadurch abstürzen. In jedem Datenblatt 
steht, dass man OSCCAL nur in solchen Schritten ändern sollte, dass sich 
maximal Taktsprünge von 2% ergeben.

Autor: Planlos (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Holger K. schrieb:
> Man vergebe mir bitte falls ich mal wieder etwas grundsätzlich falsch
> mache

Mehrfach vorgeschlagen, Antwort steht m.W. noch aus:

Test ohne interrupts. Setze “cli();“ vor dein delay.

Autor: Holger K. (zaldo)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
c-hater schrieb:
> Und übrigens: man sollte niemals stumpf OSCCAL auf so extreme Werte
> setzen. Der Controller könnte dadurch abstürzen. In jedem Datenblatt
> steht, dass man OSCCAL nur in solchen Schritten ändern sollte, dass sich
> maximal Taktsprünge von 2% ergeben.

Naja, begonnen habe ich ja mit dem ausgeworfenem Korrekturwert. Nachdem 
sich da nichts getan hat habe ich es mit größeren Schritten versucht bis 
ich letztlich da angekommen bin.

Und ja, der läuft ganz sicher mit dem internen OSC


@Planlos: Werde ich heute Abend testen, ich hatte dieser Tage wie so oft 
nicht viel Zeit für mein Projekt.

Autor: Jörg W. (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Holger K. schrieb:
> Und ja, der läuft ganz sicher mit dem internen OSC

Das passt aber irgendwie mit der Aussage nicht recht zusammen. Eine
Änderung des OSCCAL von 0 auf 255 sollte die Frequenz des Oszillators
mindestens verdreifachen.

Autor: Dieter F. (jim_quakenbush)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jörg W. schrieb:
> Eine
> Änderung des OSCCAL von 0 auf 255 sollte die Frequenz des Oszillators
> mindestens verdreifachen.

Ja, Datenblatt Seite 218 ...

Autor: Holger K. (zaldo)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dann weiß ich auch nicht, es ist kein Quarz(oszillator) auch kein 
unsichtbarer oder eine sonstige Taktquelle da dran, an dem Port hängt 
eine LED und laut Fuse ist er auf internen OSC mit 8Mhz eingestellt.

Ich schau mir das nochmal in Ruhe an, da muss ja irgendwo der Wurm drin 
sein...

Autor: Pete K. (pete77)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Schon mal jetzt mit richtigem F_CPU Wert an der richtigen Stelle 
übersetzt?

: Bearbeitet durch User
Autor: Jörg W. (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Holger K. schrieb:
> Ich schau mir das nochmal in Ruhe an, da muss ja irgendwo der Wurm drin
> sein...

Du kannst ja als ersten Test mal eine Firmware machen, die nur das
OSCCAL setzt (oder es einfach auf dem Defaultwert lässt), sonst
nichts.  Dann setzt du die CKOUT-Fuse (Bit 6 der Low-Fuse auf 0),
und fortan muss auf PB5 der interne Takt herausgewackelt kommen.
Den kannst du an Oszi oder Zählfrequenzmesser messen.

Autor: Holger K. (zaldo)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jup, guter Plan Jörg, genau das werde ich mal probieren. Dann weiß ich 
auch gleich ob die Abweichung beim Delay programmtechnisch bedingt ist, 
oder ob bzw. in wie weit der OSC tatsächlich daneben tickt...

: Bearbeitet durch User
Autor: M. K. (sylaina)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Holger K. schrieb:
> M. K. schrieb:
>> Also Energie sparen hat keinen nennenswerten Vorteil? Interessant.
>
> Nicht um jeden Preis, nein. Ich fürchte, mein PC verbrät in den 5
> Minuten in denen ich das programmiere mehr Strom, als dieser Timer in
> 100 Jahren einsparen würde, wenn ich die CPU in den Zählpausen schlafen
> schicke.

Ist ja nicht um jeden Preis und deine CPU in deinem PC ist auch ein 
wenig was anderes als ein uC in einem Projekt. ;)

Autor: Holger K. (zaldo)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So, kaum das man mal ausgeschlafen an die Sache rangeht stellt man fest, 
dass OSCCAL=xxx die main() Schleife knapp verfehlt hat :-)

Was den internen OSC und die Factory calibration angeht, die sind 
(zumindest bei meinem) anscheinend besser als Ihr Ruf. Folgende 
Schwankungen habe ich (bei Vdd=5V) ermittelt:

T = -50°C   fosc=7,911 MHz
T = 20°C    fosc=8,013 MHz
T = 70°C    fosc=8,091 MHZ

Bei T = 20°C entspricht der ermittelte Korrekturwert für OSCCAL (0xB3) 
anscheinend auch der Factory calibration, denn ein setzen eben dieses 
Wertes ändert nichts weiter. Bei 70°C mag man die rund 1% Abweichung des 
OSC damit vielleicht noch etwas verbessern können aber hey... 1% sind 
für meine Anwendung mehr als ausreichend, zumal ich den Kameraden ja 
nicht bei 70° betrieben wollte.

Autor: Arduino Fanboy D. (ufuf)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Geht doch!

Um dem eine Krone aufzusetzen, könnte man das noch dynamisch anpassen.

1. Manch ein AVR hat einen eingebauten Temperatursensor.
2. der WDT-OSC taugt auch als Vergleich, er hat (meist?) einen 
umgekehrten Temperaturkoeffizienten.

: Bearbeitet durch User
Autor: m.n. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Arduino F. schrieb:
> Um dem eine Krone aufzusetzen, könnte man das noch dynamisch anpassen.

Anstatt der Krone würde ich statisch einen Quarz nehmen.

Autor: Holger K. (zaldo)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Könnte man machen, aber halte ich für absolut nicht notwendig (Könnte ja 
auch einfach einen Quarz oder einen temperaturkompensierten 
Quarzoszillator verwenden). Das ganze wird ein Belichtungstimer für mein 
(Platinen)belichter, wenn der bei 7 Minuten real am ende zwei Sekunden 
falsch geht, liegt das völlig im Toleranzbereich des Photoresisten.

Autor: Forist (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Holger K. schrieb:
> Das ganze wird ein Belichtungstimer für mein (Platinen)belichter,

Oh my god ...

Über 100 Postings über (sub-)prozentgenauen Taktabgleich für einen 
Prozess, der auf Grund seiner chemischen Natur eher logarithmisch 
"denkt".

Das nennt man wohl Overengineering

Autor: Holger K. (zaldo)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Forist schrieb:

> Das nennt man wohl *Overengineering*

Ich hab von vorneherein immer wieder betont, dass das ganze nicht 
hochgenau sein muss... Wenns mir doch keiner glaubt? ;-)

Autor: Jörg W. (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
m.n. schrieb:
> Arduino F. schrieb:
>> Um dem eine Krone aufzusetzen, könnte man das noch dynamisch anpassen.
>
> Anstatt der Krone würde ich statisch einen Quarz nehmen.

Der Quarz als gepriesenes Allheilmittel.

Man sollte auch seine Nachteile erwähnen: er schwingt aufgrund seiner
hohen Güte extrem langsam an.  Wenn man eine Applikation hat, die
viel schlafen will, aber zwischendrin häufig mal aufwachen, kostet
das einen Haufen Energie.  Der RC-Oszillator ist nach einer
Mikrosekunde stabil und benutzbar, ein Quarz braucht typisch was im
Bereich von Millisekunden.

Keramikresonatoren liegen irgendwo dazwischen, sowohl in der
Genauigkeit als auch Anschwingzeit.

Holger K. schrieb:
> dass OSCCAL=xxx die main() Schleife knapp verfehlt hat :-)

Nun, das erklärt's dann. :)

> Was den internen OSC und die Factory calibration angeht, die sind
> (zumindest bei meinem) anscheinend besser als Ihr Ruf.

Der Ruf des RC-Oszillators ist so schlecht nicht, es gibt eben nur
immer wieder ein paar Dauernörgler, für die bereits beim bloßen
Gedanken an einen solchen die Welt zusammenbricht, was die
Genauigkeit betrifft.  Die garantierten eher lausigen 10 % des
Datenblatts leisten dem natürlich noch Vorschub – und bedeuten, dass
man sich in einer Serienproduktion halt nicht drauf verlassen kann,
sondern es exemplarbhängig nachmessen muss.  Aber für Einzelstücke
ist das ohnehin kein Thema.

Autor: Holger K. (zaldo)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jörg W. schrieb:
> Man sollte auch seine Nachteile erwähnen

Nicht nur die, vorallendingen raubt mir das mindestens einen Port. Ich 
habe zwar in meiner Schaltung noch welche frei, die habe ich aber für 
spätere Optionen vorgesehen, und habe vor diesem Hintergrund keinen Port 
mehr über, den ich für einen Quarzoszillator verwenden könnte. Es ist 
halt immer das Gesamtbild entscheidend.

Autor: Erwin D. (Gast)
Datum:

Bewertung
-1 lesenswert
nicht lesenswert
Holger K. schrieb:
> Nicht nur die, vorallendingen raubt mir das mindestens einen Port.

Wenn du von einem externen Quarzoszillator sprichst, brauchst du genau 
ein Pin, um den Takt in den µC zu bekommen. Beim direkten Anschluß eines 
Quarzes brauchst du zwei Pins. Wie kommst du auf "mindestens einen 
Port"? Ein Port hat in der Regel 8 Pins. Wozu brauchst du dann die 
übrigen 7 bzw. 6 Pins?

Autor: Hanswurst (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Holger K. schrieb:
> So, kaum das man mal ausgeschlafen an die Sache rangeht stellt man fest,
> dass OSCCAL=xxx die main() Schleife knapp verfehlt hat :-)
> [...]

Nur mal so aus Neugierde, denn ich kann mir nicht erklären, was das zu 
bedeuten hat: Was meinst Du damit, dass der Ausdruck die main-Schleife 
verfehlt hat?

Autor: Holger K. (zaldo)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Erwin D. schrieb:
> brauchst du genau ein Pin

Das meinte ich eigentlich, sorry falsche Terminologie.


@Hanswurst: Ich hatte es außerhalb der main() schleife stehen.

Autor: Hanswurst (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Holger K. schrieb:
[...]
> @Hanswurst: Ich hatte es außerhalb der main() schleife stehen.

Aha. Danke.

Wenn Du erlaubst, möchte ich noch eine weitere Frage nachschieben:

Inwiefern spielt das eine Rolle, ob der Ausdruck innerhalb oder 
ausserhalb der main-Schleife steht? Ich meine, ich gehe davon aus, dass 
Du OSCCAL auf einen (genau einen) bestimmten Wert gesetzt hast. Da ist 
es, aus meiner Sicht, eigentlich nicht notwendig, ihn mehrfach auf den 
gleichen Wert zu setzen. Der bleibt ja im Register bis der Strom 
abgeschaltet wird.

Das soll keine Kritik sein: Ich kann nur keinen Sinn darin erkennen, was 
ja auch an meiner Unkenntnis irgendeines Details liegen kann. Es ist 
auch nicht wichtig, aber irgendwie beschäftigen mich solche 
"unwichtigen" Details. Wohl zu viel Columbo geguckt :-)

Autor: Holger K. (zaldo)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich kann Dir deine Frage nicht beantworten. Wenn Du dem Thread gefolgt 
bist hast Du sicher gelesen, dass es zuvor (also außerhalb von main) 
nicht funktioniert hat. Was auch immer ich in das Register geschrieben 
habe (oder glaubte geschrieben zu haben), es hatte keine Auswirkung.

Nachdem es nun innerhalb von main() steht funktioniert es.

: Bearbeitet durch User
Autor: Hanswurst (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Holger K. schrieb:
> Ich kann Dir deine Frage nicht beantworten. Wenn Du dem Thread gefolgt
> bist hast Du sicher gelesen, dass es zuvor (also außerhalb von main)
> nicht funktioniert hat.

Genau das habe ich nirgendwo gelesen. Wo hast Du das denn geschrieben?

> [...]
> Nachdem es nun innerhalb von main() steht funktioniert es.

Ich vermute aber, mein Unverständnis ist von folgendem verursacht:

main () ist eine Funktion. Sie wird aber nicht in einer Schleife 
aufgerufen. Eine Schleife kommt nur dann zur Ausführung, wenn man eine 
hinschreibt. Also etwa:
main () {
  while (1) {
  }
}

Ich habe nun unter eine "main-Schleife" (nicht "main-Funktion") genau so 
ein Konstrukt verstanden.

Und darin spielt es, wie ich nach wie vor meine, keine Rolle ob die 
Zuweisung an OSCCAL nun innerhalb der Schleife oder ausserhalb 
geschieht.
Nur das eben die Zuweisung in dem einen Fall mehrfach ausgeführt wird - 
was wiederrum unnötig ist.
main () {
  OSCCAL = xyz;  // wird einmal bei Progammstart ausgeführt.
  while (1) {
    OSCCAL = xyz;   // wird bei jedem Schleifendurchlauf ausgeführt.
  }
}

Beides hat aber, bei identischem xyz immer die selbe Wirkung.

Was meinst Du dazu?

Autor: Markus F. (mfro)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Für mich bleibt hier nur eine Frage offen: was um Himmels Willen ist 
eine "main-Schleife"?

Autor: Draco (Gast)
Datum:

Bewertung
1 lesenswert
nicht lesenswert
Markus F. schrieb:
> Für mich bleibt hier nur eine Frage offen: was um Himmels Willen ist
> eine "main-Schleife"?

Laut Wikipedia: "Die Mainschleife bei Urphar ist eine Flussschlinge des 
Mains am südöstlichen Rand des Mainvierecks in Baden-Württemberg und 
Bayern."

:-D

Aber es hat sich halt mal so eingebürgert, obwohl es ja kein richtiger 
Ausrduck ist, das die main-Schleife die Dauerschleife in der Main() 
Funktion ist. Jeder weis was es ist, jeder nutzt diesen Ausdruck - 
jemanden dann deswegen Dumm machen zu wollen ist dämlich. Das ist 
genauso dämlich wie jemanden darauf hinzuweisen das ein Kondom nicht 
"Gummi" heißt sondern Präservativ - genauso dämlich!

Autor: Wolfgang (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Markus F. schrieb:
> Für mich bleibt hier nur eine Frage offen: was um Himmels Willen ist
> eine "main-Schleife"?

Übersetze es einfach als "Haupt-Schleife", wenn es dir dann klarer wird.
Ausführlich beschrieben ist das diejenige Funktion oder derjenige 
Programmblock, die/der im Hauptteil des Programms in einer 
Endlosschleife immer wieder aufgerufen wird.
Beim Arduino z.B. heißt die betreffende Funktion einfach loop().

Autor: Norbert (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Draco schrieb:
> Markus F. schrieb:
>> Für mich bleibt hier nur eine Frage offen: was um Himmels Willen ist
>> eine "main-Schleife"?

> Aber es hat sich halt mal so eingebürgert, obwohl es ja kein richtiger
> Ausrduck ist, das die main-Schleife die Dauerschleife in der Main()
> Funktion ist. Jeder weis was es ist, jeder nutzt diesen Ausdruck...
Jeder--;
Es ist keine Schleife, also nennt 'man' es auch nicht so!

Autor: Draco (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Norbert schrieb:
> Es ist keine Schleife, also nennt 'man' es auch nicht so!
while(1)
{

}

... ist keine Schleife?! Aha! :'D

Autor: Norbert (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Draco schrieb:
> Norbert schrieb:
>> Es ist keine Schleife, also nennt 'man' es auch nicht so!
>
>
> while(1)
> {
> 
> }
> 
>
> ... ist keine Schleife?! Aha! :'D

Hast du ein Lese- oder Verständnisproblem?
Es geht hier um die Formulierung 'main-Schleife'
int main(void) {
    ...
    return 0;
}
Das ist keine Schleife und man muss auch kein Raketenwissenschaftler 
sein um das zu erkennen, oder?

Autor: Wolfgang (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es ging um die Hauptschleife, m.a.W. um den endlos ausgeführten 
Programmteil in Main(). Wenn du das /while(1) {}/ natürlich 
unterschlägst, kannst du die Schleifenstruktur auch nicht mehr 
entdecken.

Norbert schrieb:
> Das ist keine Schleife und man muss auch kein Raketenwissenschaftler
> sein um das zu erkennen, oder?

Autor: Holger K. (zaldo)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Komisch, Eigentlich weiß jeder was gemeint ist, aber der gesamte 
Hirnschmalz der Community wendet seiner Energie auf um einem 
offensichtlichen Anfänger und Newbie mit irgendwelchen dumm gestellten 
Suggestivfragen klarzumachen, dass er halt etwas nicht korrekt 
ausformuliert hat. Ich bin raus aus diesem Thread, mein Problem ist eh 
gelöst. Danke nochmal an die die geholfen haben!

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.