Лучший способ думать о таймерах 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 задержка мкс не делает ничего (вызов функции является задержка)
- Более длительные задержки используют операцию сдвига влево для временной задержки.
Спасибо! Рад, что вы нашли его полезным. – angelatlarge