40.8.2.4. Čítače/časovače

V této sekci shromažďuji informace a podklady pro článek o použití časovačů k přerušení a měření času.

Z projektu "clock" DCF77.

// SETUP
        //Timer2 Settings: Timer Prescaler /64.
        TCCR2B |= (1<<CSS22);    // turn on CSS22 bit
        TCCR2B &= ~((1<<CS21) | (1<<CS20)); // turn off CS21 and CS20 bits
        // Use normal mode
        TCCR2A &= ~((1<<WMG21) | (1<<WMG20));   // turn off WMG21 and WMG20 bits
        TCCR2B &= ~(1<<WMG22);          // turn off WMG22
        // Use internal clock - external clock not used in Arduino
        ASSR |= (0<<AS2);
        TIMSK2 |= (1<<TOIE2) | (0<<OCIE2A);   // Timer2 Overflow Interrupt Enable

        RESET_TIMER2;

        attachInterrupt(0, int0handler, CHANGE);

Kód obsluhy přerušení od přetečeného časovače TIMER2

/**
 * The interrupt routine for counting seconds - increment hh:mm:ss.
 */
ISR(TIMER2_OVF_vect) {
    RESET_TIMER2;
    tick_counter += 1;
    if (tick_counter == 1000) {
        ss++;
        if (ss==60) {
            ss=0;
            mm++;
            if (mm==60) {
                mm=0;
                hh++;
                if (hh=24) {
                    hh=0;
                }
            }
        }
        tick_counter = 0;
    }
}

Chceme-li generovat přerušení v pravidelných intervalech a toto přerušení obsluhovat vlastním kódem, můžeme vyjít z následující ukázky.

Ukázka je ve stádiu psaní a ladění!

void setup() {
    …
    /*
     * Setup Timer2 to interrupt mode with no PWM.
     */
    noInterrupts();
    // Use internal clock from clkI/O. Must be set before TCNT2,
    // OCR2A, OCR2B, TCCR2A and TCCR2B, because of possible
    // corruption of these!  Better to write in sequence and not
    // in one command because of datasheet!
    ASSR &= ~(1<<EXCLK);    // EXCLK=0
    ASSR &= ~(1<<AS2);      // AS2=0
    // Clock Select = clkT2S/1024 (From prescaler) [CS2 2:1:0 = 111]
    TCCR2B |= 0b00000111;   // clkT2S is 16MHz/1024 = 15625Hz
    // Waveform Generation = CTC [WGM2 2:1:0 = 010]
    TCCR2A &= 0b11111010; TCCR2A |= 0b00000010
    TCCR2B &= 0b11110111;
    // Compare Match Output A and B Mode = Normal  [COM2A1:0 COM2B1:0 = 0000]
    TCCR2A &= 0b00001111;
    // Set TOP
    OCR2A = 38;	// TOP value for mode CTC. Should generate 400Hz
    // Allow interrupt only from Timer2 Compare A Match.  Overflow
    // does not work as I expected initially.
    // OCIE2B=0, OCIE2A=1, TOIE2=0
    TIMSK2 = 0b00000010;
    // Clear the Timer/Counter2 Interrupt Flags
    TIFR2 = 0b00000000;
    interrupts();
    …
}

Obsluha přerušení

ISR(TIMER2_COMPA_vect, ISR_NOBLOCK) {
    … udělej co musíš ale snaž se co nejrychleji
}
Licence Creative Commons
Elektronika a počítače, jejímž autorem je Radek Hnilica, podléhá licenci Creative Commons Uveďte autora-Nevyužívejte dílo komerčně-Zachovejte licenci 3.0 Česká republika .