#include <avr/sleep.h>
const int segA[4] = {6, 7, 8, 9}; // Сегментные линии для разрядов
const int digitPins[4] = {2, 3, 4, 5}; // Пины управления разрядами
const int btnMin = A0;
const int btnHour = A1;
const int btnSleep = A2;
const byte numbers[10] = {
B01000000, // 0
B01111001, // 1
B00100100, // 2
B00110000, // 3
B00011001, // 4
B00010010, // 5
B00000010, // 6
B01111000, // 7
B00000000, // 8
B00010000 // 9
};
volatile int hour = 0, minute = 0, second = 0;
volatile byte currentDigit = 0;
unsigned long lastSecond = 0;
void setup() {
for (int i = 0; i < 4; i++) {
pinMode(segA[i], OUTPUT);
pinMode(digitPins[i], OUTPUT);
}
pinMode(btnMin, INPUT_PULLUP);
pinMode(btnHour, INPUT_PULLUP);
pinMode(btnSleep, INPUT_PULLUP);
// Настройка таймера прерывания
Timer1Setup();
}
void loop() {
// Обновление времени
if (millis() - lastSecond >= 1000) {
lastSecond = millis();
second++;
if (second >= 60) {
second = 0;
minute++;
if (minute >= 60) {
minute = 0;
hour++;
if (hour >= 24) hour = 0;
}
}
}
// Кнопки настройки
if (digitalRead(btnMin) == LOW) {
minute = (minute + 1) % 60;
second = 0;
delay(300);
}
if (digitalRead(btnHour) == LOW) {
hour = (hour + 1) % 24;
delay(300);
}
// Переход в спящий режим
if (digitalRead(btnSleep) == LOW) {
delay(300);
goToSleep();
}
// Обновление дисплея (мультиплекс)
updateDisplay();
}
void updateDisplay() {
int displayData[4] = {
hour / 10,
hour % 10,
minute / 10,
minute % 10
};
for (int i = 0; i < 4; i++) {
digitalWrite(digitPins[i], LOW); // отключить все цифры
}
for (int j = 0; j < 4; j++) {
setSegments(numbers[displayData[j]]);
digitalWrite(digitPins[j], HIGH);
delay(2);
digitalWrite(digitPins[j], LOW);
}
}
void setSegments(byte segments) {
for (int i = 0; i < 7; i++) {
digitalWrite(segA[i], (segments >> i) & 0x01);
}
}
void goToSleep() {
for (int i = 0; i < 4; i++) {
digitalWrite(segA[i], LOW);
digitalWrite(digitPins[i], LOW);
}
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
sleep_enable();
sleep_cpu();
sleep_disable();
}
void Timer1Setup() {
cli();
TCCR1A = 0;
TCCR1B = 0;
TCCR1B |= (1 << WGM12); // CTC режим
TCCR1B |= (1 << CS12); // Делитель 256
OCR1A = 62500; // 1 сек при 16МГц / 256
TIMSK1 |= (1 << OCIE1A);
sei();
}
ISR(TIMER1_COMPA_vect) {
// секундный тик таймера (альтернатива millis)
}