Как настроить векторный таймер прерываний сторожевого таймера на Arduino Redboard/Uno?
Я пытаюсь настроить прерывание сторожевого таймера для выполнения процедуры в ISR WDT_vec с некоторым повторяющимся интервалом. Я не хочу, чтобы процессор сбрасывался, а просто выполнял код в прерывании и возвращался к «нормальной» работе. У меня есть следующий тестовый шаблон, взятый из сети, который, как утверждается, устанавливает это:
#include <avr/wdt.h>
void setup_WDT() {
noInterrupts(); // отключить все прерывания
MCUSR = 0; // убедитесь, что векторы сброса выключены
/* Отключить и очистить все настройки Watchdog. */
_WD_CONTROL_REG = (1 << WDCE) | (1 << WDE);
_WD_CONTROL_REG = 0;
/* Установка сторожевого таймера для прерывания и отсутствия сброса, а также тайм-аута приблизительно 500 мс */
_WD_CONTROL_REG = (1 << WDIE) | (1 << WDP2) | (1 << WDP0);
interrupts(); // повторно включить прерывания
}
void setup() {
setup_WDT();
Serial.begin(9600);
Serial.println("Startup");
}
void loop() {
}
ISR(WDT_vec) {
Serial.println("Watchdog Interrupt");
}
Вывод показывает, что процессор просто сбрасывается многократно и никогда не достигает ISR. Также я получаю следующее предупреждение при компиляции из IDE (Arduino 1.8.2):
предупреждение: «WDT_vec» похоже на неправильно написанный обработчик сигнала, отсутствует __векторный префикс [-Wmisspelled-isr] ISR(WDT_vec) {
@Bitrex, 👍2
Обсуждение2 ответа
Лучший ответ:
Две ошибки:
- Вектор прерывания сторожевого таймера называется
WDT_vect
, а неWDT_vec
. - Оператор
_WD_CONTROL_REG = 0;
не служит никакой полезной цели, и скорее всего, нарушит временную последовательность смены сторожевого таймера Настройка. Просто удалите ее.
Эти изменения заставили всё работать!, @Bitrex
_WD_CONTROL_REG = 0; выполняет важную функцию. Если сторожевой таймер случайно включается, например, из-за неконтролируемого указателя или состояния отключения питания, устройство будет сброшено, а сторожевой таймер останется включенным. Если код не настроен на обработку сторожевого таймера, это может привести к вечному циклу сбросов по тайм-ауту. Чтобы избежать этой ситуации, прикладное программное обеспечение всегда должно очищать флаг сброса системы сторожевого таймера (WDRF) и бит управления WDE в инициализации рутина, даже если Watchdog не используется. Если вы используете его при разработке продукта, программа которого никогда не должна зависать, то об этом важно помнить.
это нехороший ответ. в Arduino загрузчик управляет микроконтроллером через несколько секунд после включения питания или сброса. правильные загрузчики AVR отключают сторожевой таймер. в setup() слишком поздно для большинства интервалов wdt, @Juraj
спасибо, @juraj, за твой добрый комментарий. СБРОС, который мы воспринимаем обычно, и сброс, который происходит после сброса WDT, отличаются. Жесткий сброс снова запускает загрузчик, но сброс WDT даже не переинициализирует ОЗУ, запуск загрузчика — это другая проблема. Читать статью: https://playground.arduino.cc/Main/ArduinoReset & Там написано, что: К сожалению, как только Arduino начнет выполнять скетч, по-видимому, нет возможности написать программную функцию, которая имела бы точно такой же эффект, как нажатие кнопки сброса. Я буду признателен и буду рад, если окажусь неправ и узнаю что-то новое :)., @bandejiya
сторожевой таймер сбрасывается до загрузчика, @Juraj
тогда как мы можем доказать, что сторожевой таймер сбрасывает загрузчик? пожалуйста, поделитесь кодом или чем-то подлинным..!, @bandejiya
есть проекты загрузчиков для прошивки через Ethernet. но для его активации необходимо удаленно сбросить плату в загрузчик. используется сброс watchdog.https://github.com/per1234/Ariadne-Bootloader/tree/master/libraries/EthernetReset, @Juraj
на форуме arduino.cc пользователь прошил Atmega с помощью esp8266 с прошивкой AT, подключенной к RX/TX. Из скетча он инициировал с помощью AT-команд подключение к серверу, а затем сделал сброс сторожевого таймера, и сервер выполнил последовательную прошивку через esp8266 в прозрачном режиме., @Juraj
случай из предыдущего комментария https://forum.arduino.cc/index.php?topic=519242.msg3545523#msg3545523, @Juraj
@juraj PFA ссылка на техническое описание Atmega328pu на странице № 77, я нашел свой ответ в виде примечания, которое вы назвали плохим ответом..! Я немного запутался, может быть, я неправильно воспринимаю техническое описание, пожалуйста, проясните этот факт. Заранее спасибо. http://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-42735-8-bit-AVR-Microcontroller-ATmega328-328P_Datasheet.pdf, @bandejiya
В Arduino очистка флага сторожевого таймера является обязанностью загрузчика Arduino. Поэтому ваш ответ здесь не рассматривается., @Juraj
- Arduino непрерывно считывает значение АЦП с помощью прерывания
- 4-битный счетчик вверх и вниз
- Включить и отключить отдельные прерывания
- Измерить количество циклов и время цифрового входа
- Прерывание сравнения Timer2 не работает должным образом
- Проблема прерывания библиотеки MPU6050 Arduino Jeff Rowberg
- Библиотека TimerOne — время отклика
- генерировать два сдвинутых по фазе ШИМ-импульса, запускаемых внешним сигналом с частотным разделением, с помощью Arduino uno?
Будьте осторожны, используя строку serial.print внутри вашего ISR. Последовательная связь требует прерываний для функционирования., @lemontwist
@lemontwist Спасибо, похоже, работает достаточно хорошо, чтобы просто проверить, срабатывает ли ISR или нет. Я бы не стал этого делать в реальной работе..., @Bitrex