Najlepszym sposobem, aby myśleć o timerów Arduino Nano jest myśleć o timerów w chip podstawowych: w ATmega328. Posiada trzy czasy:
- zegara 0: 8-bitowy, PWM sworzni wiórowych 11 i 12
- timer 1: 16-bitowy, PWM sworzni wiórowych 15 i 16
- czasowego 2: 8- nieco PWM sworzni wiórowych 17 i 5
Wszystkie te liczniki może wytwarzać dwa rodzaje przerwań:
- „wartość dopasowane” przerwanie następuje przy wartości czasu, który dodaje się do każde tiknięcie zegara osiąga wartość porównawczą w rejestrze czasowym.
- Timer przerwanie przepełnienia występuje, gdy wartość timera osiągnie maksymalną wartość
Niestety, nie ma Arduino funkcja dołączyć do przerwania timerów. Aby korzystać z przerwań czasowych, musisz napisać nieco więcej kodu niskiego poziomu. Zasadniczo trzeba będzie zadeklarować interrupt routine coś takiego:
ISR(TIMER1_OVF_vect) {
...
}
To będzie zadeklarować funkcji do obsługi Timer1 przepełnienia przerwania. Następnie musisz włączyć przerywanie czasu timera za pomocą rejestru TIMSK1
. W powyższym przykładzie przypadku może to wyglądać tak:
TIMSK1 |= (1<<TOIE1);
lub
TIMSK1 |= BV(TOIE1);
Ustawia (Timer1 przepełnienia generowania przerwania, proszę) banderę TOIE1
w rejestrze TIMSK1. Zakładając, że twoje przerwań są włączone, twój ISR(TIMER1_OVF_vect)
będzie wywoływany za każdym razem, gdy przepełni się timer1.
Funkcja Arduino delay()
wygląda następująco w kodzie źródłowym (wiring.c
):
void delay(unsigned long ms)
{
uint16_t start = (uint16_t)micros();
while (ms > 0) {
if (((uint16_t)micros() - start) >= 1000) {
ms--;
start += 1000;
}
}
}
Więc wewnętrznie wykorzystuje funkcję micros()
, który rzeczywiście opiera się na liczbie TIMER0. Schemat Arduino wykorzystuje timer0 do zliczania milisekund, w rzeczy samej, licznik timer0 jest tam, gdzie funkcja millis()
otrzymuje swoją wartość.
Z drugiej strony, funkcja delayMicroseconds()
wykorzystuje określone operacje mikroprocesorowe w celu utworzenia opóźnienia; która funkcja jest używana, zależy od procesora i zegara; najczęściej jest to nop()
(brak operacji), który ma dokładnie jeden cykl zegara. Arduino Nano wykorzystuje zegar 16 MHz, a oto co kod źródłowy wygląda na to:
// For a one-microsecond delay, simply return. The overhead
// of the function call yields a delay of approximately 1 1/8 µs.
if (--us == 0)
return;
// The following loop takes a quarter of a microsecond (4 cycles)
// per iteration, so execute it four times for each microsecond of
// delay requested.
us <<= 2;
// Account for the time taken in the proceeding commands.
us -= 2;
Co możemy się z tego nauczyć:
- 1 ms opóźnienie ma nic (wywołanie funkcji jest opóźnienie)
- Dłuższe opóźnienia wykorzystują operację przesunięcia w lewo do czasu opóźnienia.
Dzięki! Cieszę się, że okazało się to przydatne. – angelatlarge