Моя записная книжка: Библиотека DS1307. Русское описание DS1307 Ds1307 схема включения

Здравствуйте!
Сегодня я хочу Вам поведать о такой интересной микросхеме как DS1307. Это чудные часики плюс календарь и самое замечательное что к этой микрухе есть библа в CVAVR. Да и просто она мне под руку попалась и я решил ее помучить 8) Первым делом нам понадобится схема ее подключения. Она довольно проста и была взята из даташита. Но тут есть небольшое исключение. В даташите требуют подключить резистор между ножкой питания и ножкой вывода прямоугольных импульсов. Так как я делал отдельную плату, дабы иметь возможность на ней тестировать дальнейшие проекты, приляпал еще светодиод. Очень удобно получилось. Видно например секундные импульсы.
Собственно схема.

А вот как это выглядит в сборе.

Испытания я проводил в связке ATmega32 + LCD 16x2 + DS1307. Далее есть два варианта. Первый, можно сгенерить код прям генератором CVAVR. Второй, самому все написать. Я предлагаю писать самому, но сначала давайте пройдемся по функциям DS1307.
1. rtc_init(rs, sqwe, out) Эта самая первая функция для инициализации микросхемы. Теперь все аргументы по порядку. rs нужен для того чтобы задать частоту выходных прямоугольных импульсов на ноге SQW/OUT . 0 - 1 Гц 1 - 4096 Гц 2 - 8192 Гц 3 - 32768 Гц sqwe нужен для разрешения выхода прямоугольных импульсов. 1 - можно 0 - нет. out нужен для определения логического уровня на выходной ноге если нет разрешения на вывод прямоугольных импульсов. Во загнул. Короче если не нужно дергать ногой SQW/OUT , то параметр sqwe ставим в 0 и теперь если out равен 1 , то и на ножке будет 1 , а если запишем 0 , то и на ноге тоже 0 . Пример: rtc_init(0,1,0); Это значит включить вывод прямоугольных импульсов с частотой 1 Гц. 2. rtc_set_time(hour, min, sec) Ну из названия видно что эта функция устанавливает время. Тут все просто, аргументы часы, минуты и секунды. 3. rtc_set_date(day, month, year) Та же шляпа но с датой. 4. rtc_get_time(&hour, &min, &sec) А вот тут по подробнее. Эта функция нужна для получения текущего времени. Аргументы функции являются адреса переменных куда она потом запишет значения. Это сделано из-за того что функции могут возвращать лишь один параметр (такой вот С). То есть перед вызовом функции нужно проинициализировать три беззнаковые переменные char. 5. rtc_get_date(&day, &month, &year) То же самое но с датой. Теперь все то же на примерах. rtc_set_time(15, 0, 0); Установили время 15:00:00 rtc_set_date(14, 2, 14); Установили дату 14 февраля 2014 г. Заметьте что год пишется двумя числами. Кусок даташита: Real-Time Clock (RTC) Counts Seconds, Minutes, Hours, Date of the Month, Month, Day of the week, and Year with Leap-Year Compensation Valid Up to 2100 До 2100 года, а так как у нас в функцию передается unsigned char, то значение может приниматься от 0 до 255. Я не пробовал загонять больше ста, но записанный с перепугу 2014 год отображался как 144 8) unsigned char hour, min, sec; rtc_get_time(&hour, &min, &sec); Сначала инициализируем переменные, а после вызываем функцию. После ее вызова можно смело оперировать временем которое запишется в переменные. unsigned char day, month, year; rtc_get_date(&day, &month, &year); В принципе тут тоже самое только в переменных будет лежать дата. Ну и наконец вся программа с коментами как и обещал. /***************************************************** Программа для работы с часами реального времени DS1307 Микроконтроллер: ATmega32 Частота кварца: 3,686400 MHz *****************************************************/ #include // Указываем порт и пины для шины I2C #asm .equ __i2c_port=0x1B ;PORTA .equ __sda_bit=0 .equ __scl_bit=1 #endasm #include // Подключаем библиотеку для работы с DS1307 #include // Указываем к какому порту подключен ЖКИ #asm .equ __lcd_port=0x12 ;PORTD #endasm // Подключаем библиотеку для работы с ЖКИ #include // Подключаем библиотеку для работы со строками #include void main(void) { // Инициализация массива для строки и переменные для данных unsigned char string; unsigned char c, m, s, d, me, g; PORTA=0x00; DDRA=0x00; PORTB=0x00; DDRB=0x00; PORTC=0x00; DDRC=0x00; PORTD=0x00; DDRD=0x00; // Инициализация шины I2C i2c_init(); // Инициализация DS1307 rtc_init(0,1,0); // Инициализация дисплея lcd_init(16); // Эти функции я использовал один раз для установки времени и даты. // rtc_set_time(16, 0, 0); // rtc_set_date(13, 2, 14); while (1) { // Получили время rtc_get_time(&c, &m, &s); lcd_gotoxy(0,0); // Отформатировали sprintf(string, "Время %02i:%02i:%02i ", c, m, s); // Вывели время lcd_puts(string); // Получили дату rtc_get_date(&d, &me, &g); lcd_gotoxy(0,1); // Отформатировали sprintf(string, "Дата %02i.%02i.20%2i ", d, me, g); // Вывели дату lcd_puts(string); }; } Ну вроде как и все. Для старта я думаю понятно, а там кому как. Вот как это выглядит в работе.



Роман 29.10.15 21:30

Спасибо за статью, все понятно и без воды.

Алексей 29.10.15 22:47

Стараюсь)

Женя 07.11.15 09:33

Алексей спасибо большое!

Алексей 07.11.15 10:23

Пожалуйста.

Петр 05.04.16 00:11

А в проге flowcode реально это повторить?

Алексей 05.04.16 08:52

А что это за программа?

Михаил 09.09.16 00:18
Алексей 09.09.16 12:16
Сергей 20.11.16 12:28

Спасибо за подробное объяснение примеров. Не могли бы Вы дополнить пример ручной установки времени в RTC? Иногда корректировка времени все таки нужна.

Алексей 20.11.16 15:33

Для полноценной работы с часами реального времени DS1307 и DS3231 мной написаны функции которые входят в библиотеку . Рекомендую использовать для боле упрощенной генерации проекта под Atmel Studio. Так же можно посмотреть видео о использовании данной библиотеки.

Вениамин 10.12.16 23:33

Rtc_set_date(13, 2, 14);
На такую запись компилятор может ругаться "too few arguments" так как должно передаваться 4 аргумента, первый из которых - день недели. Поэтому передавать нужно 4 числа, и забирать - тоже 4. Насколько мне известно в некоторых версиях codevision прокатывает с тремя, но я лично порядком повозился, пока выяснил почему у меня время спокойно пишется и читается, а дата - нет.

Алексей 11.12.16 00:00

Вот поэтому я забил на CVAVR с ее косяками (а они не только в часах), перешел на AtmelStudio и написал библиотеку под нее а-пя CVAVR. Теперь у меня все работает и не глючит.)))

АНОНИМ 02.03.17 00:39

Всем советую заменять Ds1307 на 3231 т.к 32я намного точней, а 1307 только для таймеров подходит.

АНТОНИМ 03.04.17 15:18

Намного точней - это на сколько именно? ИМХО точность часов определяется на 99,9999999 % точностью кварцевого резонатора.

Алексей 03.04.17 16:09

Ну не совсем. Человек наверное просто имел в виду термокомпенсацию, так как частота кварца зависит еще и от температуры.

ИгорьКазанце 31.07.19 16:54

Ситуация: Купил микруху DS1307. Спаял Вашу схему. Нужна единственная функция - выход секундных импульсов. Больше ничего не нужно. Что делать? Какой использовать программатор? [email protected]

Алексей 01.08.19 10:50

Программатор не нужен. Нужно написать программу под любой МК который передаст команду для задания частоты выходной ножки SQW/OUT. Далее пока есть напряжение на микросхеме, на выходе будет меандр в 1ГЦ.

Во многих конструкциях полезно знать текущее время, но не всегда есть возможность, да и если контроллер будет сильно загружен, то часы будут постоянно отставать или спешить, что не очень хорошо. Выходом может стать внешний готовый источник времени – часы реального времени — DS1307.

Часы состоят из микросхемы DS1307, кварца на 32,768Кгц, батарейки и 2-х подтягивающих резисторов на линии SDA и SLC. Благодаря батарейке они продолжают идти при отключении внешнего питания. Также у DS1307 есть свободные 56 байтов энергозависимой статической ОЗУ, которые можно использовать в своих целях.

Линии SCL и SDA – это I2C. На линии SQW – находиться тактовый импульс с частотой от 1 Гц до 32,768 Кгц, обычно она не используется.

У часов есть пара особенностей:

1. что бы они работали, в них должна быть батарейка или на крайний случай резистор на 4-10кОм, иначе они не будут работать и отвечать всяким мусором.
2. вокруг дорожек кварца должен быт замкнутый контур земли и корпус кварц тоже лучше подключить к земле

Немного теории

Хронометр имеет фиксированный адрес 68h, в 7 битовом адресе + 1 бит указывает на действие – чтение/запись.
Для записи используется следующий алгоритм:
Первый байт – адрес часов 68h + 0 бит указывающий на запись, итого D0h. После получения подтверждения передаётся адрес регистра. Это установит регистровый указатель. Затем начинается передача байтов данных, чтобы остановить его – генерируется условие окончания.
Для чтения:
Первый байт – адрес часов 68h + 1 бит указывающий на запись, итого D1h. После декодирования адреса и выдачи подтверждения устройство начинает передавать данные с указанного адреса (храниться в регистре указателя). Если перед началом чтения указатель регистра не записан, то первый читаемый адрес — это адрес, который был сохранён в нём последним. DS1307 должен принять «неподтверждение» для окончания чтения.

Для включения часов следует установить бит CH в ноль, это следует сделать принудительно, т.к. часы после включения по умолчанию выключены.

Часы хранят информацию в двоично-десятичном виде – для получения данных достаточно прочитать соответствующий им регистр.

DS1307 может работать как в 24, так и в 12 часовом режиме – за это отвечает бит 12/24 (02h 6 бит). При 24 часовом режиме 5 и 4 биты регистра 02h соответствуют текущему десятку часа, при 12 часовом режиме 4 бит хранит десяток, а 5 признак до полудня / после полудня.

7 регистр отвечает за выходной тактовый генератор часов, SQW вывод. Бит OUT инвертирует выходной сигнал, бит SQWE включает тактовый генеретор, а биты RS0 и RS1 устанавливают частоту тактового импульса.

Практика

Был изготовлен небольшой модуль часов реального времени. На макетке были собраны часы с использованием микроконтроллера PIC16F628A, знакогенерирующего дисплея 2×16, одной кнопки для задания времени, модуля часов реального времени и с небольшим количеством обвязки.

Плата содержит микросхему DS1307 в SMD исполнении. К ней подпаян кварц на 32,768 КГц, в корпусе DT-38, вокруг кварца должно быть кольцо земли и корпус самого кварц тоже стоит подключить к земле, для этого рядом с ним предусмотрено специальное отверстие. Для работы часов в автономном режиме предусмотрена батарейка на 3В CR120. Также для индикации работы модуля можно установить SMD светодиод с резистором на 470 Ом в корпусе типоразмера 0805.

PIC16F628A не содержит аппаратного I2C, поэтому он был реализован программно. Программный I2C был написан с нуля, он немного отличается от стандартного протокола, тем, что не ждёт подтверждения от слейва. Программный I2C будет рассмотрен в одной из следующих статей. На основе функций работы с I2C были реализованы следующие функции управления DS1307:

Void ds_write(unsigned char addr,unsigned char data) { i2c_start(); i2c_write(0xD0); i2c_write(addr); i2c_write(data); i2c_stop(); } unsigned char ds_read(unsigned char addr) { unsigned temp; i2c_start(); i2c_write(0xD0); i2c_write(addr); i2c_stop(); i2c_start(); i2c_write(0xD1); temp=i2c_read(0); i2c_stop(); return temp; } void ds_off() { ds_write(0x00,ds_read(0x00)|0x80); } void ds_on() { ds_write(0x00,ds_read(0x00)&~0x80); } void ds_init() { unsigned char i; // устанавливаем режим 24 часа i=ds_read(0x02); if((i&0x40)!=0) { ds_write(0x02,i&~0x40); } // Если часы выключены - то включаем их i=ds_read(0x00); if((i&0x80)!=0) { ds_write(0x00,i&~0x80); } } unsigned char IntToBoolInt(unsigned char data) { data=data%100; return data/10*16+data%10; }

ds_write(адрес, байт данных) — отправляет 1 байт данных по указанному адресу DS1307
байт данных ds_read(адрес) — считывает 1 байт данных из указанного адреса DS1307
ds_off() — выключить DS1307
ds_on() — включить DS1307
ds_init() — инициализация DS1307
байт IntToBoolInt(байт) — функция перекодировки числа в двоично-десятичный вид

Во время инициализации проверяются и устанавливаются, если выключены следующие биты: бит отвечающий за 24-х часовой режим работы часов и бит отвечающий за включенное состояние часов. Были реализованы 2 функции для включения и отключения часов. DS1307 может отправлять и принимать как однобайтовые посылки, так и много байтовые, но для упрощения работы с часами функции для чтения и записи только однобайтовые. Для установки часов есть ещё функция для преобразования привычной десятичной формы представления числа в двоично-десятичную, в которой микросхема хранит показатели времени. Приведённых функция для работы с часами вполне достаточно.

В прошивки реализованы функции для считывания и вывода на дисплей времени – time() , даты – date() . В бесконечном цикле через некоторые промежутки времени эти функции вызываются для вывода времени и даты на дисплей. Рассмотрим, как устроена функция для чтения с последующим выводом текущего времени:

Void time() { unsigned char i; SetLCDPosition(1, 0); i=ds_read(0x02); buffer = i/16+"0"; buffer = i%16+"0"; buffer = ":"; i=ds_read(0x01); buffer = i/16+"0"; buffer = i%16+"0"; buffer = ":"; i=ds_read(0x00); buffer = i/16+"0"; buffer = i%16+"0"; buffer = "\0"; ShowStr(buffer); }

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

В прошивки есть функция для установки часов и минут – set_time() . Эта функция с помощью одной кнопки устанавливает время. Как это делается: нажимаем на кнопку – на дисплее высвечивается надпись «Set hour:» и количество часов, увеличиваем час по средством коротких нажатий на кнопку; установив час длительным нажатием переходим на установку минут, о чём свидетельствует надпись «Set min:», таким же образом устанавливаем минуты, а длительным нажатием возвращаемся в бесконечный цикл к часам. Но т.к. эта функция большая приведём из неё только одну строчку, которая записывает в DS1307 значение минут:

Ds_write(0x02,IntToBoolInt(time));

Записываем в регистр, который соответствует минутам желаемое значение, предварительно приведённое к двоично-десятичному виду.

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

С помощью этого модуля можно отслеживать время в ваших проектах на Arduino даже в случае перепрограммирования или отключения питания. Это один из необходимых элементов для проектов будильников, сигнализаций, снятия показаний с датчиков в режиме реального времени. Одна из самых популярных моделей модуля часов реального времени - DS1307. Именно на нем мы и остановимся. Модуль отлично сочетается с микроконтроллерами Arduino, на которых питание логики равно 5 В.

Особенности модуля от компании-производителя Adafruit (китайцы предлагают аналогичные варианты раза в три-четыре дешевле):

  • Все включено: чип, обвязка, батарейка;
  • Легко собирается и прост в использовании;
  • Устанавливается на любую макетную плату или подключается напрямую с помощью проводов;
  • Есть отличные библиотеки и скетчи-примеры;
  • Два отверстия для монтажа;
  • Продолжительность работы - около пяти лет!

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

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

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

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

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

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

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

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

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

Узлы, из которых состоит модуль часов реального времени

Детали модуля часов реального времени DS1307 от компании Adafruit
Рисунок Обозначение Описание Производитель Количество
IC2 Чип часов реального времени DS1307 1
Q1 32.768 КГц, 12.5 пФ кристалл Generic 1
R1, R2 1/4 Вт 5% 2.2 КОм резистор Красный, Красный, Красный, Золотой Generic 2
C1 0.1 мкФ керамический конденсатор Generic 1
Рельса на 5 контактов (1x5) Generic 1
Батарейка 12 мм 3 В литиевая батарейка CR1220 1
12mm coin cell holder Keystone 3001 1
Плата Adafruit Industries 1

Сборка модуля часов реального времени

Сборка часов реального времени DS1307 компании Adafruit
Фото Пояснения

Подготовьтесь к сборке. Проверьте наличие всех необходимых деталей и инструментов. Установите монтажную плату в тисках.

Нанесите немного припоя на отрицательный контакт батареи.

Установите два резистора 2.2 КОм и керамический конденсатор. Как именно вы их расположите - неважно. Полярность не имеет значения. После этого установите кристалл (также симметрично), держатель (холдер) для батарейки и чип часов реального времени. Чип модуля реального времени надо установить таким образом, чтобы отметка (паз) на чипе располагалась в соответствии с обозначением на монтажной плате. Внимательно посмотрите на фото слева, там чип установлен верно.


Чтобы холдер для батарейки не выпадал, лучше его припаять сверху. После этого переверните плату и и припаяйте оставшиеся контакты.

Удалите остатки контактов от резисторов, кристалла и конденсатора.

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

Установите батарейку. Плоская часть батареи должна быть сверху. В среднем батарейка будет служить около 5 лет. Даже если батарейка села, не оставляйте слот для нее пустым.

Библиотека Arduino для работы с DS1307

DS1307 легко подключается к любому микроконтроллеру с питанием логики 5 В и возможностью I2C подключения. Мы рассмотрим подключение и использование этого модуля с Arduino .

Будем использовать библиотеку RTClib для получения и настройки показаний с DS1307. Если у вас есть вопросы по учтановке дополнительных библиотек Arduino - ознакомьтесь с этой инструкцией .

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

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

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

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

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

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


Скетч для Arduino

Проверка часов реального времени

Первый скетч, который стоит запустить - это программа, которая будет считывать данные с модуля часов реального времени раз в секунду.

Для начала давайте посмотрим, что произойдет, если мы извлечем батарейку и заменим ее на другую, пока Arduino не подключен к USB. Подождите 3 секунды и извлеките батарейку. В результате чип на часах реального времени перезагрузится. После этого вставьте код, который приведен ниже (код также можно выгрузить в меню Examples→RTClib→ds1307 в Arduino IDE) и загрузите его на Arduino.

Вам также понадобится библиотека OneWire.h, скачть ее можно

.

// функции даты и времени с использованием часов реального времени DS1307, подключенные по I2C. В скетче используется библиотека Wire lib

#include <Wire.h>

#include "RTClib.h"

Serial.begin(57600);

if (! RTC.isrunning()) {

Serial.println("RTC is NOT running!");

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

DateTime now = RTC.now();

Serial.print("/");

Serial.print("/");

Serial.print(now.day(), DEC);

Serial.print(" ");

Serial.print(":");

Serial.print(":");

Serial.println();

Serial.print(now.unixtime());

Serial.print("s = ");

Serial.println("d");

// рассчитываем дату: 7 дней и 30 секунд

DateTime future (now.unixtime() + 7 * 86400L + 30);

Serial.print(" now + 7d + 30s: ");

Serial.print(future.year(), DEC);

Serial.print("/");

Serial.print(future.month(), DEC);

Serial.print("/");

Serial.print(future.day(), DEC);

Serial.print(" ");

Serial.print(future.hour(), DEC);

Serial.print(":");

Serial.print(future.minute(), DEC);

Serial.print(":");

Serial.print(future.second(), DEC);

Serial.println();

Serial.println();

Теперь откройте окно серийного монитора и убедитесь, что скорость передачи данных установлена корректно: на 57600 bps.

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


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

Настройка времени на модуле часов

В этом же скетче раскомментируйте строку, которая начинается с RTC.adjust:

// строка ниже используется для настройки даты и времени часов

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

Процесс настройки даты и времени реализован очень элегантно. В эту строку попадают данные с вашего счетчика на персональном компьютере (в момент компилляции кода). Эти данные используются для прошивки вашего модуля часов реального времени. То есть, если время на вашем ПК настроено неверно, рекомендуем сначала исправить этот баг, а потом переходить к прошивке модуля часов для Arduino.

После настройки, откройте серийный монитор и убедитесь, что часы настроены корректно:


Все. С этого момента и на протяжении ближайших нескольких лет настраивать DS1307 не придется.

Считывание показаний времени с DS1307

После настройки часов реального времени DS1307, может отправлять к ним запросы. Давайте рассмотрим часть скетча, в которой реализованы эти запросы.

DateTime now = RTC.now();

Serial.print(now.year(), DEC);

Serial.print("/");

Serial.print(now.month(), DEC);

Serial.print("/");

Serial.print(now.day(), DEC);

Serial.print(" ");

Serial.print(now.hour(), DEC);

Serial.print(":");

Serial.print(now.minute(), DEC);

Serial.print(":");

Serial.print(now.second(), DEC);

Serial.println();

По сути существует один вариант для получения времени с использованием часов реального времени. Для этого используется функция now(), которая возвращает объект DateTime. В этом объекте содержаться данные про год, месяц, день, час, минуту и секунду.

Есть ряд библиотек для часов реального времени, в которых предусмотрены функции вроде RTC.year() и RTC.hour(). Эти функции вытягивают отдельно год и час. Но их использование сопряжено с рядом проблем: если вы сделаете запрос на вывод минут в момент времени, например, 3:14:59, то есть, прямо перед тем как показания минут должны приравняться к "15" (3:15:00), полученные данные будут равны 3:14:00 - то есть, вы потеряете одну минуту.

В общем, использование отдельных функций для вызова часа или года обосновано только в том случае, когда точность контроля времени с разбросом в одну минуту/года для вашего проекта не критична (как правило, это в тех случаях, когда показания снимаются редко - раз в сутки, раз в неделю). В любом случае, если вы хотите избежать погрешностей в показаниях, используйте now(), а уже из полученных данных тяните необходимые вам показания (минуты, года и т.п.).

Есть еще один формат данных, которые мы можем подучить - количество секунд от полуночи, 1-го января 1970 года. Для этого используется функция unixtime ():

Serial.print(" since 1970 = ");

Serial.print(now.unixtime());

Serial.print("s = ");

Serial.print(now.unixtime() / 86400L);

Serial.println("d");

Так как в одном дне 60*60*24 = 86400 секунд, можно перевести полученное значение в дни и года. Очень удобный вариант, если вам надо отследить, сколько времени прошло с момента последнего запроса. Например, если прошло 5 минут с момента последнего последнего обращения Arduino к часам реального времени DS1307, значение, которое вернет функция unixtime() будет больше на 300.

Оставляйте Ваши комментарии, вопросы и делитесь личным опытом ниже. В дискуссии часто рождаются новые идеи и проекты!

DS1307 это небольшой модуль, предназначенный для подсчета времени. Собранный на базе микросхемы DS1307ZN с реализацией питания от литиевой батарейки (LIR2032), что позволяет работать автономно в течение длительного времени. Также на модуле, установлена энергонезависимая память EEPROM объемом 32 Кбайт (AT24C32). Микросхема AT24C32 и DS1307ZN связаны обшей шиной интерфейсом I2C.

Технические параметры

Напряжение питания: 5В
Рабочая температура: – 40℃ … + 85℃
Память: 56 байт (энергонезависимая)
Батарейка: LIR2032 (автоматическое определение источника питания)
Интерфейса: I2C
Габариты: 28мм х 25мм х 8 мм

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

Использовании модуля 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 кОм. Принципиальную схему и назначение контактов можно посмотреть на рисунках ниже.

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

Первая группа контактов:
DS: вывод DS18B20 (1-wire)


VCC: «+» питание модуля
GND: «-» питание модуля

Вторая группа контактов:
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).

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

Необходимые детали:
Arduino UNO R3 x 1 шт.
Провод DuPont, 2,54 мм, 20 см x 1 шт.
Кабель USB 2.0 A-B x 1 шт.
Часы реального времени RTC DS1307 x 1 шт.

Подключение:
Для подключения часы реального времени DS1307, необходимо впаять впаять штыревые разъемы в первую группу контактов. Далее, подключаем провода SCL (DS1307) к выводу 4 (Arduino UNO) и SDA (DS1307) к выводу 5 (Arduino UNO), осталось подключить питания VCC к +5V и GND к GND. Кстати, в различных платах Arduino вывода интерфейса I2C отличаются, назначение каждого можно посмотреть ниже.

Установка времени DS1307
Первым делом, необходимо скачать и установить библиотеку «DS1307RTC» и «TimeLib» в среду разработки IDE Arduino, далее необходимо настроить время, открываем пример из библиотеки DS1307RTC «Файл» —> «Примеры» —> «DS1307RTC» —> «SetTime» или копируем код снизу.

// Подключаем библиотеку DS1307RTC const char *monthName = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; tmElements_t tm; void setup() { bool parse=false; bool config=false; // get the date and time the compiler was run if (getDate(__DATE__) && getTime(__TIME__)) { parse = true; // and configure the RTC with this info if (RTC.write(tm)) { config = true; } } Serial.begin(9600); while (!Serial) ; // wait for Arduino Serial Monitor delay(200); if (parse && config) { Serial.print("DS1307 configured Time="); Serial.print(__TIME__); Serial.print(", Date="); Serial.println(__DATE__); } else if (parse) { Serial.println("DS1307 Communication Error:-{"); Serial.println("Please check your circuitry"); } else { Serial.print("Could not parse info from the compiler, Time=\""); Serial.print(__TIME__); Serial.print("\", Date=\""); Serial.print(__DATE__); Serial.println("\""); } } void loop() { } bool getTime(const char *str) { int Hour, Min, Sec; if (sscanf(str, "%d:%d:%d", &Hour, &Min, &Sec) != 3) return false; tm.Hour = Hour; tm.Minute = Min; tm.Second = Sec; return true; } bool getDate(const char *str) { char Month; int Day, Year; uint8_t monthIndex; if (sscanf(str, "%s %d %d", Month, &Day, &Year) != 3) return false; for (monthIndex = 0; monthIndex < 12; monthIndex++) { if (strcmp(Month, monthName) == 0) break; } if (monthIndex >= 12) return false; tm.Day = Day; tm.Month = monthIndex + 1; tm.Year = CalendarYrToTm(Year); return true; }

Скачать скетч

Загружаем данную скетч в контроллер Arduino (время берется с ОС), открываем «Мониторинг порта»

Программа
В библиотеке есть еще один пример, открыть его можно DS1307RTC «Файл» —> «Примеры» —> «DS1307RTC» —> «ReadTest»

/* Тестирование производилось на Arduino IDE 1.6.12 Дата тестирования 23.11.2016г. */ #include // Подключаем библиотеку Wire #include // Подключаем библиотеку TimeLib #include // Подключаем библиотеку DS1307RTC void setup() { Serial.begin(9600); // Устанавливаем скорость передачи данных while (!Serial) ; // Ожидаем подключение последовательного порта. Нужно только для Leonardo delay(200); // Ждем 200 мкс Serial.println("DS1307RTC Read Test"); // Выводим данные на последовательный порт Serial.println("-------------------"); // Выводим данные на последовательный порт } void loop() { tmElements_t tm; if (RTC.read(tm)) { Serial.print("Ok, Time = "); print2digits(tm.Hour); Serial.write(":"); print2digits(tm.Minute); Serial.write(":"); print2digits(tm.Second); Serial.print(", Date (D/M/Y) = "); Serial.print(tm.Day); Serial.write("/"); Serial.print(tm.Month); Serial.write("/"); Serial.print(tmYearToCalendar(tm.Year)); Serial.println(); } else { if (RTC.chipPresent()) { Serial.println("The DS1307 is stopped. Please run the SetTime"); Serial.println("example to initialize the time and begin running."); Serial.println(); } else { Serial.println("DS1307 read error! Please check the circuitry."); Serial.println(); } delay(9000); } delay(1000); } void print2digits(int number) { if (number >= 0 && number < 10) { Serial.write("0"); } Serial.print(number); }

Скачать скетч

Загружаем данную код в контроллер Arduino, открываем «Мониторинг порта»

Отзывы об этих часах в интернете самые противоречивые. Кто-то говорит что часы замечательные, а кто-то называет их убогой поделкой Далласа. И вот я, дабы развеять все недостоверные слухи, достал микруху из загашника начала экспериментировать.

Особенности:

  • Очень маленькое энергопотребление. Производитель обещает 10 лет работы часов от одной стандартной батарейки CR2032
  • 56 байт памяти для хранения пользовательских данных. Думаю не особо нужная опция, но может кому-то и пригодится.
  • Программируемый вывод для тактирования внешних устройств. Может выдавать 1 Гц, 4.096 кГц, 8.192 кГц и 32.768 кГц.
  • 24-х часовой и 12-ти часовой режим

Распиновка

Выводы часов расположены следующим образом:

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

Подключение к контроллеру
Обвязка минимальна. Потребуется кварц 32.768 кГц, пара резисторов для работы шины i2c и батарейка на три вольта.

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

Кстати может работать и без кварца. Для этого на ногу X1 подают внешний тактовый сигнал с частотой 32.768 кГц, а X2 остаётся висеть в воздухе.

Организация памяти часов
Данная микруха наделена 64 байтами памяти. Первые восемь байт — рабочие. В них хранится время, дата, день недели. Остальные выделены под нужды пользователя. В них можно хранить например какие-нибудь настройки или еще что-нибудь. Естественно, когда резервное питание пропадает, вся информация в этой памяти разрушается. Вся работа с часами (чтение и установка времени/даты) сводится к тому, чтобы читать и записывать нужные ячейки памяти.

Все числа в памяти хранятся в двоично-десятичном формате. Это значит что в одном байте может хранится сразу две цифры. Например число 0x23 — содержит в себе цифру 2 и цифру 3. На каждую цифру выделяется по 4 бита. Зачем так сделано? Для удобства и экономии памяти. Кроме времени и даты в памяти хранятся несколько бит настроек:

  • Clock Halt — управляет часами. Когда бит установлен то часы стоят. Чтобы запустить ход часов необходимо записать в этот бит 0. После подключения батареи резервного питания, этот бит уставлен и часы не считают время! Об этом нужно помнить.
  • 24/12 — этот бит выбора режима часов. Когда этот бит равен единице то используется 12-ти часовой режим. В противном случае 24-х часовой. Если используется 12-ти часовой режим то пятый бит показывает AM или PM сейчас. Если бит равен 1 то значит PM. В 24-х часовом режиме этот бит используется для хранения десятков часов совместно с битом 4.
  • Output — управляет состоянием ноги SQW/OUT. Бит установлен — на ноге лог 1. Сброшен — на ноге 0. Для управления таким образом, бит SQWE должен быть сброшен.
  • SQWE — когда бит установлен, на ноге SQW/OUT появляются прямоугольные импульсы.
  • RS1, RS0 — этими битами задается частота импульсов. Зависимость частоты от комбинации бит находится в таблице ниже:

Софт

Для работы с часами DS1307 была написана нехитрая библиотека содержащая следующие базовые функции:

DS_start — запускает часы. Запустить часы можно так же установив время.
DS_stop — останавливает часы
DS_set_time — Установка времени. Перед вызовом процедуры нужно поместить в tmp1 — секунды в tmp2 — минуты и в tmp3-часы. Часы в 24-х часовом формате.
DS_get_time: — считывание времени из часов. секунды будут записаны в tmp1, минуты в tmp2, часы в tmp3
DS_get_date: — считывание даты из часов. День будет записан в tmp1, месяц в tmp2, год в tmp3
DS_set_date: — установка даты. Перед вызовом процедуры нужно поместить в tmp1 — день в tmp2 — месяц и в tmp3-год (последние 2 цифры)

Процедуры установки/чтения времени и даты могут воспринимать/возвращать входные данные в двоично-десятичном формате и в десятичном. Для выбора желаемого формата нужно закомментировать или раскомментировать по три строчки в каждой процедуре (в коде есть примечания по этому поводу).

Тестовая программа позволяет управлять часами через UART (скорость 9600, контроллер работает на частоте 8 мГц). При запуске сразу выдаются время, дата и приглашение ввести команду от 1 до 3. При выборе варианта 1 происходит повторное считывание времени/даты. Вариант 2 позволяет установить время, а вариант 3 дату. Если хочется попробовать поиграть с часами в то в архив с исходником включён файл для симуляции.

Точность
Тут очень многое зависит от применяемого кварца и разводки платы. Даташит сообщает что емкость кварца должна быть 12.5 пф. Говорят, что лучше всего применять кварцы от материнских плат. Для коррекции хода можно подпаять к резонатору подстроечный конденсатором и при помощи него в небольших пределах менять частоту. Лично у меня эти часы работают вторые сутки и отстали на 3 секунды. Что-то мне подсказывает, что дело в ёмкости кварца, попробую другой отпишусь.

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