DS1307 даташит Dallas техническое описание радиодетали, 64 X 8 Serial Real Time Clock описание на русском, аналог, микросхема

Что такое часы реального времени?

Часы реально времени — это… часы. Модуль работает от автономного питания — батарейки и продолжает вести отсчет времени, даже если на вашем проекте на Arduino пропало питание. Используя модуль реального времени, вы можете отслеживать время, даже если вы захотите внести изменения в ваш скетч и перепрограммировать микроконтроллер.

На большинстве микроконтроллеров, в том числе и Arduino, есть встроенный счетчик временни, который называется millis(). Есть и встроенные в чип таймеры, которые могут отслеживать более длительные промежутки времени (минуты или дни). Так зачем же вам отдельным модуль часов? Основная проблема в том, что millis() отслеживает время только с момента подачи питания на Arduino. То есть, как только вы отключили плату, таймер сбрасывается в 0. Вша Arduino не знает, что сейчас, например, четверг или 8-е марта. Все, чего вы можете добиться от встроенного счетчика — это «Прошло 14000 миллисекунд с момента последнего включения».

Например вы создали программу и хотите вести отсчет времени с этого момента. Если вы отключите питание микроконтроллера, счетчик времени собьется. Примерно так, как это происходит с дешевыми китайскими часами: когда садится батарейка, они начинают мигать с показанием 12:00.

В некоторых проектах Arduino вам понадобится надежный контроль времени без прерываний. Именно в таких случаях используется внешний модуль часов реального времени. Чип, который используется в подобных часах, отслеживает года и даже знает сколько дней в месяце (единственно, что обычно не учитывается — это переход на летнее и зимнее время, так как подобные переводы разные в разных частях мира).

На рисунке ниже показана материнская плата компьютера с часами реального времени DS1387. В часах используется литиевая батарея, поэтому они разрослись в размерах.

Часы реального времени на компьютере

Мы рассмотрим пример использования часов реального времени DS1307. Это дешевый, легкий в использовании модуль, который работает несколько лет от небольшой батарейки.

Пока батарейка в самом модуле не исчерпает свой заряд, DS1307 будет вести отсчет времени, даже если Arduino отключен от питания или перепрограммируется.

Общие сведения

Использовании модуля DS1307 зачастую очень оправдано, например, когда данные считываются редко, интервалом более недели, использовать собственные ресурсы контроллера, неоправданно или невозможно. Обеспечивание бесперебойное питание, например платы Arduino, на длительный срок дорого, даже при использовании батареи.
Благодаря собственной памяти и автономностью, можно регистрировать события, (при автономном питании) например изменение температуры и так далее, данные сохраняются в памяти их можно считать из памяти модуля. Так что модуль DS1307 часто используют, когда контроллерам Arduino необходимо знать точное время, для запуска какого то события и так далее.

Обмен данными с другими устройствами осуществляется по интерфейсу I2C с выводов SCL и SDA. Конденсаторы С1 и С2 необходимы для снижения помех по линию питания. Чтобы обеспечить надлежащего уровня сигналов SCL и SDA установлены резисторы R2 и R3 (подтянуты к питанию). Для проверки работоспособности модуля, на вывод 7 микросхему DS1307Z, подается сигнал SQ, прямоугольной формы с частотой 1 Гц. Элементы R4, R5, R6, VD1 необходимы для подзарядку литиевой батарейки. Так же, на плате предусмотрено посадочное место (U1), для установки датчика температуры DS18B20 (при необходимости можно впаять его), считывать показания, можно с вывода DS, который подтянут к пиатнию, через резистор R1 сопротивлением 3.3 кОм. Принципиальную схему и назначение контактов можно посмотреть на рисунках ниже.

Принципиальная схема модуля DS1307 (RTC)

На плате расположено две группы контактов, шагом 2.54 мм, для удобного подключения к макетной плате, буду использовать штырьевые разъемы, их необходимо впаять.

Первая группа контактов:
► DS:     вывод DS18B20  (1-wire)
► SCL:   линия тактирования (Serial CLock)
► SDA:  линия данных (Serial Dфta)
► VCC:  «+» питание модуля
► GND: «-» питание модуля

Смотрите также:   Инженерные коммуникации: чем отличается FTP кабель от UTP

Вторая группа контактов:
► SQ:    вход 1 МГц
► DS:    вывод DS18B20  (1-wire)
► SCL:  линия тактирования (Serial CLock)
► SDA: линия данных (Serial Dфta)
► VCC: «+» питание модуля
► GND:«-» питание модуля
► BAT:

Подзарядка батареи
Как описывал ваше модуль может заряжать батарею, реализовано это, с помощью компонентов R4, R5, R6 и диода D1. Но, данная схема имеет недостаток, через резистор R4 и R6 происходит разряд батареи (как подметил пользователь ALEXEY, совсем не большой). Так как модуль потребляем незначительный ток, можно удалить цепь питания, для этого убираем R4, R5, R6 и VD1, вместо R6 поставим перемычку (после удаления компонентов, можно использовать обычную батарейку CR2032).

Назначение выводов

  • Vcc – источник питания +5 В
  • X1, X2 – подключение кварцевого резонатора 32.768 кГц
  • VBAT – вход батареи +3 В
  • GND – общий минус
  • SDA – последовательные данные
  • SCL – последовательные синхроимпульсы
  • SQW/OUT – выходной сигнал с прямоугольными импульсами

Модельный ряд

Серия: DS1307 (6)

  • DS1307+ DS1307N+ DS1307Z+ DS1307Z+T&R DS1307ZN+ DS1307ZN+T&R

Datasheet : DS1307

  • DS1307 64 X 8 Serial Real Time Clock
  • DS1307 Real-Time Clock

Программное обеспечение

В этом руководстве мы будем использовать два различных скетча: один, который записывает время и дату в RTC, и один, который считывает время и дату из RTC. Мы сделали так потому, что так вы сможете получить более полное представление о том, что происходит. Мы будем использовать одну и ту же схему для обеих программ.

Сперва мы запишем время и дату в RTC, что аналогично установке времени на часах.

Мы используем две кнопки. Одну для увеличения часов, минут, даты, месяца, года и дня недели, а вторую для выбора между ними. Приложение не считывает состояния каких-либо критически важных датчиков, поэтому мы будем использовать прерывания для проверки, нажата ли кнопка, и обработки дребезга контактов.

Следующий код устанавливает значения и записывает их в RTC:

  • // Включение заголовочных файлов
    #include
    #include
  • // Определение выводов LCD
    #define RS 9
    #define E 10
    #define D4 8
    #define D5 7
    #define D6 6
    #define D7 5

LiquidCrystal lcd(RS, E, D4, D5, D6, D7);

  • // Прерывание 0 – это вывод 4 микроконтроллера (цифровой вывод 2 Arduino)
    int btnSet = 0;
  • // Прерывание 1 – это вывод 5 микроконтроллера (цифровой вывод 3 Arduino)
    int btnSel = 1;
  • // Флаги прерываний
    volatile int togBtnSet = false;
    volatile int togBtnSel = false;

volatile int counterVal = 0;

  • // Переменные для отслеживания, где в «меню» мы находимся
    volatile int menuCounter = 0;
    // Массив значений
    volatile int menuValues[6]; // 0=часы, 1=минуты, 2=день месяца, 3=месяц, 4=год, 5=день недели
    // Заголовки меню
    char* menuTitles[6] =
    {
    «Set hour. «,
    «Set minute. «,
    «Set date. «,
    «Set month. «,
    «Set year. «,
    «Set day (1=mon).»
    };
  • // Массив дней недели
    char* days[] = { «NA», «Mon», «Tue», «Wed», «Thu», «Fre», «Sat», «Sun» };
  • void setup() {
    // Объявление прерываний, выполнение функций increaseValue/nextItem
    // по переднему фронту на btnXXX
    attachInterrupt(btnSet, increaseValue, RISING);
    attachInterrupt(btnSel, nextItem, RISING);
    Wire.begin();
    lcd.begin(16,2);
    showWelcome();
    }
  • // Функция прерывания
    void increaseValue()
    {
    // Переменные
    static unsigned long lastInterruptTime = 0;
    // Создание метки времени
    unsigned long interruptTime = millis();
  • // Если timestamp — lastInterruptTime больше, чем 200
    if (interruptTime — lastInterruptTime > 200)
    {
    togBtnSet = true;
    // Увеличить counterVal на 1
    counterVal++;
    }
    // Установка lastInterruptTime равным метке времени
    // так мы знаем, что прошли дальше
    lastInterruptTime = interruptTime;
    }
  • // Функция прерывания для следующего пункта меню
    void nextItem()
    {
    static unsigned long lastInterruptTime = 0;
    unsigned long interruptTime = millis();
  • if (interruptTime — lastInterruptTime > 200)
    {
    togBtnSel = true;
    // Увеличить счетчик меню, так мы переходим к следующему пункту меню
    menuCounter++;
    if (menuCounter > 6)
    menuCounter = 0;
    // Поместить counterVal в элемент массива счетчиков меню
    menuValues[menuCounter] = counterVal;
    // Сбросить counterVal, сейчас мы начинаем с 0 для следующего пункта меню
    counterVal = 0;
    }
    lastInterruptTime = interruptTime;
    }
  • // Функция преобразования десятичных чисел в двоично-десятичный код
    byte decToBCD(byte val)
    {
    return ((val/10*16) + (val%10));
    }
  • // Функция проверки, была ли нажата кнопки листания меню,
    // и обновления заголовка на дисплее.
    void checkCurrentMenuItem()
    {
    if (togBtnSel)
    {
    togBtnSel = false;
    lcd.setCursor(0,0);
    lcd.print(menuTitles[menuCounter]);
    }
    }
  • // Функция проверки, была ли нажата кнопка увеличения значения,
    // и обновления переменной в соответствующем элементе массива,
    // плюс вывод нового значения на дисплей.
    void checkAndUpdateValue()
    {
    // Проверить, если прерывание сработало = кнопка нажата
    if (togBtnSet)
    {
    // Обновить значение элемента массива с counterVal
    menuValues[menuCounter] = counterVal;
    // Сбросить флаг прерывания
    togBtnSet = false;
    lcd.setCursor(7,1);
    // Напечатать новое значение
    lcd.print(menuValues[menuCounter]);
    lcd.print(» «);
    }
    }
  • // Короткое приветственное сообщение, теперь мы знаем, что всё нормально
    void showWelcome()
    {
    lcd.setCursor(2,0);
    lcd.print(«Hello world.»);
    lcd.setCursor(3,1);
    lcd.print(«I’m alive.»);
    delay(500);
    lcd.clear();
    }
  • // Запись данных в RTC
    void writeRTC()
    {
    Wire.beginTransmission(0x68);
    Wire.write(0); // начальный адрес
    Wire.write(0x00); // секунды
    Wire.write(decToBCD(menuValues[1])); // преобразовать минуты в BCD-код и записать
    Wire.write(decToBCD(menuValues[0])); // преобразовать часы в BCD-код и записать
    Wire.write(decToBCD(menuValues[5])); // преобразовать день недели в BCD-код и записать
    Wire.write(decToBCD(menuValues[2])); // преобразовать день месяца в BCD-код и записать
    Wire.write(decToBCD(menuValues[3])); // преобразовать месяц в BCD-код и записать
    Wire.write(decToBCD(menuValues[4])); // преобразовать год в BCD-код и записать
    Wire.write(0b00010000); // включить прямоугольные импульсы 1 Гц на выводе 7
    Wire.endTransmission(); // закрыть передачу
    }
  • // Показать время
    // Чтобы посмотреть, что RTC работает, вам необходимо посмотреть другую программу
    void showTime()
    {
    lcd.setCursor(0,0);
    lcd.print(» «);
    lcd.print(menuValues[0]); lcd.print(«:»); // часы
    lcd.print(menuValues[1]); lcd.print(«:»); lcd.print(«00 «); // минуты
    lcd.setCursor(3,1);
    lcd.print(days[menuValues[5]]); lcd.print(» «); // день недели
    lcd.print(menuValues[2]); lcd.print(«.»); // дата
    lcd.print(menuValues[3]); lcd.print(«.»); // месяц
    lcd.print(menuValues[4]); lcd.print(» «); // год
    // вызов функции writeRTC
    writeRTC();
    }
  • void loop()
    {
    if (menuCounter < 6)
    {
    checkCurrentMenuItem();
    checkAndUpdateValue();
    }
    else
    {
    showTime();
    }
    }
Смотрите также:   Формула расчета сопротивления при параллельном соединении резистора

Эта программа начинается с короткого приветственного сообщения. Это сообщение говорит нам, что подано питание, LCD работает, и что программа запустилась. Так как скетч служит лишь для того, чтобы показать, как записать данные из Arduino в RTC DS1307, то в нем отсутствует вспомогательный функционал (проверка, попадают ли значения в допустимые диапазоны; зацикливание при нажимании на кнопку увеличения значения, то есть сброс на 0, когда значение, например, минут превысит 60, и т.д.)

  • // Включение заголовочных файлов
    #include
    #include
  • // Определение выводов LCD
    #define RS 9
    #define E 10
    #define D4 8
    #define D5 7
    #define D6 6
    #define D7 5

LiquidCrystal lcd(RS, E, D4, D5, D6, D7);

  • // Вывод, который будет принимать импульсы от RTC
    volatile int clockPin = 0;
  • // Переменные времени и даты
    byte second;
    byte minute;
    byte hour;
    byte day;
    byte date;
    byte month;
    byte year;
  • // Массив дней недели
    char* days[] = { «NA», «Mon», «Tue», «Wed», «Thu», «Fre», «Sat», «Sun» };
  • // Функция, которая выполняется только при запуске
    void setup() {
    pinMode(clockPin, INPUT); pinMode(clockPin, LOW);
    Wire.begin();
    lcd.begin(16,2);
    showWelcome();
    }
  • // Короткое приветственное сообщение, теперь мы знаем, что всё нормально
    void showWelcome()
    {
    lcd.setCursor(2,0);
    lcd.print(«Hello world.»);
    lcd.setCursor(3,1);
    lcd.print(«I’m alive.»);
    delay(500);
    lcd.clear();
    }
  • byte bcdToDec(byte val)
    {
    return ((val/16*10) + (val%16));
    }
  • // Это выполняется постоянно
    void loop()
    {
    // Если уровень на выводе clockPin высокий
    if (digitalRead(clockPin))
    {
  • // Начать передачу I2C, адрес 0x68
    Wire.beginTransmission(0x68);
  • // Начать с адреса 0
    Wire.write(0);
  • // Закрыть передачу
    Wire.endTransmission();
  • // Начать чтение 7 двоичных данных от 0x68
    Wire.requestFrom(0x68, 7);
    second = bcdToDec(Wire.read());
    minute = bcdToDec(Wire.read());
    hour = bcdToDec(Wire.read());
    day = bcdToDec(Wire.read());
    date = bcdToDec(Wire.read());
    month = bcdToDec(Wire.read());
    year = bcdToDec(Wire.read());
  • // Форматирование и отображение времени
    lcd.setCursor(4,0);
    if (hour < 10) lcd.print(«0»);
    lcd.print(hour); lcd.print(«:»);
    if (minute < 10) lcd.print(«0»);
    lcd.print(minute); lcd.print(«:»);
    if (second < 10) lcd.print(«0»);
    lcd.print(second);
    lcd.setCursor(2,1);
  • // Форматирование и отображение даты
    lcd.print(days[day]); lcd.print(» «);
    if (date < 10) lcd.print(«0»);
    lcd.print(date); lcd.print(«.»);
    if (month < 10) lcd.print(«0»);
    lcd.print(month); lcd.print(«.»);
    lcd.print(year);
    }
    }

Подключение DS1307 к Arduino

В статье рассмотрен пример часов реального времени от Adafruit, но вы можете с тем же успехом использовать китайские аналоги. Принцип работы и подключения не отличается.

Смотрите также:   О блокинг генераторе: принцип работы и устройство прибора

Ссылки для заказа оборудования, которое использовалось в проекте из Китая

  • КУПИТЬ Arduino Uno R3;
  • КУПИТЬ Breadboard;
  • КУПИТЬ модуль часов реального времени DS1307;

На часах реального премени 5 пинов: 5V, GND, SCL, SDA и SQW.

  • 5V используется для питания чипа модуля часов реального времени, когда вы делаете к нему запрос для получения данных о времени. Если сигнал 5 В не поступает, чип переходит в «спящий» режим.
  • GND — общая земля. Обязательно подключается в схему.
  • SCL — контакт i2c часов — необходим для обмена данными с часами реального времени.
  • SDA — контакт, по которому через i2c передаются данные с часов реального времени.
  • SQW дает возможность настроить вывод данных в виде square-wave. В большинстве случаев этот контакт не используется.

Подключение DS1307 к Arduino

Если вы настроили аналоговый пин 3 (цифровой 17) в режим OUTPUT и HIGH, а аналоговый пин 2 (цифровой 16) в режим OUTPUT и LOW, вы можете запитывать часы реального времени непосредственно от этих контактов!

Подключите аналоговый пин 4 на Arduino к SDA. Аналоговый пин 5 на Arduino подключите к SCL.

Подключение DS1307 к Arduino 2

Проверка RTC модуля

При запуске первого кода программа будет считывать данные с модуля раз в секунду. Сначала можно посмотреть, как поведет себя программа, если достать из модуля батарейку и заменить на другую, пока плата Ардуино не присоединена к компьютеру. Нужно подождать несколько секунд и вытащить батарею, в итоге часы перезагрузятся. Затем нужно выбрать пример в меню Examples→RTClib→ds1307. Важно правильно поставить скорость передачи на 57600 bps.

При открытии окна серийного монитора должны появиться следующие строки:

Arduino будильник

Будет показывать время 0:0:0. Это связано с тем, что в часах пропадает питание, и отсчет времени прекратится. По этой причине нельзя вытаскивать батарею во время работы модуля.

Чтобы провести настройку времени на модуле, нужно в скетче найти строку

RTC.adjust(DateTime(__DATE__, __TIME__));

В  этой строке будут находиться данные с компьютера, которые используются ля прошивки модуля часов реального времени. Для корректной работы нужно сначала проверить правильность даты и времени на компьютере, и только потом начинать прошивать модуль часов. После настройки в мониторе отобразятся следующие данные:

Arduino будильник

Настройка произведена корректно и дополнительно перенастраивать часы реального времени не придется.

Считывание времени. Как только модуль настроен, можно отправлять запросы на получение времени. Для этого используется функция now(), возвращающая объект DateTime, который содержит информацию о времени и дате. Существует ряд библиотек, которые используются для считывания времени. Например, RTC.year() и RTC.hour() – они отдельно получают информацию о годе и часе. При работе с ними может возникнуть проблема: например, запрос на вывод времени будет сделан в 1:19:59. Прежде чем показать время 1:20:00, часы выведут время 1:19:00, то есть, по сути, будет потеряна одна минута. Поэтому эти библиотеки целесообразно использовать в случаях, когда считывание происходит нечасто – раз в несколько дней. Существуют и другие функции для вызова времени, но  если нужно уменьшить или избежать погрешностей, лучше использовать now() и из нее уже вытаскивать необходимые показания.

Сравнение популярных модулей RTC DS1302, DS1307, DS3231

В этой таблице мы привели список наиболее популярных модулей и их основные характеристики.

Название Частота Точность Поддерживаемые протоколы
DS1307 1 Гц, 4.096 кГц, 8.192 кГц, 32.768 кГц Зависит от кварца – обычно значение достигает 2,5 секунды в сутки, добиться точности выше 1 секунды в сутки невозможно. Также точность зависит от температуры. I2C
DS1302 32.768 кГц 5 секунд в сутки I2C, SPI
DS3231 Два выхода – первый на 32.768 кГц, второй – программируемый от 1 Гц до 8.192 кГц ±2 ppm при температурах от 0С до 40С.

±3,5 ppm при температурах от -40С до 85С.

Точность измерения температуры – ±3С

I2C
Источники

  • https://arduino-diy.com/arduino-chasy-realnogo-vremeni-DS1307
  • https://robotchip.ru/obzor-chasov-realnogo-vremeni-ds1307/
  • https://arduinka.pro/blog/podklyuchenie/rtc-ds1307/
  • https://www.rlocman.ru/datasheet/data.html?di=41288&/DS1307
  • https://datasheet-pdf.com/PDF/DS1307-Datasheet-Maxim-925278
  • https://radioprog.ru/post/126
  • https://ArduinoMaster.ru/datchiki-arduino/arduino-chasy-rtc-ds1307-ds1302-ds3231/

Помогла ли вам статья?

Рейтинг
( Пока оценок нет )
Библиотека радиолюбителя
Adblock
detector