Forum: Mikrocontroller und Digitale Elektronik ATmega168 Timer Compare Interrupt Zeitzählung


von tom (Gast)


Lesenswert?

Hallo.

Ich bin zurzeit dabei mich in die AVR Welt einzuarbeiten. Dabei bin ich 
auf den Artikel 
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial/Die_Timer_und_Z%C3%A4hler_des_AVR 
gestoßen. Ich habe das ganze für de n ATMega168 angepasst aud gebe die 
entsprechenden Werte (ms, s, m und h) auf einem 20x4 Display aus. Es 
sieht subjektiv betrachtet soweit ok aus. Trotzdem hänge ich an einem 
Gedanken/Problem fest. Bei mir ist auf dem Board ein 16MHz Quarz drauf. 
Über den Prescaler von 64 bekommt der Timer 250.000 mal pro Sekunde 
einen Impuls. Daher soll nach 250 Impulsen ein Compare Interrupt 
ausgelöst werden (Zeile: OCR0A = 250;). D.h. jede ms gibts einen Compare 
Int und ein entsprechender Counter kann incrementiert werden. Bedeutet 
das jetzt, dass der Timer beim 250 Impuls einen Int auslöst, der 
MilliSek-Counter wird erhöht, dann Zählt der Timer weiter bis 255 und 
dann fängt er wieder bei 0 an, zählt wieder bis 255 und löst vorher bei 
250 wieder einen Compare Int aus. Das würde ja bedeuten, dass sich ein 
Fehler von 5 Timer-Taken einschleicht, oder? Müsste nicht beim Auslösen 
den Compare Int das Zählregister des Timers auf 0 zurück gesetzt werden?

Ich hatte das testweise mal mit einem Prescaler von 256 probiert und 
OCR0A = 63. Sah rein subjektiv genauso gut aus(Counter für Sek wurde im 
Display etwa im SekundenTakt aktualisiert), obwohl hier der Fehler viel 
größer sein müsste, wenn der Timer bis 255 wiederzählt und dann bei 0 
beginnt und wieder bei 63 einen Comp Int auslöst. Hab ich da irgendetwas 
übersehen?

Auszug auf meinem Code:
1
// Timer-Compare Test-Funktion
2
void start_timer_compare()
3
{
4
    char Buffer[20];
5
6
    /*   Timer0 ( 8 bit ) konfigurieren */
7
    TCCR0A |= (1<<WGM01);
8
    TCCR0B |= ((1<<CS01)|(1<<CS00));
9
    // 1; Timer0 Vorteiler: 64 -> bei 16 MHz: 
10
    // 16.000.000 / 64 = 250000 Mal pro Sek gibts einen Takt an den Timer
11
    
12
    OCR0A = 250;
13
    // Timer0 soll bei 250 einen Output Compare Interrupt auslösen ->
14
    // 250.000 / 250 = 1000 mal pro Sek gibts einen Interrupt
15
16
    //Compare Interrupt aktivieren
17
    TIMSK0 |= (1<<OCIE0A);
18
19
    //Globale Interrupts aktivieren
20
    sei();
21
22
    while(1)
23
    {
24
        // DisplayAsgabe
25
        // eine virtel Sekunde warten bis zur nächsten Anzeige
26
        _delay_ms( 250 );
27
    }
28
  
29
    return;
30
}
31
32
// Der Compare Interrupt Handler
33
// Wird aufgerufen wenn OCR0B = 250
34
ISR (TIMER0_COMPA_vect)
35
{
36
    millisekunden++;
37
38
    if( millisekunden == 1000 )
39
    {
40
        sekunde++;
41
        millisekunden = 0;
42
43
        if(sekunde == 60)
44
        {
45
            minute++;
46
            sekunde = 0;
47
        }
48
49
        if(minute == 60)
50
        {
51
            stunde++;
52
            minute = 0;
53
        }
54
    }
55
}

von Captain S. (captainsubtext)


Lesenswert?

Schön, dass Du alleine schon so weit gekommen bist und Dir auch über 
dieses kleine Detail Gedanken gemacht hast!

Zur Frage:
Der Timer läuft durch deine Initialisierung im CTC-Modus (Clear Timer on 
Compare Match  Modus).
Dort wird der Timer mit dem Auslösen des Interrupts zurückgesetzt.

Näheres erfährst Du im Datenblatt* des AtMega168, Seite 94, Abschnitt 
14.7.2!
Darauf hättest Du aber auch selbst kommen können ;)

*http://www.atmel.com/dyn/resources/prod_documents/doc2545.pdf

von Tom M. (tomm) Benutzerseite


Lesenswert?

tom schrieb:
> Das würde ja bedeuten, dass sich ein
> Fehler von 5 Timer-Taken einschleicht, oder? Müsste nicht beim Auslösen
> den Compare Int das Zählregister des Timers auf 0 zurück gesetzt werden?

Ja, das geschieht automagisch, weil du den CTC Modus konfiguriert hast:
>     TCCR0A |= (1<<WGM01);

Schau mal ins Datenblatt zum atmega48/88/168/328, da steht nämlich:

12.7.2 Clear Timer on Compare Match (CTC) Mode
In Clear Timer on Compare or CTC mode (WGM02:0 = 2), the OCR0A Register 
is used to manipulate the counter resolution. In CTC mode the counter is 
cleared to zero when the counter value (TCNT0) matches the OCR0A. The 
OCR0A defines the top value for the counter, hence also its resolution.


Gute n8 :)

von tom (Gast)


Lesenswert?

Hallo und vielen Dank.

Ich habs wirklich übersehen. Diese Sucherei im Datenblatt, was ich 
wirklich die ganze Zeit offen gehabt hab, hat mich ganz wuschig gemacht. 
Ich muss mich erst an die vielen Registernamen gewöhnen, dann verliere 
ich wohl auch nicht mehr den Blick für wesentliche.

Frohe Wihnachten

Gruß Tom

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.