2013-04-17 4 views
5

Я хочу знать больше о Arduino Nano таймеры.Arduino Nano Таймеры

  1. Какие существуют таймеры?
  2. Производят ли прерывания?
  3. Какой код будет прикреплять к ним обработчик прерываний?
  4. Как delay() и delayMicroseconds() реализованы ... они используют таймер прерываний
    • ли? (Если да, то как я могу выполнить другой код во время этого?)
    • Или они периодически опроса, пока таймер не достигнет определенного значения?
    • Или они увеличивают значение X раз?
    • Или они делают это по-другому?

ответ

17

Лучший способ думать о таймерах Arduino Nano, чтобы думать о таймерах в базовой микросхеме: на ATmega328. Она состоит из трех таймеров:

  • Таймер 0: 8-разрядный ШИМ на штифтах чипа 11 и 12
  • Таймер 1: 16 бит, ШИМ на контакты чипа 15 и 16
  • Timer 2: 8- бит, ШИМ на чипе штифтами 17 и 5

Все эти таймеры могут производить два вида прерываний:

  • «стоимость соответствует» происходит прерывание, когда значение таймера, который добавляется к каждый тик таймера достигает значения сравнения в регистре таймера.
  • прерывания переполнения
  • Таймера происходит, когда значение таймера достигает своего максимального значение

К сожалению, нет Arduino функции пристроить прерывания таймеров. Чтобы использовать таймерные прерывания, вам нужно будет написать немного более низкоуровневый код. В принципе, вам нужно будет объявить interrupt routine что-то вроде этого:

ISR(TIMER1_OVF_vect) { 
    ... 
} 

Это объявит функцию для обслуживания TIMER1 прерывания переполнения. Затем вам нужно будет включить прерывание переполнения таймера с помощью регистра TIMSK1. В приведенном выше примере случае это может выглядеть следующим образом:

TIMSK1 |= (1<<TOIE1); 

или

TIMSK1 |= BV(TOIE1); 

Это устанавливает (генерировать timer1 прерывание переполнения, пожалуйста) флаг TOIE1 в регистре TIMSK1. Предполагая, что ваши прерывания включены, ваш ISR(TIMER1_OVF_vect) будет вызываться каждый раз, когда таймер 1 переполняется.


Функция Arduino delay() выглядит следующим образом в исходном коде (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; 
     } 
    } 
} 

Так внутренне он использует функцию micros(), которая действительно полагается на счет TIMER0. Рамка Arduino использует timer0 для подсчета миллисекунд, действительно, значение timer0 имеет значение millis().

С другой стороны, функция delayMicroseconds() использует определенные своевременные операции микропроцессора для создания задержки; используемая функция зависит от процессора и тактовой частоты; наиболее распространенным является nop() (без операции), который занимает ровно один такт. Arduino Nano использует часы с 16   МГц, а вот то, что исходный код выглядит для этого:

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

Что мы узнаем из этого:

  • 1 задержка мкс не делает ничего (вызов функции является задержка)
  • Более длительные задержки используют операцию сдвига влево для временной задержки.
+0

Спасибо! Рад, что вы нашли его полезным. – angelatlarge

Смежные вопросы