Forum: Mikrocontroller und Digitale Elektronik interruptroutinen


von Philipp Karbach (Gast)


Lesenswert?

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!

von Rahul D. (rahul)


Lesenswert?

>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"!

von Joe (Gast)


Lesenswert?

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"

von Joe (Gast)


Lesenswert?

Sorry, Programmiersprache sollte klar sein (while) ;-)) Beispiel paßt 
also.

von Spess53 (Gast)


Lesenswert?

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

von Philipp Karbach (Gast)


Lesenswert?

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.

von Johannes M. (johnny-m)


Lesenswert?

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.

von AVRFan (Gast)


Lesenswert?

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

von Philipp Karbach (Gast)


Lesenswert?

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.

von Johannes M. (johnny-m)


Lesenswert?

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

von AVRFan (Gast)


Lesenswert?

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

von Falk B. (falk)


Lesenswert?

@ 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

von Philipp Karbach (Gast)


Lesenswert?

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

von Karl H. (kbuchegg)


Lesenswert?

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.

von Johannes M. (johnny-m)


Lesenswert?

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.

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.