Interrupciones en AVR

Estoy usando un atmega328 en AVR. Todavía no he hecho ninguna codificación, pero estoy planeando. Cómo lo haré en mi cabeza. Así que quiero poder activar el ATmega328 presionando un botón e irme a dormir después de haber presionado el mismo botón. ¿Cómo haré eso?

En mi cabeza, es similar a esto .

Colocaré el código de suspensión en la función principal y también un bucle while en la función ISR. Cuando detecta que se presiona un botón, sale del ciclo while y vuelve a dormir.

esto funcionara? ¿Cómo se presiona un botón de manejo de ATmega mientras está en la función de rutina de servicio de interrupción? ¿O cómo distingue entre presionar un botón para interrumpir el sueño y presionar un botón para dormir?

No deberías poner un bucle while en una ISR, ese es un enfoque realmente tonto. Un ISR está destinado a ser una breve y rápida ráfaga de código. Solo debe tener una bandera booleana en el ISR que se activa cada vez que se presiona un botón. Luego, en el ciclo principal, verifique el estado de la bandera. Si es Verdadero, vaya a Dormir.
Asegúrese de declarar su indicador como volatile(para que el compilador sepa que puede cambiar en el ISR y no lo optimice). Por ejemplo:volatile boolean flag;
@TomCarpenter esto se define como una variable global, no como una variable local, ¿sí? es decir, cuando hago las declaraciones de funciones, etc.
Sí, variable global, para que esté dentro del alcance (visible) tanto en su ISR como en su función principal (). Puede ponerlo en la parte superior de su archivo .c si todo está en un archivo, o declararlo en un archivo .h.
Hola @TomCarpenter, gracias por el consejo. Implementé con éxito un programa que llama a la interrupción y enciende el LED durante 10 segundos, antes de volver al código original. Esto está usando una bandera volátil. Ahora estoy buscando entrar en modo de suspensión. mi pregunta es, cuando un microcontrolador está en suspensión y una interrupción cambia la bandera... ¿se despierta el microcontrolador?
Eso depende completamente del microcontrolador.
Cualquier fuente de activación activa automáticamente la CPU AVR. Una vez que se despierta, no vuelve a dormirse a menos que se lo indiques. Por lo tanto, procesará el ISR y luego volverá a ejecutar el código comenzando en la primera instrucción después del comando de suspensión.

Respuestas (1)

Las interrupciones y las pulsaciones de botones no se mezclan EN ABSOLUTO. Los botones tienen un fenómeno que conoce un rebote. Justo antes de que los contactos se cierren, "rebotan" haciendo y rompiendo el contacto. Si, por ejemplo, usa una interrupción de cambio de pin con un botón, puede ingresar y salir del modo de suspensión varias veces antes de que el botón se estabilice. Los botones necesitan rebote, una técnica que asegura que el estado del botón sea estable antes de leerlo.

La mejor manera de eliminar el rebote de un botón es leer el estado del botón en intervalos regulares, 1 ms por ejemplo. Si el estado del botón permanece constante durante al menos 50 ms, el botón puede considerarse estable.

La forma en que normalmente escribo una rutina de este tipo es marcar el botón cada 1 ms. Si no hay un evento de rebote en curso y el estado actual del botón no coincide con el estado del botón anterior, inicie un evento de rebote. Continúe comprobando el botón cada 1 ms, pero incremente un contador cada vez que se lea un botón. Normalmente comenzaré en 50. Si el botón está bajo, disminuiré y si el botón está alto, lo incrementaré. Si llega a 100, el botón está alto y si llega a 0, el botón está bajo. Restablezca la variable de inicio a 50 y establezca el evento de rebote en falso.

En su caso, usaría la interrupción de cambio de pin para activar el micro pero luego impondría un rebote obligatorio. Si pasa el rebote, quédese despierto. Si el rebote falla, lo que significa que no se presionó un botón, vuelva a dormir.