Сбой прерывания таймера инициализации Mega 2560
Ниже приведен весь мой прототипный код, циклический вывод 13 - это то, что я использую для подтверждения перезагрузки платы. Плата постоянно сбрасывается при этой реализации инициализации прерывания. Для прерывания не реализован код, достаточно просто инициализировать прерывание и специально включить прерывание сравнения вывода, установив его высокий бит, чтобы вызвать сбой. Свидетельством аварии является включение встроенного светодиода в соответствии с инструкциями процедуры setup()
.
Я пробовал устанавливать OCR3A
в одной и двух операциях, я пробовал инициализировать TIMSK3
и нет, я пробовал инициализировать TCNT3
до нулевых и ненулевых значений и устанавливать прескалер со сдвигом битов и дискретным значением, кажется, ничего не работает.
Что происходит?
void FlashLED() {
digitalWrite(13, !digitalRead(13));
delay(100);
digitalWrite(13, !digitalRead(13));
delay(100);
digitalWrite(13, !digitalRead(13));
delay(100);
digitalWrite(13, !digitalRead(13));
delay(100);
}
void setup() {
// поместите свой установочный код здесь, чтобы запустить один раз:
pinMode(13, OUTPUT);
FlashLED();
// Инициализация таймера 3 и прерывание
noInterrupts();
TCCR3A = 0;
TCCR3B = 0;
TIMSK3 = 0;
TCNT3 = 0;
// Инициализировать OCR3A в двух операциях, так как OCR3A = 62500; Serial.print(OCR3A); дает 36 (только младший байт)
unsigned int count = 62500;
OCR3AH = count >> 8;
OCR3AL = count;
TCCR3B |= 1 << WGM32; // Режим CTC
//TCR3B |= 4; // Прескалер 256
TCCR3B |= 1 << CS32; // Прескалер 256
TIMSK3 |= 1 << OCIE3A; // Output Compare Interrupt Enable
interrupts();
}
void loop() {
// поместите свой основной код здесь, чтобы запускать его повторно:
}
Обновление:
Я также пытался использовать пустой обработчик ISR и обесценил его эффект:
ISR(Timer3_COMPA_vect) {
}
Однако, как заметил бы проницательный зритель, подпись неверна в своей капитализации. Правильный обработчик - это
ISR(TIMER3_COMPA_vect) {
}
Это решило проблему.
@J Collins, 👍0
Обсуждение1 ответ
Лучший ответ:
Вы включили таймер, а также его прерывания, но у вас нет обработчика прерываний. Прерывание должно куда-то идти, и как бы то ни было, оно идет неизвестно куда. Добавьте ISR, и я верю, что это решит вашу проблему.
Да, капитализация важна!
- Использование millis() и micros() внутри процедуры прерывания
- Arduino непрерывно считывает значение АЦП с помощью прерывания
- Использование TIMER0_COMPB_vect
- 4-битный счетчик вверх и вниз
- Включить и отключить отдельные прерывания
- ATtiny85 AC Phase Control для регулировки яркости лампочки
- Присоедините функцию Arduino ISR к члену класса
- Быстрее TimerOne с Teensy 4.0 (600 МГц)
Вы включили таймер, а также его прерывания, но у вас нет обработчика прерываний. Прерывание должно куда-то идти, и как бы то ни было, оно идет неизвестно куда. Добавьте ISR, и я верю, что это решит вашу проблему., @jwh20
Как это раздражает. Я уже несколько часов работаю с пустым обработчиком ISR, вся проблема в неправильной капитализации!! Учебник Оскара Ляна обычно смешивает случай ISR, поэтому мне никогда не приходило в голову изменить его: https://oscarliang.com/arduino-timer-and-interrupt-tutorial / Не стесняйтесь отправить ответ, который я приму, так как ваша подсказка привела меня домой., @J Collins
Рад быть вам полезным., @jwh20
Несвязанный; Вы должны иметь возможность использовать
OCR3A = count
, чтобы установить как регистр H, так и регистр L только с одной строкой кода., @GerbenЭто то, что я делал изначально, но использовал Serial.print(OCR3A); вернул 36, указывая, что записывается только младший байт. Я не знаю, как мой код может вести себя иначе, чем чей-либо еще., @J Collins