Перейти к содержанию

Attiny: watchdog при внешнем прерывании = reset?

Добрый день!

Прошу помочь, разобраться во взаимоотношениях внешнего прерывания и watchdog у Attiny85.

Я делаю автономный счетчик импульсов https://github.com/dontsovcmc/ImpCounter и столкнулся с проблемой:

1) Attiny85 уходит в перезагрузку по прерыванию по таймеру в случае когда пин внешнего прерывания замкнут на землю..

2) Я подтянул RESET 10к к питанию. Стоит ли для двух входов также внешние добавить?

Спасибо за помощь!

Код
volatile uint8_t wdt_count; //0-60
volatile uint16_t btnCount;
volatile uint16_t btn2Count;

/* Watchdog interrupt vector */
ISR( WDT_vect ) {
    wdt_count--;
}  

/* External interrupt */
ISR(PCINT0_vect)
{
    btnCount += (debounce.pin(BUTTON_PIN) == LOW);
    btn2Count += (debounce.pin(BUTTON2_PIN) == LOW);
}

void gotoDeepSleep( uint16_t minutes, uint16_t *counter, uint16_t *counter2)
{
    btnCount = *counter;
    btn2Count = *counter2;


    pinMode(4, INPUT_PULLUP);
    pinMode(3, INPUT_PULLUP);

    power_all_disable();  // power off ADC, Timer 0 and 1, serial interface

    set_sleep_mode( SLEEP_MODE_PWR_DOWN );
    noInterrupts();       // timed sequence coming up
    resetWatchdog();      // get watchdog ready

    GIMSK |= (1 << PCIE);   // pin change interrupt enable
    PCMSK |= (1 << PCINT4 | 1 << PCINT3); // pin change interrupt enabled for PCINTx

    interrupts();         // interrupts are required now
    
    for (uint16_t i = 0; i < minutes; ++i)
    {
        wdt_count = 60;
        while ( wdt_count > 0 )
        {
            sleep_mode();
        }
    }
        
    wdt_disable();

    PCMSK &= ~(1 << PCINT4 | 1 << PCINT3);   // Turn off PBx as interrupt pin

    power_all_enable();

    *counter = btnCount;
    *counter2 = btn2Count;

    pinMode(4, OUTPUT);
    pinMode(3, OUTPUT);
}

void resetWatchdog()
{
    MCUSR = 0; // clear various "reset" flags
    WDTCR = bit( WDCE ) | bit( WDE ) | bit( WDIF ); // allow changes, disable reset, clear existing interrupt
    // set interrupt mode and an interval (WDE must be changed from 1 to 0 here)
    WDTCR = bit( WDIE ) | bit( WDP2 ) | bit( WDP1 );    // set WDIE, and 1 seconds delay
                                                        
    wdt_reset(); // pat the dog
}

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для публикации сообщений создайте учётную запись или авторизуйтесь

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

Создать учетную запись

Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!

Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.

Войти
Авторизация