Función de demora de interrupción del microcontrolador Atmega al presionar un botón

0

Estoy usando Atmega32A y tengo 2 LED. Aquí paso a paso lo que quiero hacer

  1. Cuando la MCU está encendida, tengo un LED encendido (PC0)
  2. Al hacer clic en un botón (PD6), el segundo LED en (PC1) se enciende y el otro se apaga.
  3. Una función de retardo está retrasando este estado durante 10 segundos. Después de eso, el primer LED (PC0) se enciende, también, durante 5 segundos. En este momento, ambos LED están encendidos.
  4. Luego 3. se repite.

Lo que quiero hacer es, cuando hago clic en el botón en (PD6) para poder interrumpir / interrumpir el retraso.

Aquí está el código

#include <avr/io.h>
#include <util/delay.h>

int main(void){
    DDRC = 0b11111111;  //Makes PORTB as Output
    DDRD = 0b00000000;  //Makes PORTD as Input

    PORTC = 0b11111110; //LEDs
    PORTD = 0b11111111; //Button

    int pressed = 0;
    int Pressed_Confidence_Level = 0;
    int Released_Confidence_Level = 0;

    while(1){
        if(bit_is_clear(PIND, 6)){  //If button is pressed (PD6)
            Pressed_Confidence_Level++;
            if(Pressed_Confidence_Level > 500){
                if(pressed == 0){
                    if(PINC & (1<<PC0)){
                        PORTC = 0b11111111; //PC0 LED ON, PC1 LED ON
                    }
                    else{
                        while(1){
                            PORTC = 0b00000001; //PC0 LED ON, PC1 LED OFF
                            _delay_ms(600000);  //10min
                            PORTC = 0b11111111; //PC0 LED ON, PC1 LED ON
                            _delay_ms(300000);  //5min
                            /* How to exit this loop on button press? */
                            }
                        }
                    }
                    pressed = 1;
                }
                Pressed_Confidence_Level = 0;
            }
        }
        else{
            Released_Confidence_Level++;
            if(Released_Confidence_Level > 500){
                pressed = 0;
                Released_Confidence_Level = 0;
            }
        }
    }
}
    
pregunta Ezio_

1 respuesta

4

Los micros atmega tienen interrupciones de hardware que pueden usarse para lograr esto. Las interrupciones se pueden usar con los manejadores de interrupciones (funciones cortas que se llaman cuando se activa una interrupción) llamadas "Rutina de servicio de interrupciones" (ISR) en atmel speak para realizar tareas cortas que le gustaría que se le llame de forma asíncrona con el "hilo" de control primario.

_delay_ms es un retardo de espera ocupado, por lo que no hay ningún daño en llamar a intervalos más cortos (por ejemplo, cada 100 ms y disminuir un contador). Si escribe un controlador de interrupción breve para establecer un indicador global, puede hacer que el bucle verifique el indicador en cada iteración y lo elimine antes. De lo contrario, también puede verificar continuamente el estado del botón en su bucle con un retardo de grano más fino sin interrupciones si el proyecto seguirá siendo tan simple como ya lo es.

Las interrupciones se pueden deshabilitar y habilitar dinámicamente, por lo que no hay ninguna preocupación de que al presionar el botón se cambie el estado del programa fuera del circuito de interés. Es bastante sencillo (una escritura de dirección de memoria) para habilitar y deshabilitar los vectores de interrupción antes y después de que se ejecute el bucle de retardo.

ver por ejemplo:

esta publicación del foro externo

este tutorial

documentación oficial de la biblioteca sobre las rutinas del servicio de interrupción de atmega

esta nota de aplicación técnica de atmel

una breve nota de tutorial de atmel

Revise la 'hoja' del documento de su micro para obtener notas de implementación aún más detalladas.

    
respondido por el crasic

Lea otras preguntas en las etiquetas