2013-04-17 41 views
5

Voglio saperne di più sui timer Arduino Nano.Arduino Nano Timer

  1. Quali timer ci sono?
  2. Producono interrupt?
  3. Quale codice dovrebbe essere collegato a un gestore di interrupt?
  4. Come si delay() e delayMicroseconds() implementato ...
    • Usano gli interrupt timer? (In tal caso, come posso eseguire un altro codice durante questo?)
    • Oppure eseguono ripetutamente il polling fino a quando un timer raggiunge un determinato valore?
    • Oppure aumentano un valore X numero di volte?
    • Oppure lo fanno in un altro modo?

risposta

17

Il modo migliore per pensare i timer Arduino Nano è pensare temporizzatori chip sottostante: la ATmega328. Ha tre timer:

  • Timer 0: 8-bit, PWM sui piedini del circuito integrato 11 e 12
  • Timer 1: 16 bit, PWM sui piedini del circuito integrato 15 e 16
  • Timer 2: 8- bit, PWM sui piedini del circuito integrato 17 e 5

Tutti questi temporizzatori possono produrre due tipi di interrupt:

  • il "valore corrispondente" si verifica interrupt quando il valore del timer, che viene aggiunto ogni segno del timer raggiunge un valore di confronto nel registro del timer.
  • Il timer di overflow interrupt si verifica quando il valore del temporizzatore raggiunge il valore massimo

Purtroppo, non v'è alcuna funzione Arduino allegare interrupt timer. Per utilizzare gli interrupt del timer è necessario scrivere un po 'più di codice di basso livello. In sostanza, è necessario dichiarare un interrupt routine qualcosa di simile:

ISR(TIMER1_OVF_vect) { 
    ... 
} 

Ciò dichiarare una funzione al servizio timer1 interrupt di overflow. Quindi è necessario abilitare l'interrupt di overflow del timer utilizzando il registro TIMSK1. Nel caso ad esempio di sopra di questo potrebbe essere simile a questo:

TIMSK1 |= (1<<TOIE1); 

o

TIMSK1 |= BV(TOIE1); 

Imposta la (generare timer1 interrupt di overflow, per favore) la bandiera TOIE1 nel registro delle TIMSK1. Supponendo che gli interrupt siano attivati, il tuo ISR(TIMER1_OVF_vect) verrà chiamato ogni volta che il timer1 trabocca.


La funzione Arduino delay() appare come segue nel codice sorgente (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; 
     } 
    } 
} 

Quindi internamente utilizza la funzione micros(), che si basa infatti sul conteggio Timer0. Il framework Arduino utilizza timer0 per contare i millisecondi, infatti, il conteggio timer0 è dove la funzione millis() ottiene il suo valore.

La funzione delayMicroseconds(), d'altra parte, utilizza determinate operazioni di microprocessore ben programmate per creare il ritardo; quale funzione viene utilizzata dipende dal processore e dalla velocità di clock; il più comune è nop() (nessuna operazione) che richiede esattamente un ciclo di clock. Arduino Nano utilizza un orologio a 16   MHz, ed ecco quello che il codice sorgente assomiglia per questo:

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

Ciò che apprendiamo da questo:

  • 1 ms ritardo non fa nulla (la chiamata di funzione è la ritardo)
  • I ritardi più lunghi utilizzano l'operazione di spostamento a sinistra per impostare il ritardo.
+0

Grazie! Sono contento che tu abbia trovato utile. – angelatlarge