Ds3231 arduino подключение

Введение

Как микроконтроллеры отслеживают время и дату? Обычный микроконтроллер обладает функцией таймера, который стартует от нуля при подаче напряжения питания, а затем начинает считать. В мире Arduino мы можем использовать функцию , чтобы узнать, сколько прошло миллисекунд с того времени, когда было подано напряжение питания. Когда вы снимете и снова подадите питания, она начнет отсчет с самого начала. Это не очень удобно, когда дело доходит до работы с часами и датами.

Вот здесь и будет удобно использование микросхемы RTC (Real Time Clock, часов реального времени). Эта микросхема с батарейкой 3В или каким-либо другим источником питания следит за временем и датой. Часы/календарь обеспечивают информацию о секундах, минутах, часах, дне недели, дате, месяце и годе. Микросхема корректно работает с месяцами продолжительностью 30/31 день и с високосными годами. Связь осуществляется через шину I2C (шина I2C в данной статье не обсуждается).

Если напряжение на главной шине питания Vcc падает ниже напряжения на батарее Vbat, RTC автоматически переключается в режим низкого энергопотребления от резервной батареи. Резервная батарея – это обычно миниатюрная батарея (в виде «монетки», «таблетки») напряжением 3 вольта, подключенная между выводом 3 и корпусом. Таким образом, микросхема по-прежнему будет следить за временем и датой, и когда на основную схему будет подано питание, микроконтроллер получит текущие время и дату.

В этом проекте мы будем использовать DS1307. У этой микросхемы вывод 7 является выводом SQW/OUT (выходом прямоугольных импульсов). Вы можете использовать этот вывод для мигания светодиодом и оповещения микроконтроллера о необходимости фиксации времени. Мы будем делать и то, и другое. Ниже приведено объяснение работы с выводом SQW/OUT.

Для управления работой вывода SQW/OUT используется регистр управления DS1307.

Ригистр управления DS1307
Бит 7 Бит 6 Бит 5 Бит 4 Бит 3 Бит 2 Бит 1 Бит 0
OUT SQWE RS1 RS0
Бит 7: управление выходом (OUT)
Этот бит управляет выходным уровнем вывода SQW/OUT, когда выход прямоугольных импульсов выключен. Если SQWE = 0, логический уровень на выводе SQW/OUT равен 1, если OUT = 1, и 0, если OUT = 0. Первоначально обычно этот бит равен 0.
Бит 4: включение прямоугольных импульсов (SQWE)
Этот бит, когда установлен в логическую 1, включает выходной генератор. Частота прямоугольных импульсов зависит от значений битов RS0 и RS1. Когда частота прямоугольных импульсов настроена на значение 1 Гц, часовые регистры обновляются во время спада прямоугольного импульса. Первоначально обычно этот бит равен 0.
Биты 1 и 0: выбор частоты (RS)
Эти биты управляют частотой выходных прямоугольных импульсов, когда выход прямоугольных импульсов включен. Следующая таблица перечисляет частоты прямоугольных импульсов, которые могут быть выбраны с помощью данных битов. Первоначально обычно эти биты равны 1.
Выбор частоты прямоугольных импульсов и уровня на выводе SQW/OUT микросхемы DS1307
RS1 RS0 Частота импульсов и уровень на выходе SQW/OUT SQWE OUT
1 Гц 1 x
1 4,096 кГц 1 x
1 8,192 кГц 1 x
1 1 32,768 кГц 1 x
x x
x x 1 1

 Данная таблица поможет вам с частотой:

Выбор частоты прямоугольных импульсов DS1307
Частота импульсов Бит 7 Бит 6 Бит 5 Бит 4 Бит 3 Бит 2 Бит 1 Бит 0
1 Гц 1
4,096 кГц 1 1
8,192 кГц 1 1
32,768 кГц 1 1 1

Если вы подключили светодиод и резистор к выводу 7 и хотите, чтобы светодиод мигал с частотой 1 Гц, то должны записать в регистр управления значение 0b00010000. Если вам нужны импульсы 4,096 кГц, то вы должны записать 0b000100001. В этом случае, чтобы увидеть импульсы вам понадобится осциллограф, так как светодиод будет мигать так быстро, что будет казаться, что он светится постоянно. Мы будем использовать импульсы с частотой 1 Гц.

Модуль ZS-042 на базе RTC DS3231N

Представляют из себя законченный модуль ZS-042, который можно подключать к различным устройствам, не только к платформе Arduino.

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

Расположение и назначение пинов на модуле ZS-042

Вывод Описание
32К Выход, частота 32 кГц
SQW Программируемый выход Square-Wave сигнала
SCL Линия тактирования (Serial CLock)
SDA Линия данных (Serial Data)
VCC Питание модуля
GND Земля

Описание ATMEL AT24C32N

AT24C32N — это EEPROM память на 32к от производителя Atmel, собранная в корпусе SOIC8, работающая по двухпроводной шине I2C. Адрес микросхемы 0x57, при необходимости легко меняется, с помощью перемычек A0, A1 и A2 (это позволяет увеличить количество подключенных микросхем AT24C32/64). Так как чип AT24C32N имеет, три адресных входа (A0, A1 и A2), которые могут находится в двух состояния, либо лог «1» или лог «0», микросхеме доступны восемь адресов. от 0x50 до 0x57.

Режимы электропитания

Напряжение питания микросхемы может находиться в пределах 2.3…5.5В, имеются две линии питания, для внешнего источника (линия Vcc), а также для батареи (Vbat). Напряжение внешнего источника постоянно отслеживается, при падении ниже порога Vpf=2,5В, происходит переключение на линию батареи. В следующей таблице представлены условия переключения между линиями питания:

Комбинации уровней напряжения Активная линия питания
Vcc < Vpf, Vcc < Vbat Vbat
Vcc < Vpf, Vcc > Vbat Vcc
Vcc > Vpf, Vcc < Vbat Vcc
Vcc > Vpf, Vcc > Vbat Vcc

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

В целях сохранения заряда, при подключении батареи (подача напряжения на линию Vbat), тактовый генератор не запускается до тех пор, пока напряжение на линии Vcc не превысит пороговое значение Vpf, или не будет передан корректный адрес микросхемы по интерфейсу I2C. Время запуска тактового генератора составляет менее одной секунды. Примерно через 2 секунды после подачи питания (Vcc), или получения адреса по интерфейсу I2C, запускается процедура коррекции частоты. После того как тактовый генератор запустился, он продолжает функционировать до тех пор, пока присутствует напряжение Vcc или Vbat. При первом включении регистры даты и времени сброшены, и имеют следующие значения 01/01/ 00 — 01 — 00/00/00 (день/месяц/год/ — день недели — час/минуты/секунды).

Ток потребления при питании от батареи напряжением 3.63В, составляет 3 мкА, при отсутствии передачи данных по интерфейсу I2C. Максимальный ток потребления может достигать 300 мкА, в случае использования внешнего источника питания напряжением 5.5В, и высокой скорости передачи данных I2C.

Подключение к плате Arduino

Модуль DS3231 подключается к плате Arduino по интерфейсу I2C, используются выводы SDA и SCL. Схема подключения показана на рис. 2.

Для программирования будем использовать библиотеки DS1307 и Time. Скетч получения данных с DS3231 и вывода в последовательный порт показан в листинге 1.

Открываем монитор последовательного порта (рис. 3).

Результат работы – правильный отсчет, но неверное значение времени и даты. При отсутствии питания значение времени в микросхеме DS3231 сбрасывается на 00:00:00 01/01/2000.

Добавим функционал скетчу – установка времени отправкой строки вида «dd/mm/ YYYY hh:mm:ss» в последовательный порт.

После загрузки скетча на плату Arduino, открываем монитор последовательного порта и отправляем в Arduino строку «dd/mm/ YYYY hh:mm:ss» для установки текущей даты и точного времени (рис. 4,5).

Теперь DS3231 будет отсчитывать точное время. И если установлена батарейка, время не собъется после отключения питания.

Other functions

temperature(void)

Description

Returns the RTC temperature.

Parameters

None.

RTC temperature as degrees Celsius times four. (int)

int t = RTC.temperature();
float celsius = t / 4.0;
float fahrenheit = celsius * 9.0 / 5.0 + 32.0;

squareWave(SQWAVE_FREQS_t freq)

Description

Enables or disables the square wave output.

Parameters

freq: a value from the SQWAVE_FREQS_t enumeration above. (SQWAVE_FREQS_t)

None.

RTC.squareWave(SQWAVE_1_HZ);	//1 Hz square wave
RTC.squareWave(SQWAVE_NONE);	//no square wave
Description

Returns the value of the oscillator stop flag (OSF) bit in the control/status register which indicates that the oscillator is or was stopped, and that the timekeeping data may be invalid. Optionally clears the OSF bit depending on the argument passed. If the argument is omitted, the OSF bit is cleared by default. Calls to and also clear the OSF bit.

Parameters

clearOSF: an optional true or false value to indicate whether the OSF bit should be cleared (reset). If not supplied, a default value of true is used, resetting the OSF bit. (bool)

Functions for reading and writing RTC registers or static RAM (SRAM) for the DS3232

The DS3232RTC.h file defines symbolic names for the timekeeping, alarm, status and control registers. These can be used for the addr argument in the functions below.

writeRTC(byte addr, byte *values, byte nBytes)

Write one or more bytes to RTC memory.

Parameters

addr: First SRAM address to write (byte). The valid address range is 0x00-0x12 for DS3231, 0x00-0xFF for DS3232. The general-purpose SRAM for the DS3232 begins at address 0x14. Address is not checked for validity by the library.
values: An array of values to write (*byte)nBytes: Number of bytes to write (byte). Must be between 1 and 31 (Wire library limitation) but is not checked by the library.

I2C status (byte). Returns zero if successful.

//write 1, 2, ..., 8 to the first eight DS3232 SRAM locations
byte buf = {1, 2, 3, 4, 5, 6, 7, 8};
RTC.sramWrite(0x14, buf, 8);

writeRTC(byte addr, byte value)

Write a single byte to RTC memory.

Parameters

addr: SRAM address to write (byte). The valid address range is 0x00-0x12 for DS3231, 0x00-0xFF for DS3232. The general-purpose SRAM for the DS3232 begins at address 0x14. Address is not checked for validity by the library.
value: Value to write (byte)

I2C status (byte). Returns zero if successful.

RTC.writeRTC(3, 14);   //write the value 14 to SRAM address 3

readRTC(byte addr, byte *values, byte nBytes)

Read one or more bytes from RTC RAM.

Parameters

addr: First SRAM address to read (byte). The valid address range is 0x00-0x12 for DS3231, 0x00-0xFF for DS3232. The general-purpose SRAM for the DS3232 begins at address 0x14. Address is not checked for validity by the library.
values: An array to receive the values read (*byte)nBytes: Number of bytes to read (byte). Must be between 1 and 32 (Wire library limitation) but is not checked by the library.

I2C status (byte). Returns zero if successful.

//read the last eight locations of SRAM into buf
byte buf;
RTC.sramRead(248, buf, 8);
Parameters

addr: SRAM address to read (byte). The valid address range is 0x00-0x12 for DS3231, 0x00-0xFF for DS3232. The general-purpose SRAM for the DS3232 begins at address 0x14. Address is not checked for validity by the library.

Quick start

STM32CubeMX setup

  • In STM32CubeMX, set I2C1 to «I2C» and USART1 to «asynchronous»
  • Set up an external interrupt pin (say PB0) in GPIO settings, use «external interrupt mode with falling edge trigger detection» and «pull-up» settings.
  • Activate the external interrupt in NVIC settings by checking the corresponding box.
  • Connect pin 3 (INT#/SQW) of the DS3231 to this external interrupt pin.
  • Save and generate code.

Main program

In main.c (main program body file), include:

#include "ds3231_for_stm32_hal.h"

Initialization

Initialization function:

void DS3231_Init(I2C_HandleTypeDef *hi2c);

In main.c, before the main loop and after the system inits, call the DS3231 init function, and pass the corresponding I2C handle:

DS3231_Init(&hi2c1);

Date and time settings

Date functions:

void DS3231_SetDayOfWeek(uint8_t dow); // <-- Number of days since Sunday, 1 to 7.
void DS3231_SetDate(uint8_t date);
void DS3231_SetMonth(uint8_t month);
void DS3231_SetYear(uint16_t year);
void DS3231_SetFullDate(uint8_t date, uint8_t month, uint8_t dow, uint16_t year);

Time functions:

void DS3231_SetHour(uint8_t hour_24mode);
void DS3231_SetMinute(uint8_t minute);
void DS3231_SetSecond(uint8_t second);
void DS3231_SetFullTime(uint8_t hour_24mode, uint8_t minute, uint8_t second);

Interrupt modes

Set interrupt mode with:

void DS3231_SetInterruptMode(DS3231_InterruptMode mode);

Possible modes: square wave interrupt and alarm interrupt.

typedef enum DS3231_InterruptMode{
    DS3231_SQUARE_WAVE_INTERRUPT, DS3231_ALARM_INTERRUPT
}DS3231_InterruptMode;

Square wave output

With square wave interrupt mode selected, select interrupting rate with:

void DS3231_SetRateSelect(DS3231_Rate rate);

Possible rates 1 Hz, 1.024 kHz, 4.096 kHz or 8.912 kHz.

typedef enum DS3231_Rate{
	DS3231_1HZ, DS3231_1024HZ, DS3231_4096HZ, DS3231_8192HZ
}DS3231_Rate;

Alarms

With alarm interrupt mode selected, enable/disable alarms with:

void DS3231_EnableAlarm1(DS3231_State enable);
void DS3231_EnableAlarm2(DS3231_State enable);

Set alarm mode with:

void DS3231_SetAlarm1Mode(DS3231_Alarm1Mode alarmMode);
void DS3231_SetAlarm2Mode(DS3231_Alarm2Mode alarmMode);

Possible alarm modes (refer to table 2 of datasheets):

typedef enum D3231_Alarm1Mode{
    DS3231_A1_EVERY_S = 0x0f, DS3231_A1_MATCH_S = 0x0e, DS3231_A1_MATCH_S_M = 0x0c,
    DS3231_A1_MATCH_S_M_H = 0x08, DS3231_A1_MATCH_S_M_H_DATE = 0x00, DS3231_A1_MATCH_S_M_H_DAY = 0x80,
}DS3231_Alarm1Mode;

typedef enum D3231_Alarm2Mode{
    DS3231_A2_EVERY_M = 0x07, DS3231_A2_MATCH_M = 0x06, DS3231_A2_MATCH_M_H = 0x04,
    DS3231_A2_MATCH_M_H_DATE = 0x00, DS3231_A2_MATCH_M_H_DAY = 0x80,
}DS3231_Alarm2Mode;

Interrupts

In stm32f*xx_it.c (interrupt service routine file), include:

#include "ds3231_for_stm32_hal.h"

Check for an alarm flag with:

uint8_t DS3231_IsAlarm1Triggered();
uint8_t DS3231_IsAlarm2Triggered();

Clearing an alarm

Clear an alarm flag with:

void DS3231_ClearAlarm1Flag();
void DS3231_ClearAlarm2Flag();

Misc

Enable 32kHz output:

void DS3231_Enable32kHzOutput(DS3231_State enable);

Check for status:

uint8_t DS3231_IsOscillatorStopped();
uint8_t DS3231_Is32kHzEnabled();

Temperature functions:

int8_t DS3231_GetTemperatureInteger();
uint8_t DS3231_GetTemperatureFraction();

Refer to ./examples (main.c, stm32f4xx_it.c) and datasheets for further information.

Обзор часов реального времени DS3231

Если вы создаете устройство, которому нужно знать точное время, вам пригодится модуль часов реального времени RTC (Real Time Clock). Данные модули отсчитывают точное время и могут сохранять его даже при отключении основного питания при использовании резервного питания (батарейка CR2032 или литий-ионный аккумулятор LIR2032-3,6 В), которого хватит на несколько лет.

Еще совсем недавно основным модулем RTC в среде Ардуинщиков являлся модуль на микросхеме DS1307. В этом модуле использовался внешний кварцевый генератор частотой 32кГц, при изменении температуры менялась частота кварца, что приводило к погрешности в подсчете времени.

Новые модули RTC (рис. 1) построены на микросхеме DS3231, внутрь которой установлен кварцевый генератор и датчик температуры, который компенсирует изменения температуры, поэтому время отсчитывается более точно. Погрешность составляет ±2 минуты за год.

Подключение и настройка

Часы реального времени общаются с управляющей электроникой по протоколу I²C / TWI. Для подключения используется два 3-проводных шлейфа. При подключении модуля к Arduino удобно использовать Troyka Shield.

Если хотите оставить минимум проводов —
воспользуйтесь Troyka Slot Shield.

Пример работы с Arduino

testClock.ino
// библиотека для работы I²C
#include <Wire.h>
// библиотека для работы с часами реального времени
#include "TroykaRTC.h"
 
// размер массива для времени
#define LEN_TIME 12
// размер массива для даты
#define LEN_DATE 12
// размер массива для дня недели
#define LEN_DOW 12
 
// создаём объект для работы с часами реального времени
RTC clock;
 
// массив для хранения текущего времени
char timeLEN_TIME;
// массив для хранения текущей даты
char dateLEN_DATE;
// массив для хранения текущего дня недели
char weekDayLEN_DOW;
 
void setup()
{
  // открываем последовательный порт
  Serial.begin(9600);
  // инициализация часов
  clock.begin();
  // метод установки времени и даты в модуль вручную
  // clock.set(10,25,45,27,07,2005,THURSDAY);    
  // метод установки времени и даты автоматически при компиляции
  clock.set(__TIMESTAMP__);
  // что бы время менялось при прошивки или сбросе питания
  // закоментируйте оба метода clock.set();
}
 
void loop()
{
  // запрашиваем данные с часов
  clock.read();
  // сохраняем текущее время, дату и день недели в переменные
  clock.getTimeStamp(time, date, weekDay);
  // выводим в serial порт текущее время, дату и день недели
  Serial.print(time);
  Serial.print("\t");
  Serial.print(date);
  Serial.print("\t");
  Serial.println(weekDay);
  // ждём одну секунду
  delay(1000);
}

Пример работы с Iskra JS

В качестве примера выведем в «поле консоли» текущее время, дату и день недели. Для запуска примера понадобится библиотека для Iskra JS. Она обеспечивает простую работу с модулем и прячет в себе все тонкости протокола обмена данными между часами реального времени и управляющей платой.

rtc.js
// Настраиваем шину I2C
PrimaryI2C.setup({sda SDA, scl SCL, bitrate 100000});
 
// Создаем новый объект Rtc
var rtc = require('@amperka/rtc').connect(PrimaryI2C);
 
// Устанавливаем на часах текущее время контроллера
rtc.setTime();
 
// Результат в виде строки ISO: 2016-21-1T12:1:14
print(rtc.getTime('iso'));

Описание регистров DS3231

Ниже в таблице представлен перечень регистров часов реального времени:

Адрес D7 D6 D5 D4 D3 D2 D1 D0 Функция Пределы
0x00 10 секунд Секунды Секунды 00-59
0x01 10 минут Минуты Минуты 00-59
0x02 12/24 AM/PM 10 часов Час Часы 1-12 +  AM/PM или 00-23
10 часов
0x03 День День недели 1-7
0x04 10 число Число Дата 01-31
0x05 Century 10 месяц Месяц Месяцы/век 01-12 + Век
0x06 10 лет Год Годы 00-99
0x07 A1M1 10 секунд Секунды Секунды, 1-й будильник 00-59
0x08 A1M2 10 минут Минуты Минуты, 1-й будильник 00-59
0x09 A1M3 12/24 AM/PM 10 часов Час Часы, 1-й будильник 1-12 +  AM/PM или 00-23
10 часов
0x0A A1M4 DY/DT 10 число День День недели, 1-й будильник 1-7
Число Дата, 1-й будильник 01-31
0x0B A2M2 10 минут Минуты Минуты, 2-й будильник 00-59
0x0C A2M3 12/24 AM/PM 10 часов Час Часы, 2-й будильник 1-12 +  AM/PM или 00-23
10 часов
0x0D A2M4 DY/DT 10 число День День недели, 2-й будильник 1-7
Число Дата, 2-й будильник 01-31
0x0E EOSC BBSQW CONV RS2 RS1 INTCN A2IE A1IE Регистр настроек (Control)
0x0F OSF EN32kHz BSY A2F A1F Регистр статуса (Status)
0x10 SIGN DATA DATA DATA DATA DATA DATA DATA Регистр подстройки частоты (Aging Offset)
0x11 SIGN DATA DATA DATA DATA DATA DATA DATA Регистр температуры, старший байт
0x12 DATA DATA Регистр температуры, младший байт

Информация о времени хранится в двоично-десятичном формате, то есть каждый разряд десятичного числа (от 0 до 9) представляется группой из 4-х бит. В случае одного байта, младший полубайт отсчитывает единицы, старший десятки и т. д. Счет времени осуществляется в регистрах с адресами 0x00-0x06, для отсчета часов можно выбрать режим 12-ти или 24-х часов. Установка 6-го бита регистра часов (адрес 0x02), задает 12-ти часовой режим, в котором 5-й бит указывает на время суток, значению 1 соответствует время после полудня (PM), значению 0 до полудня (AM). Нулевое значение 6-го бита соответствует 24-х часовому режиму, здесь 5-й бит участвует в счете часов (значения 20-23).

Регистр дня недели увеличивается в полночь, счет идет от 1 до 7, регистр месяцев (адрес 0x05) содержит бит века Century (7-й бит), который переключается при переполнении регистра счета лет (адрес 0x06), от 99 к 00.

В микросхеме DS3231 реализовано два будильника, 1-й будильник настраивается с помощью регистров с адресами 0x07-0x0A, 2-й будильник регистрами 0x0B-0x0D. Битами A1Mx и A2Mx можно настроить различные режимы для будильников, установка бита исключает соответствующий регистр из операции сравнения.

Constructor

Description

For AVR architecture only (for backwards compatibility with the DS1307RTC library), the DS3232RTC library instantiates a DS3232RTC object named ; the user should not use the constructor for AVR boards. For other architectures, the user’s code must instantiate a DS3232RTC object.

Parameters

initI2C: An optional parameter to control whether the constructor initializes the I2C bus. The default is true (again for backwards compatibility). (bool)

Example
// For non-AVR boards only. Not needed for AVR boards.
DS3232RTC myRTC(false);     // tell constructor not to initialize the I2C bus.

Enumerations

SQWAVE_FREQS_t

Symbolic names used with the squareWave() function (described below).

  • SQWAVE_NONE
  • SQWAVE_1_HZ
  • SQWAVE_1024_HZ
  • SQWAVE_4096_HZ
  • SQWAVE_8192_HZ
  • ALM1_EVERY_SECOND — causes an alarm once per second.
  • ALM1_MATCH_SECONDS — causes an alarm when the seconds match (i.e. once per minute).
  • ALM1_MATCH_MINUTES — causes an alarm when the minutes and seconds match.
  • ALM1_MATCH_HOURS — causes an alarm when the hours and minutes and seconds match.
  • ALM1_MATCH_DATE — causes an alarm when the date of the month and hours and minutes and seconds match.
  • ALM1_MATCH_DAY — causes an alarm when the day of the week and hours and minutes and seconds match.
  • ALM2_EVERY_MINUTE — causes an alarm once per minute.
  • ALM2_MATCH_MINUTES — causes an alarm when the minutes match (i.e. once per hour).
  • ALM2_MATCH_HOURS — causes an alarm when the hours and minutes match.
  • ALM2_MATCH_DATE — causes an alarm when the date of the month and hours and minutes match.
  • ALM2_MATCH_DAY — causes an alarm when the day of the week and hours and minutes match.

Functions for setting and reading the time

get(void)

Description

Reads the current date and time from the RTC and returns it as a time_t value. Returns zero if an I2C error occurs (RTC not present, etc.).

None.

Current date and time (time_t)

Example
time_t myTime;
myTime = RTC.get();

set(time_t t)

Description

Sets the RTC date and time to the given time_t value. Clears the oscillator stop flag (OSF) bit in the control/status register. See the function and also the DS323x datasheet for more information on the OSF bit.

t: The date and time to set the RTC to (time_t)

Example
//this example first sets the system time (maintained by the Time library) to
//a hard-coded date and time, and then sets the RTC from the system time.
//the setTime() function is part of the Time library.
setTime(23, 31, 30, 13, 2, 2009);   //set the system time to 23h31m30s on 13Feb2009
RTC.set(now());                     //set the RTC from the system time

read(tmElements_t &tm)

Description

tm: Address of a tmElements_t structure to which the date and time are returned.

I2C status (byte). Returns zero if successful. The date and time read from the RTC are returned to the tm parameter.

Example
tmElements_t tm;
RTC.read(tm);
Serial.print(tm.Hour, DEC);
Serial.print(':');
Serial.print(tm.Minute,DEC);
Serial.print(':');
Serial.println(tm.Second,DEC);
Description

Sets the RTC to the date and time given by a tmElements_t structure. Clears the oscillator stop flag (OSF) bit in the control/status register. See the function and also the DS323x datasheet for more information on the OSF bit.

Example
tmElements_t tm;
tm.Hour = 23;             //set the tm structure to 23h31m30s on 13Feb2009
tm.Minute = 31;
tm.Second = 30;
tm.Day = 13;
tm.Month = 2;
tm.Year = 2009 - 1970;    //tmElements_t.Year is the offset from 1970
RTC.write(tm);            //set the RTC from the tm structure

Режимы электропитания

Напряжение питания микросхемы может находиться в пределах 2,3…5,5В, имеются две линии питания, для внешнего источника (линия Vcc), а также для батареи (Vbat). Напряжение внешнего источника постоянно отслеживается, при падении ниже порога Vpf=2,5В, происходит переключение на линию батареи. В следующей таблице представлены условия переключения между линиями питания:

Комбинации уровней напряжения Активная линия питания
Vcc < Vpf, Vcc < Vbat Vbat
Vcc < Vpf, Vcc > Vbat Vcc
Vcc > Vpf, Vcc < Vbat Vcc
Vcc > Vpf, Vcc > Vbat Vcc

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

В целях сохранения заряда, при подключении батареи (подача напряжения на линию Vbat), тактовый генератор не запускается до тех пор, пока напряжение на линии Vcc не превысит пороговое значение Vpf, или не будет передан корректный адрес микросхемы по интерфейсу I2C. Время запуска тактового генератора составляет менее одной секунды. Примерно через 2 секунды после подачи питания (Vcc), или получения адреса по интерфейсу I2C, запускается процедура коррекции частоты. После того как тактовый генератор запустился, он продолжает функционировать до тех пор, пока присутствует напряжение Vcc или Vbat. При первом включении регистры даты и времени сброшены, и имеют следующие значения 01/01/ 00 – 01 – 00/00/00 (день/месяц/год/ – день недели – час/минуты/секунды).

Ток потребления при питании от батареи напряжением 3,63В, составляет 3 мкА, при отсутствии передачи данных по интерфейсу I2C. Максимальный ток потребления может достигать 300 мкА, в случае использования внешнего источника питания напряжением 5,5В, и высокой скорости передачи данных I2C.

Использование

bool begin();                   // инициализация, вернет true, если RTC найден
void setTime(uint8_t param);	// установка времени == времени компиляции
void setTime(DateTime time);	// установить из структуры DateTime
void setTime(int8_t seconds, int8_t minutes, int8_t hours, int8_t date, int8_t month, int16_t year);	// установка времени
void setHMSDMY(int8_t hours, int8_t minutes, int8_t seconds, int8_t date, int8_t month, int16_t year);	// установка времени тип 2
    
// структура DateTime
uint8_t second; 
uint8_t minute;
uint8_t hour;
uint8_t day;
uint8_t date;
uint8_t month;
uint16_t year;

DateTime getTime();			// получить в структуру DateTime
uint8_t getSeconds();		// получить секунды
uint8_t getMinutes();		// получить минуты
uint8_t getHours();			// получить часы
uint8_t getDay();			// получить день недели
uint8_t getDate();			// получить число
uint16_t getYear();			// получить год
uint8_t getMonth();			// получить месяц
    
String getTimeString();			// получить время как строку вида HH:MM:SS
String getDateString();			// получить дату как строку вида DD.MM.YYYY
void getTimeChar(char* array);	// получить время как char array  вида HH:MM:SS
void getDateChar(char* array);	// получить дату как char array  вида DD.MM.YYYY       
    
bool lostPower();			// проверка на сброс питания
float getTemperatureFloat();// получить температуру float
int getTemperature();		// получить температуру int

Пример использования

Создадим проект часов с выводом данных на 4-х разрядный семисегментный дисплей на базе драйвера TM1637.

Нам потребуются следующие компоненты:

Плата прототипирования – 1

Модуль DS3231 – 1

4digit display на базе TM1637 – 1

Схема соединения элементов показана на рис. 6.

Для программирования вывода данных на 4-х разрядный семисегментный дисплей на базе драйвера TM1637 установим в Arduino IDE библиотеку TM1637. Каждые 5 секунд меняем на дисплее отображение:

При отображении показаний текущего времени каждые 0.5 секунды мигаем разделителем типа «двоеточие» между вторым и третьим разрядом. Содержимое скетча показано в листинге 3.

Загружаем скетч на плату Arduino и проверяем работу часов.

Часто задаваемые вопросы

1. Отсутствует получение данных времени с модуля DS3231.

Проверьте правильность подключения модуля DS3231 к плате Arduino.

2. Данные, получаемые с модуля DS3231, неверные.

Установите правильную дату и время, загрузив код из листинга 2 и отправив из последовательного порт правильные данные.

3. При отключении питания сбивается время и дата.

Установите резервное питание модуля (батарейка CR2032 или литий-ионный аккумулятор LIR2032-3,6 В).

Проверьте напряжение резервного питания (должно быть не менее 2,3 В).

Alarm functions

The DS3232 and DS3231 have two alarms. Alarm1 can be set to seconds precision; Alarm2 can only be set to minutes precision.

setAlarm(ALARM_TYPES_t alarmType, byte seconds, byte minutes, byte hours, byte daydate)

Set an alarm time. Sets the alarm registers only. To cause the INT pin to be asserted on alarm match, use alarmInterrupt(). This function can set either Alarm 1 or Alarm 2, depending on the value of alarmType (use the ALARM_TYPES_t enumeration above). When setting Alarm 2, the seconds value must be supplied but is ignored, recommend using zero. (Alarm 2 has no seconds register.)

alarmType: A value from the ALARM_TYPES_t enumeration, above. (ALARM_TYPES_t)seconds: The seconds value to set the alarm to. (byte)minutes: The minutes value to set the alarm to. (byte)hours: The hours value to set the alarm to. (byte)dayOrDate: The day of the week or the date of the month. For day of the week, use a value from the Time library timeDayOfWeek_t enumeration, i.e. dowSunday, dowMonday, dowTuesday, dowWednesday, dowThursday, dowFriday, dowSaturday. (byte)

None.

Example
//Set Alarm1 for 12:34:56 on Sunday
RTC.setAlarm(ALM1_MATCH_DAY, 56, 34, 12, dowSunday);

setAlarm(ALARM_TYPES_t alarmType, byte minutes, byte hours, byte daydate)

Set an alarm time. Sets the alarm registers only. To cause the INT pin to be asserted on alarm match, use alarmInterrupt(). This functiuon can set either Alarm 1 or Alarm 2, depending on the value of alarmType (use the ALARM_TYPES_t enumeration above). However, when using this function to set Alarm 1, the seconds value is set to zero. (Alarm 2 has no seconds register.)

alarmType: A value from the ALARM_TYPES_t enumeration, above. (ALARM_TYPES_t)minutes: The minutes value to set the alarm to. (byte)hours: The hours value to set the alarm to. (byte)dayOrDate: The day of the week or the date of the month. For day of the week, use a value from the Time library timeDayOfWeek_t enumeration, i.e. dowSunday, dowMonday, dowTuesday, dowWednesday, dowThursday, dowFriday, dowSaturday. (byte)

None.

Example
//Set Alarm2 for 12:34 on the 4th day of the month
RTC.setAlarm(ALM2_MATCH_DATE, 34, 12, 4);

alarmInterrupt(byte alarmNumber, bool alarmEnabled)

Enable or disable an alarm «interrupt». Note that this «interrupt» just causes the RTC’s INT pin to be asserted. To use this signal as an actual interrupt to (for example) a microcontroller, the RTC «interrupt» pin needs to be connected to the microcontroller and the microcontroller application firmware must properly configure the interrupt and also provide for handling it.

alarmNumber: The number of the alarm to enable or disable, ALARM_1 or ALARM_2 (byte)alarmEnabled: true or false (bool)

None.

Example
RTC.alarmInterrupt(ALARM_1, true);      //assert the INT pin when Alarm1 occurs.
RTC.alarmInterrupt(ALARM_2, false);     //disable Alarm2

alarm(byte alarmNumber)

Tests whether an alarm has been triggered. If the alarm was triggered, returns true and resets the alarm flag in the RTC, else returns false.

Value of the alarm flag bit (bool)

Example
if ( RTC.alarm(ALARM_1) ) {		//has Alarm1 triggered?
	//yes, act on the alarm
}
else {
	//no alarm
}

checkAlarm(byte alarmNumber)

Tests whether an alarm has been triggered. If the alarm was triggered, returns true, else returns false. The alarm flag is not reset.

Value of the alarm flag bit (bool)

Example
if ( RTC.checkAlarm(ALARM_1) ) {		//has Alarm1 triggered?
	//yes, act on the alarm
}
else {
	//no alarm
}
Example
if ( RTC.checkAlarm(ALARM_1) ) {		//has Alarm1 triggered?
    //yes, act on the alarm
	RTC.clearAlarm(ALARM_1);           //clear the alarm flag
}
else {
	//no alarm
}

Шаг 3. Код проекта

Я просто использую примерный эскиз из библиотеки, который будет содержать множество комментариев:

// DS3231_Serial_Easy
// Copyright (C)2015 Rinky-Dink Electronics, Henning Karlsen. All right reserved
// web: http://www.RinkyDinkElectronics.com/
//
// A quick demo of how to use my DS3231-library to 
// quickly send time and date information over a serial link
//
// To use the hardware I2C (TWI) interface of the Arduino you must connect
// the pins as follows:
//
// Arduino Uno/2009:
// ----------------------
// DS3231:  SDA pin   -> Arduino Analog 4 or the dedicated SDA pin
//          SCL pin   -> Arduino Analog 5 or the dedicated SCL pin
//
// Arduino Leonardo:
// ----------------------
// DS3231:  SDA pin   -> Arduino Digital 2 or the dedicated SDA pin
//          SCL pin   -> Arduino Digital 3 or the dedicated SCL pin
//
// Arduino Mega:
// ----------------------
// DS3231:  SDA pin   -> Arduino Digital 20 (SDA) or the dedicated SDA pin
//          SCL pin   -> Arduino Digital 21 (SCL) or the dedicated SCL pin
//
// Arduino Due:
// ----------------------
// DS3231:  SDA pin   -> Arduino Digital 20 (SDA) or the dedicated SDA1 (Digital 70) pin
//          SCL pin   -> Arduino Digital 21 (SCL) or the dedicated SCL1 (Digital 71) pin
//
// The internal pull-up resistors will be activated when using the 
// hardware I2C interfaces.
//
// You can connect the DS3231 to any available pin but if you use any
// other than what is described above the library will fall back to
// a software-based, TWI-like protocol which will require exclusive access 
// to the pins used, and you will also have to use appropriate, external
// pull-up resistors on the data and clock signals.
//

#include 

// Init the DS3231 using the hardware interface
DS3231  rtc(SDA, SCL);

void setup()
{
  // Setup Serial connection
  Serial.begin(115200);
  // Uncomment the next line if you are using an Arduino Leonardo
  //while (!Serial) {}
  
  // Initialize the rtc object
  rtc.begin();
  
  // The following lines can be uncommented to set the date and time
  //rtc.setDOW(WEDNESDAY);     // Set Day-of-Week to SUNDAY
  //rtc.setTime(12, 0, 0);     // Set the time to 12:00:00 (24hr format)
  //rtc.setDate(1, 1, 2014);   // Set the date to January 1st, 2014
}

void loop()
{
  // Send Day-of-Week
  Serial.print(rtc.getDOWStr());
  Serial.print(" ");
  
  // Send date
  Serial.print(rtc.getDateStr());
  Serial.print(" -- ");

  // Send time
  Serial.println(rtc.getTimeStr());
  
  // Wait one second before repeating :)
  delay (1000);
}

На этом всё, эта библиотека очень проста в использовании.

Заключение

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

Ниже на видеоролике можно увидеть функционирование схемы с часами DS3231, а также процесс установки времени:

https://youtube.com/watch?v=Z_SNrayM910