AVR Modo de interrupción de vigilancia y modo de reinicio

0

Estoy pasando por la hoja de datos de AVR2560V. En la página 65, tabla 12-1, dice que el AVR2560 tiene 3 modos para el perro guardián

  1. Interrupt mode - WDE = 0, WDIE = 1
  2. Reset Mode - WDE = 1, WDIE = 0
  3. Both - WDE = 1, WDIE = 1

Esto significa que si queremos usar el temporizador de vigilancia como fuente de Interrupción, entonces debería deshabilitar WDE. Estoy en lo cierto? Porque cuando deshabilito WDE en el código, el temporizador de vigilancia se desactiva. He visto esto enlace también e incluso él está haciendo lo mismo. WDE tiene sentido que debe estar habilitado, solo la tabla en la hoja de datos me confunde. ¿Alguien puede ayudarme, por favor, a aclarar esta duda?

A continuación se muestra la función Watchdog_init que estoy usando.

 Watchdog_init(){
        MCUSR &= ~(1<<WDRF);

        WDTCSR |= (1<<WDCE) | (1<<WDE); // as per datasheet WDE should be 0?

        // timeout in 8 second
        WDTCSR = 1<<WDP0 | 1<<WDP3;

        // watchdog interrupt enabler
        WDTCSR |= _BV(WDIE);
    }
    
pregunta srj0408

2 respuestas

2

Tienes múltiples escrituras en WDTCSR:

  1. Establezca WDCE y WDE, dejando el resto de basura
  2. Establezca WDP0 y WDP3, y borre el resto
  3. Establezca algunos otros bits de acuerdo con la macro _BV, dejando el resto como estaban

Por lo tanto, tu paso 1 se está eliminando con el paso 2.

Sugeriría combinar los tres en una sola tarea.

    
respondido por el AaronD
2
  

Esto significa que si queremos usar el temporizador de vigilancia como fuente de interrupción,   entonces debería deshabilitar WDE. Estoy en lo correcto?

Correcto: no se debe configurar WDE si desea utilizar WD en modo de interrupción.

  

Porque cuando deshabilito WDE en el código, el temporizador de vigilancia está recibiendo   inhabilitado.

Esto no es correcto. WDE significa Watchdog System Reset Enable . El temporizador de vigilancia en realidad siempre se ejecuta sin importar qué. Los bits WDE y WDIE solo determinan lo que sucede cuando el temporizador alcanza el tiempo de espera.

Su código para configurar el modo de interrupción WD es básicamente correcto, excepto ...

  1. Es una buena práctica desactivar las interrupciones mientras se cambia el WDTCSR porque si ocurriera un intervalo entre el momento en que se habilitan los cambios y se intenta realizar el cambio real, entonces habrían transcurrido más de 4 ciclos y el cambio fallar.
  2. Es un poco más eficiente configurar todos los bits en WDTCSR a la vez.

    Watchdog_init() {    
    
    
        // Just to be safe since we can not clear WDE if WDRF is set
        MCUSR &= ~(1<<WDRF);
    
    
        // disable interrupts so we do not get interrupted while doing timed sequence
        cli()
    
        // First step of timed sequence, we have 4 cycles after this to make changes to WDE and WD timeout
        WDTCSR |= (1<<WDCE) | (1<<WDE); 
    
        // timeout in 8 second, disable reset mode. Must be done in one operation
        WDTCSR = 1<<WDP0 | 1<<WDP3;
    
        // enable global interrupts
        sei();
    
        // enable watchdog interrupt only mode 
        WDTCSR |= _BV(WDIE);
    

    }

Otras cosas para verificar:

  1. Asegúrese de que las interrupciones globales estén habilitadas; de lo contrario, las interrupciones se producirán pero no ejecutarán su controlador.
  2. Asegúrese de que el fusible WDTON no esté programado o, de lo contrario, no podrá usar el modo de interrupción.
respondido por el bigjosh

Lea otras preguntas en las etiquetas