Прошу помочь, разобраться во взаимоотношениях внешнего прерывания и 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
}
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
}