El modo de suspensión en ATMEGA16 no funciona

Estoy tratando de poner mi controlador en modo de suspensión y despertarlo en una cierta cantidad de desbordamiento del temporizador. El código es el siguiente:

//*******TIMER 2 INITILIZATION  will be used
    TCCR2=0X07;   //clock source select, prescaler
    TIMSK=0X40;  //timer 2 interrupt selected
    TCNT2=0X00;   // timer resistor
    sei();

    // controller sleep mode
    set_sleep_mode(SLEEP_MODE_PWR_SAVE); // sleep mode selected
    sleep_enable();  // set SE bit
    sleep_cpu(); // sleep mode activated
    do 
    {
        if(count>=1000) //  min delay
        {
            sleep_disable();   // SE bit reset
            _delay_ms(1000);
            print("waking up.....");
            _delay_ms(2000);
            cmd(0xc0);
            print("AT+CFUN=1");
            _delay_ms(1000);
            transmit("AT+CFUN=1\r\n");
            _delay_ms(1000);
            _delay_ms(2000);count=0;
            break;              

        }
        else
        {
            print("sleep");
            sleep_enable();
            sleep_cpu();                
        }       

    } while (1);

el ISR correspondiente es el siguiente

ISR(TIMER2_OVF_vect)
{
    count++;

}

El problema es que no sale del modo de suspensión.

Estoy usando un reloj interno de 8MHz y timer2. editar: encontré esta descripción en la hoja de datos, lo que significa que tengo que usar un reloj asíncrono para el temporizador 2 (es decir, proporcionado por un osc de cristal externo). ¿Hay alguna forma de que pueda hacer esto con la ayuda de un reloj interno?
descripción del modo de ahorro de energía en la hoja de datos

¿Por qué vuelves(cuentas) fuera del servicio de interrupción? Es bastante sin sentido. Además, ¿está declarado como volátil?
He declarado el recuento como tipo entero globalmente con un valor inicial de 0. La función de retorno que estaba usando solo para verificar podría estar usando el retorno, funcionará, pero la eliminaré.
eliminar el retorno (recuento); línea de ISR y agregue 'volátil' antes de la declaración 'int count'.
Además, ¿dónde reinicia la variable 'contar'?
todavía no funciona. No estoy restableciendo la variable de conteo. ¿Es este el código de razón que no funciona?
Porque una vez que la variable cuenta llega a 1000, la condición si (cuenta>=1000) se activará sin parar. A menos que esto sea lo que querías lograr.
No, no puedes hacer esto. Período. Mira tu propio resaltado amarillo. Detiene TODOS LOS RELOJES excepto Async. No hay reloj interno para usar. Ninguno. Está TODO detenido.
¿Un concepto que quiero reconfirmar que el reloj asíncrono solo se proporciona con un oscilador externo o puede ser a través de un osc interno?
¿Cuánta potencia baja necesitas? (Por favor, no responda "lo mejor posible"). ¿Ha leído el capítulo "Minimizar el consumo de energía" de la hoja de datos? Por supuesto, el sueño es importante, pero puede optimizarse mucho más.
En la hoja de datos se da: Modo de apagado: < 1 μA. así que también estoy esperando lo mismo. Investigué un poco y usé xtal externo de 32.7khz y configuré el bit de bandera en consecuencia ahora está funcionando correctamente.

Respuestas (1)

Como dijiste, el temporizador 2 solo se puede usar con Xtal externo en modo de ahorro de energía.

  • Utilice el modo de reposo inactivo (puede reducir la frecuencia de la MCU antes de entrar en reposo para aumentar el consumo)
  • O puede usar el perro guardián para que lo despierte (deshabilitar el modo de interrupción y reinicio). Por supuesto, esto será un poco menos preciso, pero podría usar el modo de suspensión de apagado, que es aún mejor.
Investigué un poco y usé xtal externo de 32.7khz y configuré el bit de bandera en consecuencia. ahora está funcionando correctamente.
Necesitaba la potencia mínima posible y el modo de apagado está satisfaciendo mi necesidad <1 μA. ahora esta funcionando gracias