#define __AVR_ATmega2560__ #define F_CPU 16000000UL #include #include #include #include "lib/util.h" #include "lib/7segment.h" #include "lib/7segment_4digits.h" /** * O O O O O O O O * DDRF x x x x x x x x * \-\-\-\-\-\-\-\--- 7 segment output * * I I O O O O O O * DDRK x x x x x x x x * | | \-\-\-\--- digit selection output * \-\--------------- Button input */ void main() { DDRF = 0b11111111; DDRK = 0b00001111; PORTK = 0b11000000; // set pull-up uint32_t millis = 0; bool counting = false; bool pressed_pause = false; bool pressed_clear = false; while(1) { // show_float() doesn't actually print to the display directly, it only updates // a variable stored in memory. We call `update_display_all_sync()` periodically, // which reads the stored variable and outputs it. show_float(millis / 1000.0f); // Cycles through all 4 displays, turns them on for a set amount of time // while displaying the value set by `show_float()` earlier and returns // the total amount waited. uint32_t sleep_time = update_display_all_sync(); if (counting) { // We can use the returned sleep_time to (inaccurately) count time. millis += sleep_time; } // If the button connected to PIN7 is pressed, pause or unpause the counter. if (!pressed_pause && bit_is_clear(PINK, PINK7)) { counting = !counting; pressed_pause = true; } else if (pressed_pause && bit_is_set(PINK, PINK7)) { pressed_pause = false; } // If the button connected to PIN6 is pressed, reset and pause the counter. if (bit_is_clear(PINK, PINK6)) { millis = 0; counting = false; pressed_clear = true; } else pressed_clear = false; } }