ich versuche gerade eine genaue uhr zu programmieren. Das ganze läuft
auch schon nur ist es noch nicht besonders genau. Dabei kommt bei mir
immer mal wieder eine frage auf: Wann laufen interruptroutinen ab? Vor
der while schleife oder danach? Wie sehr beeinflusst die schleife bzw.
andere routinen die interruptroutine? (zum beispiel auf dem LCD
zeichnen, ist dann der sekundentakt noch genau? Was ist wenn ich ein
paar ms delay zwischendrin hab?)
Wäre nett wenn mir das jemand erläutern könnte!
>Vor der while schleife oder danach?
Oder mittendrin. Das kann man eher selten genau vorraussagen.
>Wie sehr beeinflusst die schleife bzw. andere routinen die interruptroutine?
Beim AVR wird immer nur eine Interruptroutine zur Zeit abgearbeitet;
will sagen: Es gibt keine mit höherer Priorität. Nur wenn mehrere
Interrupts auftreten, wird zuerst der abgearbeitet, der die höchste
Priorität / niedrigste Adresse in der Interrupt-Vektor-Tabelle hat.
>Wäre nett wenn mir das jemand erläutern könnte!
Such mal in der Codesammlung nach "Uhr" oder "Sekunde"!
Wäre schön wenn du mitteilen könntest welchen MC und Programmiersprache
du verwendest.
Bei den 8x51 Typen kann man die Interruptprioritäten z.B. bestimmen.
Eine genaue Uhr (vergleichbar mit der Gangenauigkeit von typ.
Quarzuhren) ist möglich.
Ein Beispiel für AVR's findest du hier:
Beitrag "Die genaue Sekunde / RTC"
Hi
Interrupts unterbrechen das Programm einige Takte nach Auftreten des
entsprechenden Ereignisses. Ausnahnme: Der Controller arbeitet gerade
einen höher priorisierten Interrupt ab. Dann erfolgt die Abarbeitung
danach. Timingprobleme können nur auftreten, wenn die Abarbeitungszeit
der Interruptroutine länger als die Zeit zwischen zwei Interrupts ist.
Entscheidender für die Ganggenauigkeit deine Uhr dürfte die Wahl der
richtigen Qurzfrequenz und die Einstellung des Timers sein.
MfG Spess
sorry, arbeite mit einem mega2561, also alles avr technik. Benutze den
Timer 1 (16bit) mit einem Prescaler von 256. Die F_CPU liegt bei 8Mhz
(interner Quarz, wie genau ist der eigentlich?). Ich setze den TCNT1 auf
MAX - (F_CPU/PRESCALER) beim start und bei jedem Overflow, im Overflow
interrupt zähle ich auch die Sekunden hoch. Habe das ganze mal über
nacht laufen lassen, also rund 10 Stunden, die Uhr geht 6 Minuten nach.
Meine platine hat sogar einen Uhrenquarz drauf, leider finde ich
überhaupt KEINE Beispiele dazu wie man die beim mega128/256 ansteuert..
Die Informationen im Datenblatt finde ich auch eher rätselhaft.
Philipp Karbach wrote:
> sorry, arbeite mit einem mega2561, also alles avr technik. Benutze den> Timer 1 (16bit) mit einem Prescaler von 256. Die F_CPU liegt bei 8Mhz> (interner Quarz, wie genau ist der eigentlich?).
Einen internen Quarz gibt es nicht! Das ist ein RC-Oszillator.
Im Übrigen ist die "Ansteuerung" bei den Peripherie-Einheiten nicht
anders als bei anderen AVRs auch. Siehe AVR-Tutorial bzw.
AVR-GCC-Tutorial.
> (interner Quarz, wie genau ist der eigentlich?)
Neiheiiiin, kein AVR-IC ist so groß, dass man da einen Quarz drin
unterbringen könnte. Bei der internen Taktquelle handelt sich um einen
RC-Oszillator, und der tickt prinzipbedingt bei weitem nicht so präzise
wie ein Quarz. Deshalb kannst Du damit - wie Du selbst festgestellt
hast - eine zufriedenstellend ganggenaue Uhr nicht realisieren. Für
diesen Anwendungszweck kommt als Taktquelle nur ein Quarz bzw.
Quarzoszillator in Frage.
Im Datenblatt Deines AVRs findest Du hinten ein paar Diagramme, in denen
die Abhängigkeit der Frequenz des internen RC-Oszillators u. a. von der
Temperatur und der Betriebsspannung graphisch dargestellt ist.
sorry für die falsche formulierung! War mir nur nicht so ganz sicher was
im IC Gehäuse steckt. Jetzt konnte mir aber immer noch keiner ein
wirkliches Beispiel zur ansteurung des RTC Quarzes zeigen.
Alle erforderlichen Informationen gehen ziemlich eindeutig aus dem
Datenblatt hervor. Der Timer muss in die asynchrone Betriebsart versetzt
werden. Dazu müssen nur ein paar Bits in den betreffenden
Steuerregistern gesetzt werden. Da brauchts wirklich kein
"Beispielprogramm". Oder weißt Du nicht, wie man Bits in I/O-Registern
setzt?
BTW: Es gibt im Datenblatt sogar einen extra Abschnitt "Asynchronous
operation of the Timer/Counter". Da bleiben eigentlich keine Fragen
offen...
>Jetzt konnte mir aber immer noch keiner ein>wirkliches Beispiel zur ansteurung des RTC Quarzes zeigen.
Wieso willst Du den Uhrenquarz überhaupt verwenden? Am einfachsten wäre
es, wenn Du einen gewöhnlichen 8-MHz-Quarz (oder Quarzoszillator) nimmst
und Deinen µC damit taktest. Dann läuft der komplette Controller mit
einer hochgenauen Frequenz - vorschriftsmäßige Betriebsbedingungen für
den Quarz vorausgesetzt, versteht sich. Also die Zuleitungen kurz
halten und nicht auf die Lastkondensatoren verzichten.
@ AVRFan (Gast)
>Wieso willst Du den Uhrenquarz überhaupt verwenden? Am einfachsten wäre
Vielleicht um Strom zu sparen.
>es, wenn Du einen gewöhnlichen 8-MHz-Quarz (oder Quarzoszillator) nimmst>und Deinen µC damit taktest. Dann läuft der komplette Controller mit
Ja, das geht auch und ist für den Anfang auch besser, weil einfacher.
AVR - Die genaue Sekunde / RTC
MfG
Falk
nachdem ich das datenblatt noch 4 mal studiert hab, danke nochmal für
den tipp :). Habe ich jetzt noch etwas hinbekommen, wenn alles stimmt
dürfte jetzt der Uhrenquarz genutzt werden:
#define CPU 32768
#define TIMER 256 - (CPU/128)
SIGNAL (SIG_OVERFLOW2) {
second++;
TCNT2 = TIMER;
}
void timer_init (void) {
TIMSK2 &=~((1<<TOIE2)|(1<<OCIE2B));
ASSR |= (1<<AS2);
TCNT2 = 0x00;
TCCR2B = 0x05;
while(ASSR & 0x07);
TIMSK2 |= (1<<TOIE2);
sei();
}
Ist das korrekt? (möglicherweise veraltet etc. aber ich will erstmal ein
brauchbare version haben bevor ich optimiere...) Wenn ich die Uhr starte
zählt die sekunde hoch, sieht okay aus, ob es genau ist kann ich so
nicht sagen :).
Philipp Karbach wrote:
> Ist das korrekt?
Was sagt dein Datenblatt?
> brauchbare version haben bevor ich optimiere...) Wenn ich die Uhr starte> zählt die sekunde hoch, sieht okay aus, ob es genau ist kann ich so> nicht sagen :).
Glaub ich eher nicht.
Schon alleine deswegen, weil du im Interrupthandler den
Timer immer wieder nachlädst und du nicht weist wieviele
Takte vom Auslösen des Overflow Interrupts bis zum Nachladen
des Timers vergangen sind.
Zunächst mal:
Was willst Du eigentlich genau machen?
a) Den µC mit dem Uhrenquarz takten oder
b) Eine RTC mit Timer 2 im Asynchronmodus basteln
Wenn Du a) machen willst (was im Prinzip machbar wäre, allerdings den
Programmablauf extrem verlangsamen würde) ist Timer 2 wurscht.
Andernfalls (b)) ist aber der CPU-Takt nicht 32768... Also bitte mal
etwas genauere Spezifikationen. Und wie weiter oben schon mal bemerkt:
Grundsätzlich brauchst Du für einen Sekundentakt keinen Uhrenquarz, es
sei denn, Du willst den µC tatsächlich schlafen legen, um Strom zu
sparen.
Im Programm stimmt einiges nicht. SIGNAL ist tatsächlich veraltet (wie
Du vermutet hast) und wenn Du Dir selbst einen Gefallen tun willst,
verwende ISR. Und poste bitte ein KOMPLETTES Programm! Ob das
überhaupt funktionieren kann, kann man nur sagen, wenn man den Rest auch
gesehen hat.