2013-04-17 49 views
5

Chcę wiedzieć więcej na temat timerów Arduino Nano.Arduino Nano Timery

  1. Jakie są zegary?
  2. Czy produkują przerywniki?
  3. Jaki kod dołączałby do nich obsługę przerwań?
  4. Jak delay() i delayMicroseconds() realizowane ...
    • Czy oni używać timera przerwań? (Jeśli tak, jak mogę w tym czasie wykonać inny kod?)
    • Czy też powtarzają sondowanie, dopóki licznik nie osiągnie określonej wartości?
    • A może zwiększają one wartość X razy?
    • Czy robią to w inny sposób?

Odpowiedz

17

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.
+0

Dzięki! Cieszę się, że okazało się to przydatne. – angelatlarge