Forum: Mikrocontroller und Digitale Elektronik Verständnisproblem Interrupt (ATMEGA16)


von Humphrey (Gast)


Lesenswert?

Hallo Zusammen.

Ach Mensch, wieder ein Beitrag über Intrerrupts :)
Ich hoffe jemand könnte sich trotzdem kurz die Zeit nehmen, mir zu 
helfen, stehe nämlich gerade recht auf dem Schlauch!

Also folgendes:

Ich habe einen 5.24288MHz Quarz. Ich löse damit alle 100ms einen 
Interrupt aus und zwar benutze ich den 16-Bit Timer und einen Prescaler 
von 8.
Das klappt bis jetzt auch alles wunderbar. Da ich ein bisschen spät dran 
bin mit der Entprellung (habe das ganze bis jetzt vor mich hingeschoben) 
möchte ich gerne die Entprellung auch in einer Interrupt Routine lösen.

Den Code dazu habe ich auch schon (einfache State-Machine), allerdings 
ist 100ms Entprellzeit einfach zu lang. Deshalb hätte ich eigentlich 
gerne einen Interrupt alle 10ms.

Einen Quarz habe ich nicht gefunden, bei dem der die ganze Geschichte 
schön aufgeht, darum möchte ich fragen: Wie und wo kann ich angeben, 
wann der Interrupt stattfinden soll? Ich habe bis jetzt einfach immer 
mit dem Overflow gearbeitet aber eigentlich will ich ja, dass der 
Interrupt schon früher auslöst. Wie würdet ihr das lösen?

Gruss
Humphrey

von spess53 (Gast)


Lesenswert?

Hi

>Wie würdet ihr das lösen?

Timer im CTC-Mode initialisieren.

MfG Spess

von Humphrey (Gast)


Lesenswert?

spess53 schrieb:
> Timer im CTC-Mode initialisieren.

Hm.. habe das noch nie gemächt, wäre sehr froh um ein wenig 
Hilfestellung!
Ich habe mir das mal im Datenblatt der ATMEGA16 rausgesucht, Seite 112 
Table 47. Ich habe es jetzt nicht ganz durchschaut, in welches Register 
diese Bits kommen? Oder haben die etwa ein eigenes Register?

Gruss
Gordon

von Karl H. (kbuchegg)


Lesenswert?


von Humphrey (Gast)


Lesenswert?

Ah, der Beitrag ist aber gut verständlich geschrieben. Vielen Dank!
Ich denke es wird das einfachste sein, wenn ich einen 8Mhz Quarz nehme, 
Prescaler von 8 und den Timer1 bis 9999 (10'000 - 1) zählen lasse?

Jetzt muss ich das nur noch irgendwie mit der Initialisierung hinkriegen 
:P
Melde mich dann nochmal, wenn ich mich da etwas schläuer gemacht habe.

Gruss
Humphrey

von spess53 (Gast)


Lesenswert?

Hi

>Hm.. habe das noch nie gemächt, wäre sehr froh um ein wenig
>Hilfestellung!

Dann wird es langsam Zeit.

>Ich habe mir das mal im Datenblatt der ATMEGA16 rausgesucht, Seite 112
>Table 47. Ich habe es jetzt nicht ganz durchschaut, in welches Register
>diese Bits kommen? Oder haben die etwa ein eigenes Register?

Dann sieh dir die Beschreibung der Register TCCR1A und TCCR1B an. Die 
Beschreibung von CTC und die Berechnung findest du unter 'Modes of 
Operation'.

Wenn du keine genaue 10ms brauchst geht auch ein 8-Bit-Timer im 
Overflow.

MfG Spess

von Karl H. (kbuchegg)


Lesenswert?

Humphrey schrieb:
> Ah, der Beitrag ist aber gut verständlich geschrieben. Vielen Dank!
> Ich denke es wird das einfachste sein, wenn ich einen 8Mhz Quarz nehme,
> Prescaler von 8 und den Timer1 bis 9999 (10'000 - 1) zählen lasse?

Hä?
CTC Modus und ein bischen rechnen?


(ums rechnen wirst du auf Dauer nicht herumkommen. Also gewöhn dich 
besser jetzt schon daran. Das ist täglich Brot, die Timereinstellungen 
ausrechnen zu können. Wenn du erst mal verstanden hast, was da abgeht, 
ist das doch trivial. Oder bist du auch einer von den Programmierern, 
die nur dann arbeiten können, wenn man ihnen ihr Problem ganz konkret 
mit ihren Zahlen vorkaut?)

von Humphrey (Gast)


Lesenswert?

spess53 schrieb:
> Wenn du keine genaue 10ms brauchst geht auch ein 8-Bit-Timer im
> Overflow.

Doch, muss schon ziemlich genau sein (Uhr).

Karl Heinz Buchegger schrieb:
> Hä?
> CTC Modus und ein bischen rechnen?

Habe ich doch gerade? 8Mhz / 8 = 1Mhz. Im 1Mhz Takt zählt er 100 *  auf 
10'000 (resp. 9999) -> 100 Interrupts pro Sekunde -> alle 10ms ein 
Interrupt.

Oder sehe ich das falsch?

Gruss
Humphrey

von Karl H. (kbuchegg)


Lesenswert?

Humphrey schrieb:
> spess53 schrieb:
>> Wenn du keine genaue 10ms brauchst geht auch ein 8-Bit-Timer im
>> Overflow.
>
> Doch, muss schon ziemlich genau sein (Uhr).
>
> Karl Heinz Buchegger schrieb:
>> Hä?
>> CTC Modus und ein bischen rechnen?
>
> Habe ich doch gerade? 8Mhz / 8 = 1Mhz. Im 1Mhz Takt zählt er 100 *  auf
> 10'000 (resp. 9999) -> 100 Interrupts pro Sekunde -> alle 10ms ein
> Interrupt.
>

Und warum willst du da jetzt deinen Quarz wechseln?

> Oder sehe ich das falsch?

Für eine Uhr siehst du das sowieso falsch. Denn auch dein 8Mhz Quarz 
macht nicht 8000000 Schwingungen in der Sekunde sondern ein paar 100 
mehr oder weniger. D.h. da kommst du sowieso nicht drummherum die 
genaue(!) Quarzfrequenz festzustellen (und mit einem Vorteiler von 1 zu 
arbeiten. Jede Schwingung zählt)

d.h. dein 8 Mhz Quarz ist genausogut wie dein 5.irgendwas Mhz Quarz

AVR - Die genaue Sekunde / RTC

von Humphrey (Gast)


Lesenswert?

Karl Heinz Buchegger schrieb:
> d.h. dein 8 Mhz Quarz ist genausogut wie dein 5.irgendwas Mhz Quarz

Das weiss ich, und mit meinem 5.xxx Quarz habe ich pro Tag ca. 2 
Sekunden Abweichung, was mir absolut genügt. Für die 2. Version ist 
sowieso ein RTC vorgesehen -> mir geht es noch nicht um die absolute 
Genauigkeit.

Karl Heinz Buchegger schrieb:
> Und warum willst du da jetzt deinen Quarz wechseln

Naja, warum nicht? Ich muss ca. 10m laufen um einen 8MHz Quarz zu holen, 
dann noch ca. 20 Sekunden für's einlöten.. geht einfach schneller.

Gruss
Humphrey

von Karl H. (kbuchegg)


Lesenswert?

Humphrey schrieb:
> Karl Heinz Buchegger schrieb:
>> d.h. dein 8 Mhz Quarz ist genausogut wie dein 5.irgendwas Mhz Quarz
>
> Das weiss ich, und mit meinem 5.xxx Quarz habe ich pro Tag ca. 2
> Sekunden Abweichung, was mir absolut genügt. Für die 2. Version ist
> sowieso ein RTC vorgesehen -> mir geht es noch nicht um die absolute
> Genauigkeit.
>
> Karl Heinz Buchegger schrieb:
>> Und warum willst du da jetzt deinen Quarz wechseln
>
> Naja, warum nicht? Ich muss ca. 10m laufen um einen 8MHz Quarz zu holen,
> dann noch ca. 20 Sekunden für's einlöten.. geht einfach schneller.

Wetten nicht?

von Karl H. (kbuchegg)


Lesenswert?

10 ms sind 100 ISR AUfrufe in der Sekunde


Prescaler auf 1

5242880 / 100  ->  524288

CTC Modus ein. OCR Register auf 52428

10 ISR Aufruf abzählen.

Fertig.

Hat keine 20 Sekunden gedauert.

von Karl H. (kbuchegg)


Lesenswert?

Danach lässt du deine Uhr (wie im Link beschrieben) ein paar Tage 
laufen, stellst die Abweichung fest und rechnest dir die tatsächliche 
QUarzfrequenz aus. Die Korrektur machst du bei jedem 10 ISR Aufruf, 
indem du den durch Manipulation des OCR1A Registers um die enstprechende 
Anzahl Takte länger machst.

Fertig ist die genau gehende Uhr.

von Humphrey (Gast)


Lesenswert?

Karl Heinz Buchegger schrieb:
> OCR Register auf 52428

Öhm, muss ehrlich sagen, dass ich auch die Zahl auch gekommen bin. 
Dachte aber das liegt ausserhalb des Wertebereichs vom 16-Bit Timer 
(warum auch immer). Und dann hatte ich bereits keine Lust mehr mir über 
Prescaler Gedanken zu machen :P

Hattest natürlich recht, sorry.

Auf alle Fälle läuft das ganze jetzt (sieht soweit gut aus) aber muss 
ich nicht noch von den 52'428 eins abzählen?

Gruss
Humphrey

von Humphrey (Gast)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Danach lässt du deine Uhr (wie im Link beschrieben) ein paar Tage
> laufen, stellst die Abweichung fest und rechnest dir die tatsächliche
> QUarzfrequenz aus.

Ja, das mache ich dann noch. Dauertest ist sowieso noch vorgesehen :)

Gruss
Humphrey

von Karl H. (kbuchegg)


Lesenswert?

Humphrey schrieb:
> Karl Heinz Buchegger schrieb:
>> OCR Register auf 52428
>
> Öhm, muss ehrlich sagen, dass ich auch die Zahl auch gekommen bin.
> Dachte aber das liegt ausserhalb des Wertebereichs vom 16-Bit Timer
> (warum auch immer). Und dann hatte ich bereits keine Lust mehr mir über
> Prescaler Gedanken zu machen :P
>
> Hattest natürlich recht, sorry.
>
> Auf alle Fälle läuft das ganze jetzt (sieht soweit gut aus) aber muss
> ich nicht noch von den 52'428 eins abzählen?

kannst du machen.
Der genaue Wert wäre ja 52427.8, was aber aus naheliegenden Gründen 
nicht geht :-)

Aber es sagt ja keiner, dass alle CTC Zyklen gleich lang sein müssen. 
Kennt man erst mal die genaue Quarzfrequenz, kann man ja in der ISR 
EINEN Zyklus einlegen, in dem man mal mit einem etwas größeren/kleinern 
OCR1A Wert operiert.

ISR( ... )
{
   cnt++;

   if( cnt == 10 )
   {
     ...
     OCR1A = ....;    // ein Zyklus ein bischen anders um die über
                      // 9 Zklen akkumulierten Fehler auszugleichen

   }
   else
     OCR1A = 52428;
}


Wie gesagt. Auch dieser QUarz macht keine exakten 5242880 Schwingungen

von Humphrey (Gast)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Aber es sagt ja keiner, dass alle CTC Zyklen gleich lang sein müssen.
> Kennt man erst mal die genaue Quarzfrequenz, kann man ja in der ISR
> EINEN Zyklus einlegen, in dem man mal mit einem etwas größeren/kleinern
> OCR1A Wert operiert.

Ja, das wäre natürlich auch noch 'ne Option.
Auf alle Fälle vielen Dank für deine Hilfe, hätte nicht gedacht, dass es 
so schnell geht :D

Mache noch einen Dauertest so 2, 3 Wochen und dann stell ich das noch 
um. Sollte dann genügend genau sein. Wenn ich die Uhr von meinem HTC 
Handy Anschaue, ist die um weiten ungenauer :P

Einen schönen Tag, wünsche ich noch.

Gruss
Humphrey

von Humphrey (Gast)


Lesenswert?

Und einfach noch für die Nachwelt, falls das mal irgendwer braucht:
1
int main ()
2
3
{
4
    TIMSK = (1<<OCIE1A); // den Output Compare Interrupt des Timers freigeben
5
    sei();               // Globale Interrupts erlauben
6
    TCCR1B = (1<<WGM12) | (1<<CS10);    // Vorteiler 1, CTC Modus
7
    OCR1A  = 52428; //Zählen bis 52428
8
 
9
    while (1)
10
11
    {
12
13
     //Programm hier
14
15
    }
16
17
}
18
19
ISR (TIMER1_COMPA_vect)
20
{
21
22
  //Interrupt Routine hier
23
24
}

Gruss
Humphrey

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.