Запуск программного сброса Arduino Leonardo

Я хочу выполнить программный сброс на моем Arduino Leonardo и после некоторых поисков остановился на использовании сторожевого таймера, так как это кажется самым простым и понятным способом сделать это.

Однако я не думаю, что это работает должным образом. Кажется, в следующем примере все работает нормально:

#include <avr/wdt.h>

int outputPin = LED_BUILTIN;

void setup() {
  MCUSR = 0;
  wdt_disable();
  pinMode(outputPin, OUTPUT);
  digitalWrite(outputPin, HIGH);
  delay(500);
  digitalWrite(outputPin, LOW);
  delay(500);
  digitalWrite(outputPin, HIGH);
  delay(500);
  digitalWrite(outputPin, LOW);
  delay(1000);
}

void loop() {
  wdt_enable(WDTO_15MS);
  while (true) {}
}

Светодиодный индикатор постоянно мигает.

Но для следующего примера:

#include <avr/wdt.h>

void setup() {
  MCUSR = 0;
  wdt_disable();
  Serial.begin(9600);
  while (!Serial);
  Serial.println("Hello");
}

void loop() {
  wdt_enable(WDTO_15MS);
  while (true) {}
}

«Привет» печатается только один раз (хотя я ожидал, что оно будет поступать постоянно).

Я попробовал увеличить время ожидания сторожевого таймера до 2 секунд, но это не решило проблему.

, 👍2

Обсуждение

попробуйте для теста более длительное время, например WDTO_2S. некоторые загрузчики не сбрасывают флаг wdt, а затем следующий сброс запускается до того, как чип войдет в вашу настройку()., @Juraj

@Juraj, изменив WDTO_15MS на WDTO_2S в приведенном выше примере, окончательное состояние (L горит, RX мигает) устанавливается через 2 секунды, но, к сожалению, это не решило проблему., @martonbognar

вы тестируете эскиз без серийного номера, как эскиз в Вопросе?, @Juraj

Подсказка: вы можете определить функцию для вектора сброса, например void (*RESET)() = NULL;, а затем вызывать эту функцию, когда захотите, например RESET();. Обратите внимание, что все аппаратные регистры не сбрасываются. Настройка эскиза не должна предполагать состояние аппаратного регистра., @Mikael Patel

@Юрай, Юрай, я отредактировал вопрос. С тех пор я обнаружил, что мне не хватает pinMode в моем исходном примере, и это решило эту конкретную проблему. Однако для (теперь добавленного) последовательного примера это все еще не работает., @martonbognar

@MikaelPatel, ты имеешь в виду что-то вроде этого? https://pastebin.com/raw/0UNf3mik Это по-прежнему печатает «Привет» только один раз., @martonbognar

Вместо этого попробуйте мигать светодиодом. Правильно установите регистры в настройках., @Mikael Patel

Ой, подождите, я думаю, проблема может заключаться в том, что после каждого сброса последовательный монитор отключается (хотя он не становится серым), и поэтому я не вижу следующих сообщений «Привет». Я исследую немного дальше., @martonbognar

Последовательный порт (USB) отключится, и USB-соединение с хостом прервется. Вам понадобится гораздо более продвинутое обнаружение и повторное подключение к хосту :), @Mikael Patel

Да, похоже, это была единственная проблема. Спасибо за помощь МикаэлПателю и Юрай!, @martonbognar

еще одна вещь: while (!Serial); останавливает скетч, если USB-соединение не открыто., @Juraj


1 ответ


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

1

Вот и получается, что мой код работал корректно, сторожевой таймер выполнил сброс как надо, проблема была только в том, что мне нужно было перезапускать последовательный монитор после каждого сброса.

,