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
}