#include <Wire.h>
#include <RTClib.h>
// Определение пинов для подключения сдвиговых регистров
const int dataPin = 2; // DS (pin 14) на 74HC595
const int latchPin = 3; // ST_CP (pin 12) на 74HC595
const int clockPin = 4; // SH_CP (pin 11) на 74HC595
// Объект для работы с RTC
RTC_DS3231 rtc;
// Массив с кодами для цифр на 7-сегментном индикаторе (общий катод)
// Биты: DP A B C D E F G
const byte digitPatterns[10] = {
B00111111, // 0
B00000110, // 1
B01011011, // 2
B01001111, // 3
B01100110, // 4
B01101101, // 5
B01111101, // 6
B00000111, // 7
B01111111, // 8
B01101111 // 9
};
void setup() {
// Инициализация последовательного порта для отладки
Serial.begin(9600);
// Установка пинов в режим выхода
pinMode(dataPin, OUTPUT);
pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
// Инициализация RTC
if (!rtc.begin()) {
Serial.println("Не удалось найти RTC");
while (1);
}
// Если RTC потерял питание, установим время компиляции
if (rtc.lostPower()) {
Serial.println("RTC потерял питание, устанавливаем время компиляции!");
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
}
// Начальное состояние - все сегменты выключены
updateShiftRegisters(0, 0, 0, 0);
}
void loop() {
static unsigned long lastUpdate = 0;
// Обновляем отображение чаще (для плавности)
if (millis() - lastUpdate >= 200) {
lastUpdate = millis();
// Получаем текущее время от RTC
DateTime now = rtc.now();
// Обновляем отображение
displayTime(now.hour(), now.minute());
}
// Здесь можно добавить обработку кнопок для настройки времени
}
void displayTime(byte hours, byte minutes) {
// Разделяем часы и минуты на отдельные цифры
byte hourTens = hours / 10;
byte hourUnits = hours % 10;
byte minuteTens = minutes / 10;
byte minuteUnits = minutes % 10;
// Получаем коды для каждой цифры
byte digit1 = hourTens > 0 ? digitPatterns[hourTens] : 0; // Не показываем ноль в старшем разряде часов
byte digit2 = digitPatterns[hourUnits];
byte digit3 = digitPatterns[minuteTens];
byte digit4 = digitPatterns[minuteUnits];
// Добавляем двоеточие между часами и минутами (включено для digit2)
//digit2 |= B10000000; // Устанавливаем бит DP
// Отправляем данные в регистры
updateShiftRegisters(digit1, digit2, digit3, digit4);
}
void updateShiftRegisters(byte digit1, byte digit2, byte digit3, byte digit4) {
// Устанавливаем latchPin в LOW перед передачей данных
digitalWrite(latchPin, LOW);
// Передаем данные, начиная с последнего регистра (digit4)
shiftOut(dataPin, clockPin, MSBFIRST, digit4);
shiftOut(dataPin, clockPin, MSBFIRST, digit3);
shiftOut(dataPin, clockPin, MSBFIRST, digit2);
shiftOut(dataPin, clockPin, MSBFIRST, digit1);
// Устанавливаем latchPin в HIGH для обновления выхода регистров
digitalWrite(latchPin, HIGH);
}