Как настроить векторный таймер прерываний сторожевого таймера на 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) {

, 👍2


2 ответа


Лучший ответ:

1

Две ошибки:

  1. Вектор прерывания сторожевого таймера называется WDT_vect, а не WDT_vec.
  2. Оператор _WD_CONTROL_REG = 0; не служит никакой полезной цели, и скорее всего, нарушит временную последовательность смены сторожевого таймера Настройка. Просто удалите ее.
,

0

_WD_CONTROL_REG = 0; выполняет важную функцию. Если сторожевой таймер случайно включается, например, из-за неконтролируемого указателя или состояния отключения питания, устройство будет сброшено, а сторожевой таймер останется включенным. Если код не настроен на обработку сторожевого таймера, это может привести к вечному циклу сбросов по тайм-ауту. Чтобы избежать этой ситуации, прикладное программное обеспечение всегда должно очищать флаг сброса системы сторожевого таймера (WDRF) и бит управления WDE в инициализации рутина, даже если Watchdog не используется. Если вы используете его при разработке продукта, программа которого никогда не должна зависать, то об этом важно помнить.

,