Ремонт аргуино мега после залития

Тема в разделе "Arduino & Shields", создана пользователем Mitrandir, 21 июн 2018.

  1. Un_ka

    Un_ka Гуру

     
  2. Un_ka

    Un_ka Гуру

    Где этот код искать?
     
  3. Airbus

    Airbus Радиохулиган Модератор

    Хочешь я поищу за тебя?
     
  4. parovoZZ

    parovoZZ Гуру

    Ну хорошо. Мысля на код не ложится, поэтому потрещу с вами.
    Определяем макросы
    Код (C++):
    //... Сторожевая собака
    #define WDT_on            WDTCSR = Bit(WDE) | Bit(WDCE)
    #define WDT_int_on            WDTCSR = Bit(WDIE) | Bit(WDE)                    // Включение собаки и разрешение прерываний от нее
    #define WDT_int_64mS        WDTCSR = Bit(WDIE) | Bit(WDE) | Bit(WDCE) | Bit(WDP1)        // Включение собаки на 64 мс и разрешение прерываний от нее
    #define WDT_int_125mS        WDTCSR = Bit(WDIE) | Bit(WDE) | Bit(WDCE) | Bit(WDP1) | Bit(WDP0)    // Включение собаки на 125 мс и разрешение прерываний от нее
    #define WDT_off            WDT_on; WDTCSR = 0
    Работу с макросами сна определим в функцию
    Код (C++):
        //... Сон
    void Sleep(uint8_t Sleep_Mode)
    {
        set_sleep_mode(Sleep_Mode);

        sleep_enable();

        sleep_cpu();                // Уходим в сон здесь
                           
        sleep_disable();                // Из прерывания возвращаемся сюда
    }
    макросы определены в файле
    Код (C++):
    #include <avr/sleep.h>
    Вместо макросов можно прямо писать в регистр сна, но с макросами удобнее и нагляднее)))

    У avr есть несколько режимов сна. При этом, чем крепче сон, тем тяжелее ему просыпаться. Из самого крепкого сна SLEEP_MODE_PWR_DOWN он может проснуться только от внешнего прерывания INTх (PCINTx - не знаю. В даташитах расплывчато написано) или от собаки. Ну и от любого ресета МК уйдёт на вектор ресета. Итак, код:
    Код (C++):
    int main(void)
    {  
        wdt_reset();

        WDT_int_125mS;                // Заряжаем будильник на 125 мс, как пример

        sei();

        Sleep(SLEEP_MODE_PWR_DOWN);

        WDT_off;
    Сразу после того, как отресетились по собаке, не забываем, что она настроена по умолчанию на 8 мс и ресет. Поэтому в самом начале собаку надо отресетить, чтобы не уйти на вечный ресет. Если далее по коду собака не нужна, то выключаем её.
    Также, если в мк присутствует защитный регистр CCP, то перед конфигурированием регистров MCUCR и некоторых битов регистра собаки WDTCSR (смотреть даташит), в регистр надо занести сигнатуру. Для 441/841 аттиньки код выглядит примерно так:

    Код (C++):
    #define WDT_int_on()        CCP = 0xD8; WDTCSR = Bit(WDIE) | Bit(WDE);        // Включение собаки и разрешение прерываний от нее
    #define WDT_int_64mS()        CCP = 0xD8; WDTCSR = Bit(WDIE) | Bit(WDE) | Bit(WDP1);    // Включение собаки на 64 мс и разрешение прерываний от нее
    #define WDT_int_125mS()        CCP = 0xD8; WDTCSR = Bit(WDIE) | Bit(WDE) | Bit(WDP1) | Bit(WDP2);    // Включение собаки на 125 мс и разрешение прерываний от нее
    Никаких библиотек не надо. Без них всё просто и наглядно. В случае чего смотрим в даташит. С библиотекой смотреть некуда - только на форуме милостыню просить.
     
    Daniil нравится это.
  5. parovoZZ

    parovoZZ Гуру

    Да, забыл. Уходим на вектор прерывания, чтобы сбросить флаг:
    Код (C++):
    ISR(WDT_vect)
    {
                      // Обработка исключительно для сброса флага прерывания от собаки
    }
    ВНИМАНИЕ! Для разный мк векторы определены по разному. Но код скомпилируется с любым аргументом в вызове прерывания!!! Какой именно вектор в вашем случае, смотреть в соответствующем заголовочном файле. Для 44 аттиньки это файл iotn44a.h и вектор зовется WATCHDOG_vect.
     
    Yaroslav1 и Daniil нравится это.
  6. Изопропанол (изопропиловый спирт) ? :)