From 7f9bd24fc8f6501583fbba41eb4e3f8686699560 Mon Sep 17 00:00:00 2001 From: Imbus <> Date: Mon, 1 Apr 2024 20:38:35 +0200 Subject: [PATCH] Better base template --- main.c | 64 +++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 41 insertions(+), 23 deletions(-) diff --git a/main.c b/main.c index ba94b22..17f29f2 100644 --- a/main.c +++ b/main.c @@ -1,38 +1,56 @@ #include #include #include -#include +#include -#define BLINK_TIME 0.5 // 1 second +#define LED_PIN PB5 // Define the pin connected to the LED -ISR(TIMER1_OVF_vect) { - PORTB ^= _BV(PORTB5); // Toggle the LED - TCNT1 = 65535 - (F_CPU / 1024 * BLINK_TIME); // Reset timer value +ISR(TIMER1_COMPA_vect) { + // Static variable to keep track of the number of interrupts + static uint16_t counter = 0; + + PORTB ^= _BV(LED_PIN); // Toggle the LED + + // Modulo magic, see below for explanation + if (++counter % 2 == 0) { + OCR1A = 15624 / 2; + } else { + OCR1A = 15624 / 16; + } + + // Clear the interrupt flag + TIFR1 |= (1 << TOV1); +} + +// 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 + 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) } int main(void) { - // Set PORTB5 as output - DDRB |= _BV(DDB5); + // Configure the LED pin as an output + DDRB |= _BV(LED_PIN); - // Initialize TIMER1 value - TCNT1 = 65535 - (F_CPU / 1024 * BLINK_TIME); + configure_interrupt(); - // Set the prescaler to 1024 - TCCR1B |= _BV(CS10) | _BV(CS12); + // Set the watchdog timer to 8 seconds + wdt_enable(WDTO_8S); - // Enable TIMER1 overflow interrupt - TIMSK1 |= _BV(TOIE1); - - // Enable global interrupts - // sei(); - - // Enable global interrupts with style - __asm__ __volatile__ ("sei"); + // Set the sleep mode to idle + set_sleep_mode(SLEEP_MODE_IDLE); + // Pat the dog and sleep until the next interrupt while (1) { - // Keep in mind that the sleep mode depth will affect the wake up time - sleep_cpu(); // Deep sleep - // set_sleep_mode(SLEEP_MODE_IDLE); // Idle sleep - // sleep_mode(); // Sets the CPU to whatever mode was set + wdt_reset(); + sleep_mode(); } + + return 0; }