diff --git a/main.c b/main.c index 17f29f2..8e2ee04 100644 --- a/main.c +++ b/main.c @@ -2,9 +2,18 @@ #include #include #include +#include #define LED_PIN PB5 // Define the pin connected to the LED +// Flipping the led every 0.5s using the overflow interrupt +ISR(TIMER1_OVF_vect) { + PORTB ^= _BV(LED_PIN); // Toggle the LED + TCNT1 = (uint16_t)(65535 - (F_CPU / 1024) * 0.5); // Reset the counter + TIFR1 |= (1 << TOV1); // Clear the interrupt flag +} + +// 'Pulse' the LED ISR(TIMER1_COMPA_vect) { // Static variable to keep track of the number of interrupts static uint16_t counter = 0; @@ -14,6 +23,7 @@ ISR(TIMER1_COMPA_vect) { // Modulo magic, see below for explanation if (++counter % 2 == 0) { OCR1A = 15624 / 2; + counter = 0; } else { OCR1A = 15624 / 16; } @@ -22,34 +32,77 @@ ISR(TIMER1_COMPA_vect) { TIFR1 |= (1 << TOV1); } +// External interrupt +ISR(INT0_vect) { + PORTB ^= _BV(LED_PIN); // Toggle the LED + _delay_ms(200); // Debounce +} + // We will use Timer1 for the interrupt void configure_interrupt() { - TCNT1 = 0; // Initialize the counter value to 0 - TCCR1A = 0; // Set the timer to normal mode - TCCR1B = 0; // Set the timer to normal mode - OCR1A = 15624 / 16; // 31250 for a 2s delay, 15624 for a 1s delay + TCCR1A = 0; // Set the timer to normal mode + TCCR1B = 0; // Set the timer to normal mode TCCR1B |= (1 << WGM12); // Set the timer to CTC mode TCCR1B |= (1 << CS02) | (1 << CS00); // Set the prescaler to 1024 TIMSK1 |= (1 << OCIE1A); // Enable overflow interrupt - sei(); // Enable global interrupts (cli() to disable) + sei(); // Enable global interrupts (cli() to disable) + OCR1A = 0; // 31250 for a 2s delay, 15624 for a 1s delay + TCNT1 = (uint16_t)(65535 - (F_CPU / 1024) * 0.5); // Reset the counter +} + +void configure_external_interrupt() { + // Set the external interrupt to trigger on the falling edge + EICRA |= (1 << ISC01); + EICRA &= ~(1 << ISC00); + + // Enable the external interrupt + EIMSK |= (1 << INT0); // Pin D2 is INT0 + + DDRD &= ~_BV(PD2); // Set the pin as an input + PORTD |= _BV(PD2); // Enable the pull-up resistor + + // Enable global interrupts + sei(); +} + +void configure_ovf_interrupt() { + // Set the timer to normal mode + TCCR1A = 0; + TCCR1B = 0; + + // Initialize the counter to 0xFFFF + TCNT1 = 0xFFFF; + + // Set the prescaler to 1024 + TCCR1B |= _BV(CS12) | _BV(CS10); + + // Enable overflow interrupt + TIMSK1 |= (1 << TOIE1); + + // Enable global interrupts + sei(); } int main(void) { // Configure the LED pin as an output DDRB |= _BV(LED_PIN); - configure_interrupt(); + // Choose one (or both) + // configure_interrupt(); + // configure_ovf_interrupt(); + configure_external_interrupt(); // Set the watchdog timer to 8 seconds - wdt_enable(WDTO_8S); + // wdt_enable(WDTO_8S); + // wdt_disable(); + // wdt_reset(); // Reset the watchdog timer // Set the sleep mode to idle set_sleep_mode(SLEEP_MODE_IDLE); // Pat the dog and sleep until the next interrupt while (1) { - wdt_reset(); - sleep_mode(); + sleep_mode(); // Doesent sleep through interrupts } return 0;