Hallo,
ich bin gerade dabei mir Timer beizubringen.
Ich habe für den Arduino Uno ein Programm geschrieben, um eine LED
blinken zu lassen. Einse Sekunde an, eine Sekunde wieder aus. Wenn ich
das blinken aber mit Uhren vergleiche (Windows, Online), dann ist die
Frequenz nicht exakt die gleiche, der Arduino zieht nach. Kann mir
jemand sagen woher das kommt bzw. was an meinem Code falsch ist?
Hubert G. schrieb:> Beim Mega328 ist der Timer1 16Bit.> Um wieviel ist die Sekunde langsamer?
Ich hatte vorhin das Oszi dran und glaube, dass es 40ms waren.
Also der Code stimmt, unter der Annahme dass der Takt 16Mhz ist.
Allerdings toggelst du den Pin bei jedem Interrupt, die LED ist also
eine Sekunde an, eine Sekunde aus usw.
Der Takt ist 0,960 Sekunden? Das sind dann 4 Promille zu wenig. Ich
glaube das ist die Genauigkeit die man erwarten kann.
32768kHz Uhrenquarz wäre die Antwort.
Aber wenn du nur den Timer lernen wolltest: Glückwunsch, den CTC Modus
kannst du.
Wenn du Lust hast, kannst du ein Potentiometer an den ADC anschließen
und darüber deinen Compare-Wert feintunen. Aber erwarte keine genau
gehende Uhr ohne Uhrenquarz.
Wolfgang schrieb:> Soder D. schrieb:>> #define F_CPU 16000000UL>> Ein paar von den vielen Nullen sind mit Sicherheit gelogen. Ich tippe> auf mindesten drei.
Kann sein dass ich auf dem Schlauch stehe, aber ich lese da 16Mhz ab:
>> #define F_CPU 16.000.000UL
Hubert G. schrieb:> Hast du im Arduino einen Originalen Mega328 drin oder ist es ein neuer.> Wenn neu, dann stimmen die Fuses nicht.
In der tat ist es ein neues Atmega328p, da er sonst allerdings
funktioniert (wie genau hab ich da aber noch gar nicht beobachtet) habe
ich mir gedacht die Fuses stimmen schon.
Weiß jemand was die richtigen Fuses sind? Kenn mich da leider auch nicht
so aus.
Soder D. schrieb:> Hubert G. schrieb:>> Beim Mega328 ist der Timer1 16Bit.>> Um wieviel ist die Sekunde langsamer?>> Ich hatte vorhin das Oszi dran und glaube, dass es 40ms waren.
Ich glaube, daß mal genau messen solltest und uns verläßliche Angaben
machen solltest. Auch ein Oszi könnte falsch messen. Vielleicht ist eine
Kontrollmessung mit einem anderen Gerät möglich.
Sascha schrieb:> Kann sein dass ich auf dem Schlauch stehe, aber ich lese da 16Mhz ab:>>> #define F_CPU 16.000.000UL
Eben, aber es sind bestimmt nicht 16,000000 Mhz.
Für eine genau gehende Uhr wird man korrigierend eingreifen müssen.
Damit hätte sich dann auch das Thema Uhrenquarz erledigt, zumindest wenn
man versucht ist, wegen eines passenden Teilerfaktors darauf zurück zu
greift.
Beitrag "Die genaue Sekunde / RTC"
luigi schrieb:> Soder D. schrieb:>> Hubert G. schrieb:>>> Beim Mega328 ist der Timer1 16Bit.>>> Um wieviel ist die Sekunde langsamer?>>>> Ich hatte vorhin das Oszi dran und glaube, dass es 40ms waren.>> Ich glaube, daß mal genau messen solltest und uns verläßliche Angaben> machen solltest. Auch ein Oszi könnte falsch messen. Vielleicht ist eine> Kontrollmessung mit einem anderen Gerät möglich.
Die Fuses habe ich nun richtig eingestellt, aber keine Besserung:
Genaue Oszimessung: Tein=Taus=1,04s
Messung passt also genau zu dem Bild, was mir auch online Uhren oder die
Windows Uhr vermitteln.
EDIT: Ich habs mal mit _delay_ms(1000); gemacht und jetzt zeigt das Oszi
genau eine Sekunde an. Wohl doch programmierfehler?
Gerhard schrieb:> TCCR1B |= (1<<WGM12); // NICHT TCCR1A |= (1<<WGM12);
Merkt das dieser Kompiler nicht, wenn es ein Bit des Namens WGM12 in dem
Register TCCR1A gar nicht gibt? Das wäre ja ganz großer Pfriem...
MfG Paul
Gerhard schrieb:> Nein!> Für den Compiler bedeutet WGM12 nur eine "3".
Na super...
Da bin ich heilfroh, daß in z.B. in Bascom die Bit- und Registernamen
mit denen der .inf-Datei verglichen werden und so ein Fehler sofort
auffällt, da das Programm dann nicht kompiliert wird.
MfG Paul
Paul B. schrieb:> Merkt das dieser Kompiler nicht, wenn es ein Bit des Namens WGM12 in dem> Register TCCR1A gar nicht gibt? Das wäre ja ganz großer Pfriem...
Nein. WGM12 ist definiert als Zahl 3. Das hat aber nichts mit dem
Compiler zu tun.
Der Compiler rechnet 1 << 3 aus und setzt das Ergebnis da rein. Ob das
Sinn macht, interessiert ihn nicht. Hat ihn auch ncht zu interessieren.
Was den Inhalt der Daten angeht, ist immer noch der Programmierer der
Chef. Du könntest auch
Danke für die Erklärung.
Wenn die Bezeichnungen der jeweiligen Bits aus dem Datenblatt hier nur
Schall und Rauch sind, dann tun sich dadurch m.E.n. Stolperfallen en
Gros auf, die die Arbeit nicht leichter machen.
Ich bin froh (und jetzt noch ein Stück froher), daß ich mich mit solch
einem Mist nicht herumschlagen muß.
MfG Paul
Paul B. schrieb:> Da bin ich heilfroh, daß in z.B. in Bascom die Bit- und Registernamen> mit denen der .inf-Datei verglichen werden und so ein Fehler sofort> auffällt, da das Programm dann nicht kompiliert wird.
€Paul: Dann mach mal eine Zeile in BASCOM mit obiger Zuweisung, WGM12
nach tccr1a, die nicht compiliert wird. Syntax muß natürlich richtig
sein.
luigi schrieb:> €Paul: Dann mach mal eine Zeile in BASCOM mit obiger Zuweisung, WGM12> nach tccr1a, die nicht compiliert wird. Syntax muß natürlich richtig> sein.
Das macht er komischerweise. Für TCCR1A aber auch für TCCR1B.
S. Landolt schrieb:> Und bitte auch noch mit dem Synonym CTC1; da bin ich gespannt.
Das macht er nicht. Hustet und spuckt...
MfG Paul
@ Paul Baumann (paul_baumann)
>Wenn die Bezeichnungen der jeweiligen Bits aus dem Datenblatt hier nur>Schall und Rauch sind, dann tun sich dadurch m.E.n. Stolperfallen en>Gros auf, die die Arbeit nicht leichter machen.
Das ist wohl leider wahr. Man kann auch vollkommen falsche Bitnamen auf
vollkommen falsche Register anwenden, es gibt keinen Compilerfehler!
Die Alternative dazu wäre, die Register und deren Bits als Structs mit
Bitfeldern anzulegen. Das macht z.B. der C2000 Compiler von TI. Dort
kann sowas nicht passieren.
>Ich bin froh (und jetzt noch ein Stück froher), daß ich mich mit solch>einem Mist nicht herumschlagen muß.
;-)
Man kann es auch so sehen. Die Programmiersprache C ist wie ein
Rasiermesser. Sehr scharf, aber man muss damit umgehen können, um sich
nicht zu verletzen.
Da wären wir bei einer strikten Typprüfung.
Die Funktioniert nur wenn die Register komplett als Datentyp beschrieben
werden.
Die AVRLIBC macht das alles über Marcos.
@Paul Baumann (paul_baumann)
>> Da wären wir bei einer strikten Typprüfung.>Praktisch wie am Eingang einer Disco: "Du kummst hier net rein,>weißtu!?">;-)
Na wenigstens kannst du über den Witz lachen. Die Typprüfung an der
deutschen Außengrenze fehlt seit geraumer Zeit . . . (jajajajajaja, er
hat P........ gesagt!)
Falk B. schrieb:> Na wenigstens kannst du über den Witz lachen. Die Typprüfung an der> deutschen Außengrenze fehlt seit geraumer Zeit . . . (jajajajajaja, er> hat P........ gesagt!)
Ja, das ist wohl wahr. Vor Allem fehlt der Platz, um neue Arrays
anzulegen, die Taktfrequenzen werden immer höher und die Timer laufen
schneller ab, als manch Einer denkt. Aber: Lassen wir das, sonst gibt es
durch die einschlägigen Quellen gleich einen Interrupt und ich habe
keine Lust, am
Sonnabend-Nachmittag noch eine Service-Routibne dafür zu machen.
mfG Paul
Gerhard schrieb:> Du hast NICHT den mode 4 "CTC" eingestellt!> Mode 4:>
1
>TCCR1B|=(1<<WGM12);// NICHT TCCR1A |= (1<<WGM12);
2
>
>> Gerhard
Ahh, natürlich, da hätt ich natürlich auch selber drauf kommen können.
Funktioniert so wunderbar.
Hab das ganze jetzt auch mal mit OCR1B probiert und da geht die LED an
D5 aber gar nicht mehr aus. OCRnB ist doch das gleiche wie CRnA, den ich
mit einem anderen Wert befüllen kann....
Soder D. schrieb:> Hab das ganze jetzt auch mal mit OCR1B probiert und da geht die LED an> D5 aber gar nicht mehr aus. OCRnB ist doch das gleiche wie CRnA, den ich> mit einem anderen Wert befüllen kann....
Vom Prinzip her schon - aber...
Nur A kannst du verwenden um den Zählumfang im CTC-Mode zu begrenzen. Da
bei deinem Test nun aber A=0 (default) wird logischer Weise dein Wert in
B nie erreicht werden.
Sascha
Scheint so, dass CTC mit nur WGM12 auf high nur für OCR1A funktioniert
(ausgehend vom ATmega328).
Wenn du zusätzlich WGM13 setzt, dann geht das auch mit dem Register
ICR1.