ATMega328P (najczęściej używana w Arduino) posiada 3 osobne timery. Timer0 i Timer2 mają rejestry 8-bit a w Timer1 rejestr odliczający ma 16 bitów. Zaznaczyć trzeba, że Arduino używa timerów do niektórych funkcji, stąd manipulacje przy nich mogą wpłynąć na efekty działania kodu Arduino bądź uzycie niektórych funkcji Arduino może wpłynąć na działanie timerów. Poniższa tabela obrazuje podstawowe konfilkty jakie moga się wydarzyć:
| Timer | Piny PWM | funkcje |
|---|---|---|
| 0 | 5,6 | delay,millis,micros |
| 1 | 9,10 | servo |
| 2 | 11,3 | tone |
Standardowo timery przyjmują zegar mikrokontrolera jako źródło swojego tatktowania. Niestety przy rejestrze mającym 8 albo 16 bitów i tatktowaniu rzędu 16MHz odmiarzane okresy będą dosyć krótkie stąd przydatnym może być użycie prescalerów. Prescalery dzielą ilość ilość taktów zegara przez podany wskaźnik i są to 1:1, 1:8, 1:64, 1:256 i 1:1024. Wartości prescalerów ustala się w rejestrze TCCRxB (gdzie x to numer timera).
| CSx2 | CSx1 | CSx0 | dzielnik |
|---|---|---|---|
| 0 | 0 | 0 | pauza |
| 0 | 0 | 1 | 1 |
| 0 | 1 | 0 | 8 |
| 0 | 1 | 1 | 64 |
| 1 | 0 | 0 | 256 |
| 1 | 0 | 1 | 1024 |
| 1 | 1 | 0 | T1 fall |
| 1 | 1 | 1 | T1 rise |
Prescaler 1024 dla Timer1 możemy ustawić na kilka sposobów np.:
TCCR1B |= B00000101;
TCCR1B |= (1 << CS12) | (1 << CS10);
Rejestr TCNTx zawiera wartość od której licznik zaczyna liczyć, przed uruchomieniem timera warto go ustawić na 0 jeśli z premedytacją nie chcemy innej wartości.
TCNT1 = 0;
Timer może generować dwa rodzaje przerwań - Compare Match i Overflow. Przerwanie Overflow jest generowane jeśli licznik osiągnie maksymalną wartość czyli w przypadku Timer0 i Timer2 jest to 255 a Timer1 to 6553.
Włączenie przerwania Compare Match odbywa się poprzez ustawienie bitu 1 albo bitu 2 w rejestrze TIMSKx, gdzie ustawiony bit 1 (oznaczenie OCIExA) powoduje porównywanie danych z rejestru OCRxA z wartością licznika timera a bit 2 (oznaczenie OCIExB) z rejestrem OCRxB.
Ustawienie przerwanie Compare Match dla Timer1 z rejestrem OCR1A wygląda następująco (ustawienie bitu 1 (oznaczonego jako OCIE1A):
TIMSK1 |= B00000010;
Włączenie porównywania wartości dla obu rejestrów OCR1(A/B) i generowanie przerwań możemy uruchomić w następujący sposób:
TIMSK1 |= (1 << OCIE1A) | (1 << OCIE1B);
Zaznaczyć trzeba, że górną wartością zegara staje się wtedy wartość z rejestru OCIE1A.
Możemy równocześnie korzystać z przerwań dla porównywania licznika timer a rejestrami OCRxA i OCRxB, dysponujemy zatem w sumie sześcioma przerwaniami dla zdarzeń typu Compare Match:
Skorzysać możemy ze wzoru (częstotliwość kwarcu/(prescaler * oczekiwana częstotliwość))-1. Trzeba pamiętać, że przy OCR1(A/B) możemy korzystać z wartości 0 - 65536 a w przypadku OCR0(A/B) i OCR2(A/B) ograniczeniem jest zakres 0 - 255.