Arduino Mega — включение режима CTC отключает таймер
Я пытаюсь использовать timer3 на Arduino Mega 2560 в режиме CTC. Однако включение CTC полностью отключает код.
Вот функция, которую я вызываю в setup() для установки времени.
void SetupInterrerupt() {
cli(); // Запретить прерывания
// Настройка таймера
TCCR3A = 0; // устанавливаем весь регистр TCCR3A в 0
TCCR3B = 0; // то же самое для TCCR3B
// Настройка регистра сравнения совпадений
OCR3B = CMP_FAST; // CMP_FAST = 40
// включаем режим CTC:
TCCR3B |= (1 << WGM32); // Закомментировав эту строку, код заработает
// Устанавливаем биты CS10 и CS12 для прескалера 1024:
TCCR3B |= (1 << CS30) | (1 << CS32);
// включаем прерывание сравнения таймера:
TIMSK3 |= (1 << OCIE3B);
sei(); // Разрешаем прерывания
Serial.println("Timers enabled");
}
И вектор прерывания.
// Прерывание таймера 3
ISR(TIMER3_COMPB_vect){//timer1 прерывание 1 Гц переключает контакт 13 (светодиод)
// делаем что-то...
}
Как есть, прерывание вообще не выполняется. Как отмечено в коде, закомментирование «TCCR3B |= (1 << WGM32);» фактически выполняет прерывание, за исключением того, что частота больше похожа на 1 Гц вместо 720.
Я использую библиотеку Arduino-lmic, а также некоторые другие библиотеки структур данных. Я не думаю, что они используют какие-либо таймеры, но, поскольку lmic разработан для Uno, я решил, что использование таймеров 3 и выше будет вполне приемлемым.
К сожалению, мои таймеры немного подзабыли. Кто-нибудь сможет заметить мою ошибку?
Спасибо.
@Jordan Sim, 👍0
1 ответ
Я думаю, ваша проблема в том, что вы используете неправильный регистр значения счетчика «TOP».
OCR3B = CMP_FAST; // CMP_FAST = 40
должно быть:
OCR3A = CMP_FAST; // CMP_FAST = 40
Я не слишком знаком с работой AVR времен, но согласно таблице данных:
В режиме сброса таймера при сравнении или CTC (WGM22:0 = 2) регистр OCR2A используется для управления разрешением счетчика. В режиме CTC счетчик обнуляется, когда значение счетчика (TCNT2) соответствует OCR2A. OCR2A определяет верхнее значение счетчика, а значит, и его разрешение.
(Примечание: здесь упоминается только регистр таймера 2, но то же самое справедливо для всех таймеров одного класса, включая таймер 3).
Поскольку OCR3A равен нулю, совпадение никогда не происходит. А поскольку существует только один счетчик (TCNT3), который при совпадении сбрасывается в 0, для сравнения может быть только один регистр, и это регистр «А». Регистр «B» кажется избыточным в режиме CTC.
Возможно, вам также придется переключиться на вектор COMPA (я не уверен в этом, честно говоря)
- Проблема прерывания библиотеки MPU6050 Arduino Jeff Rowberg
- Точность синхронизации Arduino nano
- Мега: присоединение Interrupt на выводе 18/19/20/21 не работает
- Считать данные датчика повторно через указанное время?
- Обнаружение, когда прерывание таймера не выполняется
- Проблема с использованием Arduino Mega Timer2 с прерыванием PinChange
- DS3231 с Arduino Nano для точной синхронизации
- Arduino mega PinChangeInterrupt с 16 битным таймером
Спасибо за ответ! К сожалению, это, похоже, не сработало. Переключение с OCR3B на OCR3A не меняет поведение. Переключение на вектор COMPA приводит к постоянной перезагрузке Arduino (я подозреваю, что всякий раз, когда происходит прерывание). Включение TCCR3B |= (1 << WGM32); просто снова отключает таймер. Думаю, я также пробовал использовать таймеры 0-2, но безрезультатно., @Jordan Sim
Возможно, вам следует вместо этого переключиться на использование библиотеки, чтобы управлять ею за вас. Я уверен, что есть некоторые варианты библиотеки TimerOne для Таймера 3., @Majenko
Помимо изменения OCR3B на OCR3A, вам также необходимо изменить OCIE3B на OCIE3A и TIMER3_COMPB_vect на TIMER3_COMPA_vect., @Gerben