Watchdog

Тема в разделе "Микроконтроллеры AVR", создана пользователем Orest, 4 ноя 2021.

  1. Orest

    Orest Нерд

    Доброе время суток. Беспокоит меня вопрос, прошу подсказать решение. В свой проект хочу добавить watchdog. На одной и той же плате Arduino хочет работает, а хочет нет. То есть когда проект фактически пуст (10 строк кода) – то отлично работает, когда большой (более 900 строк кода) вообще не реагирует на переполнение по времени. Пытался экспериментировать с настройками компилятора (уровни оптимизации) Arduino IDE, так в момент переполнения по времени просто повисает или ведет себя не адекватно. Пробовал разные библиотеки watchdog, эффект почти тот же. Что не так?
     
  2. parovoZZ

    parovoZZ Гуру

    Повисает вачдог? Как? Это просто таймер. Он не может зависнуть - у него свой RC генератор.
    Библиотека для вачдога? Зачем? Всё реализуется несколькими строчками кода записи в регистры вачдога.

    Как работает вачдог и вообще как он устроен, об этом можно почитать в книге Евстифеева. Там есть пара тонкостей.
    Для старых тинек у меня есть такие макроподстоновки
    Код (C++):
    #define WDT_16_mS            WDTCSR = Bit(WDE)
    #define WDT_125mS           WDTCSR = Bit(WDE) | Bit(WDP1) | Bit(WDP0)
    #define WDT_250mS           WDTCSR = Bit(WDE) | Bit(WDP2)
    #define WDT_int_16mS        WDTCSR = Bit(WDIE) | Bit(WDE)                            // Включение собаки на 16 мс и разрешение прерываний от нее
    #define WDT_int_32mS        WDTCSR = Bit(WDIE) | Bit(WDE) | Bit(WDP0)                // Включение собаки на 32 мс и разрешение прерываний от нее
    #define WDT_int_125mS        WDTCSR = Bit(WDIE) | Bit(WDE) | Bit(WDP1) | Bit(WDP0)    // Включение собаки на 125 мс и разрешение прерываний от нее
    #define WDT_int_250mS        WDTCSR = Bit(WDIE) | Bit(WDE) | Bit(WDP2)                // Включение собаки на 250 мс и разрешение прерываний от нее
    #define WDT_int_500mS        WDTCSR = Bit(WDIE) | Bit(WDE) | Bit(WDP2) | Bit(WDP0)
    #define MCUSR_reset         MCUSR = 0
    #define WDT_off                WDTCSR = 0
    Для сброса вачдога есть ассемблерная инструкция:
    Код (C++):
    asm("WDR");
     
  3. Orest

    Orest Нерд

    у меня проблема, что не происходит RESET ардуины
     
  4. parovoZZ

    parovoZZ Гуру

  5. Рокки1945

    Рокки1945 Гуру

    да - а когда он должен происходить - можно поподробнее
     
  6. parovoZZ

    parovoZZ Гуру

    информация о причине загрузки МК содержится в регистре MCUSR.
     
  7. parovoZZ

    parovoZZ Гуру

  8. parovoZZ

    parovoZZ Гуру

    После подачи питания у тебя взведётся бит PORF. После внешнего ресета будет взведён бит EXTRF. Ресет по вачдогу - WDRF.
     
    Последнее редактирование: 5 ноя 2021
  9. parovoZZ

    parovoZZ Гуру

    а ресет разве не вызывает загрузку МК?
     
    Рокки1945 нравится это.
  10. Orest

    Orest Нерд

    wdt_disable();
    wd = MCUSR & B00001000;
    bo = MCUSR & B00000100;
    ext = MCUSR & B00000010;
    pon = MCUSR & B00000001;
    MCUSR = MCUSR & B11110000;
    wdt_enable(WDTO_8S);

    этот кусок кода влиять на ситуацию может?
     
  11. parovoZZ

    parovoZZ Гуру

    на какую ситуацию?
    MCUSR можно обнулить целиком
    Код (C++):
    MCUSR = 0;