2013-04-17 10 views
5

Ich möchte mehr über Arduino Nano Timer wissen.Arduino Nano Timer

  1. Welche Timer gibt es?
  2. Produzieren sie Interrupts?
  3. Welcher Code würde ihnen einen Interrupt-Handler beifügen?
  4. Wie wird delay() und delayMicroseconds() implementiert ...
    • Haben sie Timer-Interrupts verwenden? (Wenn ja, wie kann ich während dieses Vorgangs anderen Code ausführen lassen?)
    • Oder werden sie wiederholt abgefragt, bis ein Timer einen bestimmten Wert erreicht?
    • Oder erhöhen sie einen Wert X mehrmals?
    • Oder machen sie es anders?

Antwort

17

Der beste Weg, um das Arduino Nano-Timer zu denken, ist über die Zeitgeber in dem zugrundeliegenden Chip zu denken: die ATmega328. Es verfügt über drei Timer:

  • Timer 0: 8-Bit-PWM-on-Chip-Pins 11 und 12
  • Timer 1: 16-Bit-PWM-auf-Chip-Pins 15 und 16
  • Timer 2: 8- bit, PWM auf Chip-Pins 17 und 5

Alle diese Timer können zwei Arten von Interrupts erzeugen:

  • der "Wert matched" Interrupt auftritt, wenn der Zeitgeberwert, der hinzugefügt wird, Jeder Tick des Timers erreicht einen Vergleichswert im Timer-Register.
  • Der Timer-Interrupt-Überlauf tritt auf, wenn der Timerwert seinen Maximalwert erreicht

Leider gibt es keine Arduino Funktion Interrupts Timer zu befestigen. Um Timer-Interrupts zu verwenden, müssen Sie etwas mehr Low-Level-Code schreiben. Grundsätzlich müssen Sie ein interrupt routine so etwas erklären:

ISR(TIMER1_OVF_vect) { 
    ... 
} 

Dies wird deklariert eine Funktion timer1 Überlauf Unterbrechung zu bedienen. Dann müssen Sie aktivieren die Zeitüberlauf-Interrupt unter Verwendung der TIMSK1 registrieren. Im obigen Beispiel Fall könnte dies wie folgt aussehen:

TIMSK1 |= (1<<TOIE1); 

oder

TIMSK1 |= BV(TOIE1); 

Dies setzt die TOIE1 (erzeugen timer1 Überlauf-Interrupt, bitte) Flag im TIMSK1 Register. Wenn Ihre Interrupts aktiviert sind, wird Ihr ISR(TIMER1_OVF_vect) jedes Mal aufgerufen, wenn timer1 überläuft.


Die Arduino delay() Funktion sieht wie im Quellcode folgt (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; 
     } 
    } 
} 

So intern verwendet es die micros()-Funktion, die in der Tat auf der Timer0 Zählung beruht. Das Arduino-Framework verwendet timer0, um Millisekunden zu zählen. In der Tat ist timer0 count is, wobei die Funktion millis() ihren Wert erhält.

Die Funktion delayMicroseconds() hingegen verwendet bestimmte zeitgesteuerte Mikroprozessoroperationen, um die Verzögerung zu erzeugen; Welche Funktion verwendet wird, hängt vom Prozessor und der Taktgeschwindigkeit ab; am häufigsten ist nop() (keine Operation), die genau einen Taktzyklus dauert. Arduino Nano verwendet einen 16  -MHz-Takt, und hier ist es, was der Quellcode wie für das aussieht:

// 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; 

Was lernen wir daraus:

  • 1 & mgr; s Verzögerung hat nichts (der Funktionsaufruf ist die Verzögerung)
  • Bei längeren Verzögerungen wird die Verzögerung mit der linken Verschiebeoperation zeitgesteuert.
+0

Danke! Freut mich, dass Sie es nützlich fanden. – angelatlarge