Контейнерная программа Arduino Timer0
Как описано здесь https://learn.adafruit.com/multi-tasking-the-arduino-part- 2/таймеры
Я использую таймер 0, чтобы получить собственный таймер с разрешением в миллисекундах.
Он настроен следующим образом:
void setup (void)
{
...
cli();
OCR0A = 0xAB;
TIMSK0 |= (1 << OCIE0A);
sei();
...
}
Значение 0xAB выбирается случайно и не должно влиять на поведение.
Обработчик прерывания выглядит следующим образом:
ISR(TIMER0_COMPA_vect)
{
if (myTimer != 0)
myTimer--;
return;
}
Это работает просто нормально, но при более внимательном рассмотрении фактических значений времени с помощью millis() я обнаружил, что значения таймера, заданные этим ISR, примерно на 2-3% больше, чем нужно.
Согласно сайту adafruit.com, этот метод должен точно следовать встроенному в Arduino таймеру millis(). В моей программе нет других активных прерываний. Есть некоторые выходные данные Serial.print(), может быть, они влияют на время? Решение, которое я нашел, выглядит так:
ISR(TIMER0_COMPA_vect)
{
static unsigned long timeLast;
unsigned long timeNow = millis();
uint8_t timeDiff = (uint8_t)(timeNow - timeLast);
timeLast = timeNow;
if (myTimer != 0)
myTimer -= timeDiff;
return;
}
Вместо простого уменьшения значения таймера значение таймера уменьшается на фактическое время, прошедшее с момента последнего вызова ISR.
При этом мой таймер точно следует за миллисом(). Но почему первый подход не дает точного времени? По-видимому, бывают случаи, когда время между вызовами ISR составляет не 1 мс, а 2 мс.
@Sören, 👍1
Обсуждение1 ответ
Ядро Arduino настраивает таймер 0 на период 1024 мкс. Твой Затем ISR будет вызываться через очень регулярные промежутки времени, и это хорошее место. иметь код, связанный с синхронизацией. Просто нужно помнить, что устройство времени составляет не одну миллисекунду, а 1,024 мс.
Если вас беспокоит этот «странный» модуль, вы можете сделать следующее: Ардуино ISR по времени: отслеживает задержку относительно 1 мс период, вы получаете. Когда вы заметите, что опаздываете на 1 мс, посчитайте одна дополнительная миллисекунда.
- Использование millis() и micros() внутри процедуры прерывания
- Кнопка с таймером переключения и функцией сброса времени + светодиод обратной связи
- Использовать timer0, не влияя на millis() и micros().
- Влияет ли `millis()` на длинные ISR?
- Сброс Arduino с помощью ПО (каждый день)
- Как отслеживать миллисекунды в спящем режиме
- Отрегулируйте расчет времени после изменения частоты Timer0
- Как выйти из прерывания таймера (ISR(TIMER1_COMPA_vect))
Означает ли это, что millis() уже возвращает исправленное значение, т.е. millis() дает фактическое количество миллисекунд, а не 1,024 мс?, @Sören