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 }