Estoy escribiendo un programa para un ATtiny85. Quiero usar el watchdog para despertarme del apagado en ciertos intervalos. Todo funciona bien siempre y cuando los intervalos para un evento de perro guardián no cambien dentro del programa (es decir, no cambio los bits WDP0-3 después de que se configuren una vez).
Tan pronto como cambio el tiempo de espera del perro guardián, realiza un reinicio no deseado. No tengo el fusebit WDTON habilitado, por lo que el perro gordo no siempre está encendido, sino que tiene que estar habilitado por el software. (De hecho, los bits de los fusibles son: Bajo = 0xe2, Alto = 0xdf y Extendido = 0xff hacen que el controlador funcione a 8 Mhz desde el oscilador interno).
Aquí hay un recorte de mi código:
#include <avr/wdt.h>
#include <avr/power.h>
#include <avr/sleep.h>
#include <avr/interrupt.h>
void Config_wdt(uint8_t timeout) {
cli();
wdt_reset(); // reset watchdog timer
MCUSR &= ~(1<<WDRF); // clear reset flag
WDTCR = (1<<WDE) | (1<<WDCE); // enable watchdog
WDTCR = (1<<WDIE) | timeout; // watchdog interrupt instead of reset
//+reset, timeout can be 15,30,60,120,250,500ms or 1,2,4,8s
sei();
}
EMPTY_INTERRUPT(WDT_vect)
void Sleep_now(uint8_t i, uint8_t timeout) {
Config_wdt(timeout);
for(i=i; i>0; --i) {
set_sleep_mode(SLEEP_MODE_PWR_DOWN); // set type of sleepmode
power_all_disable(); // disable unneeded loads
wdt_reset(); // timer should start at zero
sleep_enable(); // approach sleep mode
sleep_mode(); // enter sleep mode (confirm)
sleep_disable(); // entrance point when woken up
// Another Config_wdt(timeout); here or re-enabling WDIE doesn't help either
power_all_enable(); // re-enable the loads
}
}
int main() {
Config_wdt(WDTO_500MS);
Do_some_stuff();
Sleep_now(5, WDTO_500MS); // WORKS AS EXPECTED, SLEEPS 5 TIMES 500ms = 2.5s
while(1) {
Make_other_things();
Sleep_now(3, WDTO_30MS); // DOES AN UNWANTED RESET, ...
\+I.E. STARTS FROM THE BEGINNING BEFORE "Do_some_sfuff()"...
\+IF I REPLACE "WDTO_30MS" HERE by "WDTO_500MS" FROM ABOVE...
\+THE CODE WORKS FINE.
}
}
La hoja de datos tiene esto que decir:
Si se establece WDE, WDIE se borra automáticamente por el hardware cuando se produce un tiempo de espera. Esto es útil para mantener el Watchdog Reinicia la seguridad mientras usas la interrupción Una vez que se borra el bit WDIE, el siguiente tiempo de espera generará un Reiniciar. Para evitar el restablecimiento de Watchdog, WDIE debe configurarse después de cada interrupción.
Pero incluso si configuro el bit WDIE inmediatamente después de levantarme del modo de suspensión, todavía se hace un reinicio no deseado.
Entonces, ¿cómo cambio el tiempo de espera de vigilancia en mi código, sin el reinicio no deseado?