Compare commits

..

No commits in common. "5950b75da42fd2a8038a07006465b87396a69e45" and "d18e4cfd08a7d0ac0efafab4ff7f1812990d0fac" have entirely different histories.

2 changed files with 25 additions and 42 deletions

64
main.c
View file

@ -1,56 +1,38 @@
#include <avr/interrupt.h> #include <avr/interrupt.h>
#include <avr/io.h> #include <avr/io.h>
#include <avr/sleep.h> #include <avr/sleep.h>
#include <avr/wdt.h> #include <util/delay.h>
#define LED_PIN PB5 // Define the pin connected to the LED #define BLINK_TIME 0.5 // 1 second
ISR(TIMER1_COMPA_vect) { ISR(TIMER1_OVF_vect) {
// Static variable to keep track of the number of interrupts PORTB ^= _BV(PORTB5); // Toggle the LED
static uint16_t counter = 0; TCNT1 = 65535 - (F_CPU / 1024 * BLINK_TIME); // Reset timer value
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) { int main(void) {
// Configure the LED pin as an output // Set PORTB5 as output
DDRB |= _BV(LED_PIN); DDRB |= _BV(DDB5);
configure_interrupt(); // Initialize TIMER1 value
TCNT1 = 65535 - (F_CPU / 1024 * BLINK_TIME);
// Set the watchdog timer to 8 seconds // Set the prescaler to 1024
wdt_enable(WDTO_8S); TCCR1B |= _BV(CS10) | _BV(CS12);
// Set the sleep mode to idle // Enable TIMER1 overflow interrupt
set_sleep_mode(SLEEP_MODE_IDLE); TIMSK1 |= _BV(TOIE1);
// Enable global interrupts
// sei();
// Enable global interrupts with style
__asm__ __volatile__ ("sei");
// Pat the dog and sleep until the next interrupt
while (1) { while (1) {
wdt_reset(); // Keep in mind that the sleep mode depth will affect the wake up time
sleep_mode(); sleep_cpu(); // Deep sleep
// set_sleep_mode(SLEEP_MODE_IDLE); // Idle sleep
// sleep_mode(); // Sets the CPU to whatever mode was set
} }
return 0;
} }

View file

@ -9,7 +9,7 @@ MCU = atmega328p
QEMU_MACHINE_NAME = uno QEMU_MACHINE_NAME = uno
# Compiler flags # Compiler flags
CFLAGS = -std=c99 -Wall -Wno-array-bounds -mmcu=$(MCU) -DF_CPU=16000000UL -Os -g CFLAGS = -std=c2x -Wall -Wno-array-bounds -mmcu=$(MCU) -DF_CPU=16000000UL -O3
# Source files # Source files
SRCS = main.c SRCS = main.c
@ -30,6 +30,7 @@ all: $(TARGET).hex
# Link object files # Link object files
$(TARGET).elf: $(OBJS) $(TARGET).elf: $(OBJS)
$(CC) $(CFLAGS) $(OBJS) -o $(TARGET).elf $(CC) $(CFLAGS) $(OBJS) -o $(TARGET).elf
avr-strip $(TARGET).elf
# Convert ELF to HEX # Convert ELF to HEX
$(TARGET).hex: $(TARGET).elf $(TARGET).hex: $(TARGET).elf