Добавляем библиотеку iarduino_RTC в качестве основного хранителя времени

This commit is contained in:
2022-04-24 11:56:12 +03:00
parent 2a8eb84836
commit 39c83aa328
22 changed files with 2047 additions and 0 deletions

13
lib/iarduino_RTC/LICENSE Normal file
View File

@@ -0,0 +1,13 @@
Copyright © 2019 iarduino.ru
Данная лицензия разрешает лицам, получившим копию данного программного обеспечения и сопутствующей документации (в дальнейшем именуемыми «Программное Обеспечение»), безвозмездно использовать Программное Обеспечение без ограничений, включая неограниченное право на использование, копирование, изменение, слияние, публикацию, распространение, сублицензирование и/или продажу копий Программного Обеспечения, а также лицам, которым предоставляется данное Программное Обеспечение, при соблюдении следующих условий:
Указанное выше уведомление об авторском праве и данные условия должны быть включены во все копии или значимые части данного Программного Обеспечения.
ДАННОЕ ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ ПРЕДОСТАВЛЯЕТСЯ «КАК ЕСТЬ», БЕЗ КАКИХ-ЛИБО ГАРАНТИЙ, ЯВНО ВЫРАЖЕННЫХ ИЛИ ПОДРАЗУМЕВАЕМЫХ, ВКЛЮЧАЯ ГАРАНТИИ ТОВАРНОЙ ПРИГОДНОСТИ, СООТВЕТСТВИЯ ПО ЕГО КОНКРЕТНОМУ НАЗНАЧЕНИЮ И ОТСУТСТВИЯ НАРУШЕНИЙ, НО НЕ ОГРАНИЧИВАЯСЬ ИМИ. НИ В КАКОМ СЛУЧАЕ АВТОРЫ ИЛИ ПРАВООБЛАДАТЕЛИ НЕ НЕСУТ ОТВЕТСТВЕННОСТИ ПО КАКИМ-ЛИБО ИСКАМ, ЗА УЩЕРБ ИЛИ ПО ИНЫМ ТРЕБОВАНИЯМ, В ТОМ ЧИСЛЕ, ПРИ ДЕЙСТВИИ КОНТРАКТА, ДЕЛИКТЕ ИЛИ ИНОЙ СИТУАЦИИ, ВОЗНИКШИМ ИЗ-ЗА ИСПОЛЬЗОВАНИЯ ПРОГРАММНОГО ОБЕСПЕЧЕНИЯ ИЛИ ИНЫХ ДЕЙСТВИЙ С ПРОГРАММНЫМ ОБЕСПЕЧЕНИЕМ.
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

104
lib/iarduino_RTC/README.md Normal file
View File

@@ -0,0 +1,104 @@
[![](https://iarduino.ru/img/logo.svg)](https://iarduino.ru)[![](https://wiki.iarduino.ru/img/git-shop.svg?3)](https://iarduino.ru) [![](https://wiki.iarduino.ru/img/git-wiki.svg?2)](https://wiki.iarduino.ru) [![](https://wiki.iarduino.ru/img/git-lesson.svg?2)](https://lesson.iarduino.ru)[![](https://wiki.iarduino.ru/img/git-forum.svg?2)](http://forum.trema.ru)
# iarduino_RTC [СКАЧАТЬ](https://github.com/tremaru/iarduino_RTC/archive/1.2.1.zip)
Библиотека позволяет читать и записывать время RTC модулей на базе чипов: DS1302, [DS1307](http://iarduino.ru/shop/Expansion-payments/chasy-realnogo-vremeni-rtc-trema-modul.html), [DS3231](http://iarduino.ru/shop/Expansion-payments/chasy-realnogo-vremeni-rtc-trema-modul-v2-0.html), ...
Преимуществом данной библиотеки является удобная реализация получения времени.
> Подробнее про установку библиотеки читайте в нашей [инструкции](https://wiki.iarduino.ru/page/Installing_libraries/).
Пример подключения к [Arduino](https://iarduino.ru/shop/boards/arduino-uno-r3.html)/[Piranha UNO](https://iarduino.ru/shop/boards/piranha-uno-r3.html) с помощью [Trema Shield](https://iarduino.ru/shop/Expansion-payments/trema-shield.html)
Подробнее о [подключении модуля](https://wiki.iarduino.ru/page/chasy-realnogo-vremeni-rtc-trema-modul/)
![enter image description here](https://iarduino.ru/img/upload/6a83fe7f3deb2f48d1408daac49284ba.png)
| Модель | Ссылка на магазин|
|--|--|
| DS1307 ![enter image description here](https://wiki.iarduino.ru/img/resources/643/643.svg) | https://iarduino.ru/shop/Expansion-payments/chasy-realnogo-vremeni-rtc-trema-modul.html|
| DS3231 ![enter image description here](https://wiki.iarduino.ru/img/resources/877/877.svg) | https://iarduino.ru/shop/Expansion-payments/chasy-realnogo-vremeni-rtc-trema-modul-v2-0.html |
## Описание библиотеки:
Библиотека позволяет читать и записывать время RTC модулей на базе чипов: DS1302, [DS1307](http://iarduino.ru/shop/Expansion-payments/chasy-realnogo-vremeni-rtc-trema-modul.html), [DS3231](http://iarduino.ru/shop/Expansion-payments/chasy-realnogo-vremeni-rtc-trema-modul-v2-0.html), …
Преимуществом данной библиотеки является удобная реализация получения времени.
**[ Подробное описание, подключение и примеры работы ](https://wiki.iarduino.ru/page/chasy-realnogo-vremeni-rtc-trema-modul/)**
## Назначение функций и переменных:
Подробное описание работы с библиотекой, находится в разделе https://wiki.iarduino.ru/page/chasy-realnogo-vremeni-rtc-trema-modul/
**Подключаем библиотеку.**
#include <iarduino_RTC.h> // Подключаем библиотеку.
**Создаём объект.**
iarduino_RTC ОБЪЕКТ ( НАЗВАНИЕ [, ВЫВОД_RST [, ВЫВОД_CLK [, ВЫВОД_DAT ]]] ); // Создаём объект.
**Инициализация работы RTC модуля.**
Функция begin(); // Инициализация работы RTC модуля.
**Установка времени.**
Функция settime( СЕК [, МИН [, ЧАС [, ДЕНЬ [, МЕС [, ГОД [, ДН ]]]]]] ); // Установка времени.
**Чтение времени.**
Функция gettime( [ СТРОКА ] ); // Чтение времени.
**Заставляет функцию gettime «мигать» указанным параметром времени.**
функция blinktime( ПАРАМЕТР [ ЧАСТОТА ] ); // Заставляет функцию gettime «мигать» указанным параметром времени.
**Указывает минимальный период обращения к модулю в минутах.**
функция period( МИНУТЫ ); // Указывает минимальный период обращения к модулю в минутах.
**Возвращает секунды от 0 до 59.**
Переменная seconds // Возвращает секунды от 0 до 59.
**Возвращает минуты от 0 до 59.**
Переменная minutes // Возвращает минуты от 0 до 59.
**Возвращает часы от 1 до 12.**
Переменная hours // Возвращает часы от 1 до 12.
**Возвращает часы от 0 до 23.**
Переменная Hours // Возвращает часы от 0 до 23.
**Возвращает полдень 0 или 1 (0-am, 1-pm).**
Переменная midday // Возвращает полдень 0 или 1 (0-am, 1-pm).
**Возвращает день месяца от 1 до 31.**
Переменная day // Возвращает день месяца от 1 до 31.
**Возвращает день недели от 0 до 6 (0-воскресенье, 6-суббота).**
Переменная weekday // Возвращает день недели от 0 до 6 (0-воскресенье, 6-суббота).
**Возвращает месяц от 1 до 12.**
Переменная month // Возвращает месяц от 1 до 12.
**Возвращает год от 0 до 99.**
Переменная year // Возвращает год от 0 до 99.

View File

@@ -0,0 +1,128 @@
// Пример считывания текущего времени: //
//
// Раскомментируйте для программной реализации шины I2C: //
// #define pin_SW_SDA 3 // Назначение любого вывода Arduino для работы в качестве линии SDA программной шины I2C.
// #define pin_SW_SCL 9 // Назначение любого вывода Arduino для работы в качестве линии SCL программной шины I2C.
// Раскомментируйте для совместимости с большинством плат: //
// #include <Wire.h> // Библиотека iarduino_RTC будет использовать методы и функции библиотеки Wire.
// Ссылки для ознакомления: //
// Подробная информация о подключении модуля к шине I2C: // http://wiki.iarduino.ru/page/i2c_connection/
// Подробная информация о функциях и методах библиотеки: // http://wiki.iarduino.ru/page/chasy-realnogo-vremeni-rtc-trema-modul/
//
#include <iarduino_RTC.h> // Подключаем библиотеку iarduino_RTC для работы с модулями реального времени.
// iarduino_RTC watch(RTC_DS1302, 2, 3, 4); // Объявляем объект watch для работы с RTC модулем на базе чипа DS1302, указывая выводы Arduino подключённые к выводам модуля RST, CLK, DAT.
// iarduino_RTC watch(RTC_DS1307); // Объявляем объект watch для работы с RTC модулем на базе чипа DS1307, используется шина I2C.
iarduino_RTC watch(RTC_DS3231); // Объявляем объект watch для работы с RTC модулем на базе чипа DS3231, используется шина I2C.
// iarduino_RTC watch(RTC_RX8025); // Объявляем объект watch для работы с RTC модулем на базе чипа RX8025, используется шина I2C.
//
void setup(){ //
delay(300); // Ждем готовности модуля отвечать на запросы.
Serial.begin(9600); // Инициируем передачу данных в монитор последовательного порта на скорости 9600 бод.
watch.begin(); // Инициируем работу с модулем.
} //
void loop(){ //
if(millis()%1000==0){ // Если прошла 1 секунда.
Serial.println(watch.gettime("d-m-Y, H:i:s, D")); // Выводим время.
delay(1); // Приостанавливаем скетч на 1 мс, чтоб не выводить время несколько раз за 1мс.
} //
} //
//
// ====================================================== //
// ОПИСАНИЯ ПАРАМЕТРОВ ФУНКЦИЙ:
//
// • Подключение библиотеки:
// #include <iarduino_RTC.h>
// iarduino_RTC watch(название модуля [, вывод SS/RST [, вывод CLK [, вывод DAT]]]);
// - Если модуль работает на шине I2C или SPI, то достаточно указать 1 параметр, например: iarduino_RTC watch(RTC_DS3231);
// - Если модуль работает на шине SPI, а аппаратный вывод SS занят, то номер назначенного вывода SS для модуля указывается вторым параметром, например: iarduino_RTC watch(RTC_DS1305,22);
// - Если модуль работает на трехпроводной шине, то указываются номера всех выводов, например: iarduino_RTC watch(RTC_DS1302, 2, 3, 4); // RST, CLK, DAT.
//
// • Для работы с модулями, в библиотеке реализованы 7 функции:
// - Инициировать модуль begin();
// - Указать время settime(секунды [, минуты [, часы [, день [, месяц [, год [, день недели]]]]]]);
// - Получить время gettime(["строка с параметрами"]);
// - Мигать времем blinktime(0-не_мигать / 1-мигают_сек / 2-мигают_мин / 3-мигают_час / 4-мигают_дни / 5-мигают_мес / 6-мигает_год / 7-мигают_дни_недели / 8-мигает_полдень);
// - Разгрузить шину period(минуты);
// - Получить Unix время gettimeUnix();
// - Указать Unix время settimeUnix(секунды);
//
// • Функция begin():
// - Функция инициирует модуль: проверяет регистры модуля, запускает генератор модуля и т.д.
//
// • Функция settime(секунды [, минуты [, часы [, день [, месяц [, год [, день недели]]]]]]):
// - Функция записывает время в модуль.
// - Год указывается без учёта века, в формате 0-99.
// - Часы указываются в 24-часовом формате, от 0 до 23.
// - День недели указывается в виде числа: 0-воскресенье, 1-понедельник, 2-вторник ..., 6-суббота.
// - Если предыдущий параметр надо оставить без изменений, то можно указать отрицательное или заведомо большее значение.
// - Все параметры, кроме секунд, являются необязательными. Если параметр не указан, значит он не будет изменён.
// - Пример: watch.settime(-1, 10); // Установить 10 минут, а секунды, часы и дату, оставить без изменений.
// - Пример: watch.settime(0, 5, 13); // Установить 13 часов, 5 минут, 0 секунд, а дату оставить без изменений.
// - Пример: watch.settime(-1, -1, -1, 9, 2, 17); // Установить дату 09.02.2017, а время и день недели оставить без изменений.
//
// • Функция gettime(["строка с параметрами"]):
// - Функция получает и возвращает строку заменяя описанные ниже символы на текущее время:
// - Пример: watch.gettime("d-m-Y, H:i:s, D"); // Вернуть строку с датой и временем, например: "01-10-2015, 14:00:05, Thu".
// - Пример: watch.gettime("s"); // Вернуть строку с секундами, например: "05".
// - Указанные символы идентичны символам для функции date() в PHP:
// s - Вернуть секунды от 00 до 59 (два знака).
// i - Вернуть минуты от 00 до 59 (два знака).
// h - Вернуть часы в 12-часовом формате от 01 до 12 (два знака).
// H - Вернуть часы в 24-часовом формате от 00 до 23 (два знака).
// d - Вернуть день месяца от 01 до 31 (два знака).
// w - Вернуть день недели от 0 до 6 (один знак: 0-воскресенье, 6-суббота).
// D - Вернуть день недели наименование от Mon до Sun (три знака: Mon Tue Wed Thu Fri Sat Sun).
// m - Вернуть месяц от 01 до 12 (два знака).
// M - Вернуть месяц наименование от Jan до Dec (три знака: Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec).
// Y - Вернуть год от 2000 до 2099 (четыре знака).
// y - Вернуть год от 00 до 99 (два знака).
// a - Вернуть полдень am или pm (два знака, в нижнем регистре).
// A - Вернуть полдень AM или PM (два знака, в верхнем регистре).
//
// Если требуется получить время в виде цифр, то можно вызвать функцию gettime() без параметра, после чего получить время из переменных:
// - Пример: watch.gettime();
// Serial.print(watch.Hours); Serial.print(":"); // Вывести часы.
// Serial.print(watch.minutes); Serial.print(":"); // Вывести минуты.
// Serial.print(watch.seconds); Serial.println(""); // Вывести секунды.
// seconds - Переменная содержит секунды 0-59.
// minutes - Переменная содержит минуты 0-59.
// hours - Переменная содержит часы 1-12.
// Hours - Переменная содержит часы 0-23.
// midday - Переменная содержит полдень 0-1 (0-am, 1-pm).
// day - Переменная содержит день месяца 1-31.
// weekday - Переменная содержит день недели 0-6 (0-воскресенье, 6-суббота).
// month - Переменная содержит месяц 1-12.
// year - Переменная содержит год 0-99.
// Unix - Переменная содержит секунды прошедшие с начала эпохи Unix.
//
// • Функция blinktime(параметр [, частота ]):
// - Данная функция указывает функции gettime("строка с параметрами"); мигать одним из параметров времени (заменять параметр пробелами).
// - Эта функция может быть полезна, для отображения на дисплее, устанавливаемого параметра времени.
// Например, при установке минут, они начинают мигать, и Вам понятно, что именно Вы устанавливаете.
// - Первым аргументом функции указывается параметр в виде числа от 0 до 8:
// 0 - не мигать.
// 1 - мигают сек.
// 2 - мигают мин.
// 3 - мигают час.
// 4 - мигают дни.
// 5 - мигают мес.
// 6 - мигает год.
// 7 - мигают дни недели.
// 8 - мигает полдень.
// - Второй аргумент функции является необязательным, он указвает частоту миганий в Гц, по умолчанию 1Гц.
// - Пример: watch.blinktime(6); // При выводе на дисплей будет мигать год с частотой по умолчанию 1Гц.
// - Пример: watch.blinktime(6, 2); // При выводе на дисплей будет мигать год с частотой 2Гц.
//
// • Функция period(минуты):
// - Устанавливает минимальный период обращения к модулю в минутах (от 0 до 255).
// - Данная функция указывает функции gettime() откуда брать текущее время: из модуля (не чаще заданного периода), или рассчитать в библиотеке (без обращения к модулю).
// - Пример: watch.period(10); // Теперь функция gettime() будет получать время от модуля только 1 раз в 10 минут.
// Ответом на все остальные запросы к функции gettime(), будет рассчитанное время: сумма времени полученного от модуля и времени прошедшего с момента его получения.
//
// • Функция gettimeUnix():
// - Функция возвращает число равное количеству секунд прошедших с начала эпохи Unix (с полуночи 1 января 1970 года).
//
// • Функция settimeUnix(секунды):
// - Функция записывает время в модуль.
// - В качестве единственного параметра функции указывается количество секунд прошедших с начала эпохи Unix.
// - Пример: watch.settimeUnix(1577836800); // Установить время на 1577836800 сек больше даты 01.01.1970г 00:00:00, что соответствует дате 01.01.2020г 00:00:00.

View File

@@ -0,0 +1,128 @@
// Пример считывания секунд прошедших с начала эпохи Unix: //
//
// Раскомментируйте для программной реализации шины I2C: //
// #define pin_SW_SDA 3 // Назначение любого вывода Arduino для работы в качестве линии SDA программной шины I2C.
// #define pin_SW_SCL 9 // Назначение любого вывода Arduino для работы в качестве линии SCL программной шины I2C.
// Раскомментируйте для совместимости с большинством плат: //
// #include <Wire.h> // Библиотека iarduino_RTC будет использовать методы и функции библиотеки Wire.
// Ссылки для ознакомления: //
// Подробная информация о подключении модуля к шине I2C: // http://wiki.iarduino.ru/page/i2c_connection/
// Подробная информация о функциях и методах библиотеки: // http://wiki.iarduino.ru/page/chasy-realnogo-vremeni-rtc-trema-modul/
//
#include <iarduino_RTC.h> // Подключаем библиотеку iarduino_RTC для работы с модулями реального времени.
// iarduino_RTC watch(RTC_DS1302, 2, 3, 4); // Объявляем объект watch для работы с RTC модулем на базе чипа DS1302, указывая выводы Arduino подключённые к выводам модуля RST, CLK, DAT.
// iarduino_RTC watch(RTC_DS1307); // Объявляем объект watch для работы с RTC модулем на базе чипа DS1307, используется шина I2C.
iarduino_RTC watch(RTC_DS3231); // Объявляем объект watch для работы с RTC модулем на базе чипа DS3231, используется шина I2C.
// iarduino_RTC watch(RTC_RX8025); // Объявляем объект watch для работы с RTC модулем на базе чипа RX8025, используется шина I2C.
//
void setup(){ //
delay(300); // Ждем готовности модуля отвечать на запросы.
Serial.begin(9600); // Инициируем передачу данных в монитор последовательного порта на скорости 9600 бод.
watch.begin(); // Инициируем работу с модулем.
} //
void loop(){ //
if (millis()%1000==0){ // Если прошла 1 секунда.
Serial.println( watch.gettimeUnix() ); // Выводим количество секунд прошедших с начала эпохи Unix (01.01.1970 00:00:00 GMT).
delay(1); // Приостанавливаем скетч на 1 мс, чтоб не выводить время несколько раз за 1мс.
} //
} //
//
// ====================================================== //
// ОПИСАНИЯ ПАРАМЕТРОВ ФУНКЦИЙ:
//
// • Подключение библиотеки:
// #include <iarduino_RTC.h>
// iarduino_RTC watch(название модуля [, вывод SS/RST [, вывод CLK [, вывод DAT]]]);
// - Если модуль работает на шине I2C или SPI, то достаточно указать 1 параметр, например: iarduino_RTC watch(RTC_DS3231);
// - Если модуль работает на шине SPI, а аппаратный вывод SS занят, то номер назначенного вывода SS для модуля указывается вторым параметром, например: iarduino_RTC watch(RTC_DS1305,22);
// - Если модуль работает на трехпроводной шине, то указываются номера всех выводов, например: iarduino_RTC watch(RTC_DS1302, 2, 3, 4); // RST, CLK, DAT.
//
// • Для работы с модулями, в библиотеке реализованы 7 функции:
// - Инициировать модуль begin();
// - Указать время settime(секунды [, минуты [, часы [, день [, месяц [, год [, день недели]]]]]]);
// - Получить время gettime(["строка с параметрами"]);
// - Мигать времем blinktime(0-не_мигать / 1-мигают_сек / 2-мигают_мин / 3-мигают_час / 4-мигают_дни / 5-мигают_мес / 6-мигает_год / 7-мигают_дни_недели / 8-мигает_полдень);
// - Разгрузить шину period(минуты);
// - Получить Unix время gettimeUnix();
// - Указать Unix время settimeUnix(секунды);
//
// • Функция begin():
// - Функция инициирует модуль: проверяет регистры модуля, запускает генератор модуля и т.д.
//
// • Функция settime(секунды [, минуты [, часы [, день [, месяц [, год [, день недели]]]]]]):
// - Функция записывает время в модуль.
// - Год указывается без учёта века, в формате 0-99.
// - Часы указываются в 24-часовом формате, от 0 до 23.
// - День недели указывается в виде числа: 0-воскресенье, 1-понедельник, 2-вторник ..., 6-суббота.
// - Если предыдущий параметр надо оставить без изменений, то можно указать отрицательное или заведомо большее значение.
// - Все параметры, кроме секунд, являются необязательными. Если параметр не указан, значит он не будет изменён.
// - Пример: watch.settime(-1, 10); // Установить 10 минут, а секунды, часы и дату, оставить без изменений.
// - Пример: watch.settime(0, 5, 13); // Установить 13 часов, 5 минут, 0 секунд, а дату оставить без изменений.
// - Пример: watch.settime(-1, -1, -1, 9, 2, 17); // Установить дату 09.02.2017, а время и день недели оставить без изменений.
//
// • Функция gettime(["строка с параметрами"]):
// - Функция получает и возвращает строку заменяя описанные ниже символы на текущее время:
// - Пример: watch.gettime("d-m-Y, H:i:s, D"); // Вернуть строку с датой и временем, например: "01-10-2015, 14:00:05, Thu".
// - Пример: watch.gettime("s"); // Вернуть строку с секундами, например: "05".
// - Указанные символы идентичны символам для функции date() в PHP:
// s - Вернуть секунды от 00 до 59 (два знака).
// i - Вернуть минуты от 00 до 59 (два знака).
// h - Вернуть часы в 12-часовом формате от 01 до 12 (два знака).
// H - Вернуть часы в 24-часовом формате от 00 до 23 (два знака).
// d - Вернуть день месяца от 01 до 31 (два знака).
// w - Вернуть день недели от 0 до 6 (один знак: 0-воскресенье, 6-суббота).
// D - Вернуть день недели наименование от Mon до Sun (три знака: Mon Tue Wed Thu Fri Sat Sun).
// m - Вернуть месяц от 01 до 12 (два знака).
// M - Вернуть месяц наименование от Jan до Dec (три знака: Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec).
// Y - Вернуть год от 2000 до 2099 (четыре знака).
// y - Вернуть год от 00 до 99 (два знака).
// a - Вернуть полдень am или pm (два знака, в нижнем регистре).
// A - Вернуть полдень AM или PM (два знака, в верхнем регистре).
//
// Если требуется получить время в виде цифр, то можно вызвать функцию gettime() без параметра, после чего получить время из переменных:
// - Пример: watch.gettime();
// Serial.print(watch.Hours); Serial.print(":"); // Вывести часы.
// Serial.print(watch.minutes); Serial.print(":"); // Вывести минуты.
// Serial.print(watch.seconds); Serial.println(""); // Вывести секунды.
// seconds - Переменная содержит секунды 0-59.
// minutes - Переменная содержит минуты 0-59.
// hours - Переменная содержит часы 1-12.
// Hours - Переменная содержит часы 0-23.
// midday - Переменная содержит полдень 0-1 (0-am, 1-pm).
// day - Переменная содержит день месяца 1-31.
// weekday - Переменная содержит день недели 0-6 (0-воскресенье, 6-суббота).
// month - Переменная содержит месяц 1-12.
// year - Переменная содержит год 0-99.
// Unix - Переменная содержит секунды прошедшие с начала эпохи Unix.
//
// • Функция blinktime(параметр [, частота ]):
// - Данная функция указывает функции gettime("строка с параметрами"); мигать одним из параметров времени (заменять параметр пробелами).
// - Эта функция может быть полезна, для отображения на дисплее, устанавливаемого параметра времени.
// Например, при установке минут, они начинают мигать, и Вам понятно, что именно Вы устанавливаете.
// - Первым аргументом функции указывается параметр в виде числа от 0 до 8:
// 0 - не мигать.
// 1 - мигают сек.
// 2 - мигают мин.
// 3 - мигают час.
// 4 - мигают дни.
// 5 - мигают мес.
// 6 - мигает год.
// 7 - мигают дни недели.
// 8 - мигает полдень.
// - Второй аргумент функции является необязательным, он указвает частоту миганий в Гц, по умолчанию 1Гц.
// - Пример: watch.blinktime(6); // При выводе на дисплей будет мигать год с частотой по умолчанию 1Гц.
// - Пример: watch.blinktime(6, 2); // При выводе на дисплей будет мигать год с частотой 2Гц.
//
// • Функция period(минуты):
// - Устанавливает минимальный период обращения к модулю в минутах (от 0 до 255).
// - Данная функция указывает функции gettime() откуда брать текущее время: из модуля (не чаще заданного периода), или рассчитать в библиотеке (без обращения к модулю).
// - Пример: watch.period(10); // Теперь функция gettime() будет получать время от модуля только 1 раз в 10 минут.
// Ответом на все остальные запросы к функции gettime(), будет рассчитанное время: сумма времени полученного от модуля и времени прошедшего с момента его получения.
//
// • Функция gettimeUnix():
// - Функция возвращает число равное количеству секунд прошедших с начала эпохи Unix (с полуночи 1 января 1970 года).
//
// • Функция settimeUnix(секунды):
// - Функция записывает время в модуль.
// - В качестве единственного параметра функции указывается количество секунд прошедших с начала эпохи Unix.
// - Пример: watch.settimeUnix(1577836800); // Установить время на 1577836800 сек больше даты 01.01.1970г 00:00:00, что соответствует дате 01.01.2020г 00:00:00.

View File

@@ -0,0 +1,138 @@
// Пример считывания текущего времени в переменные: //
//
// Раскомментируйте для программной реализации шины I2C: //
// #define pin_SW_SDA 3 // Назначение любого вывода Arduino для работы в качестве линии SDA программной шины I2C.
// #define pin_SW_SCL 9 // Назначение любого вывода Arduino для работы в качестве линии SCL программной шины I2C.
// Раскомментируйте для совместимости с большинством плат: //
// #include <Wire.h> // Библиотека iarduino_RTC будет использовать методы и функции библиотеки Wire.
// Ссылки для ознакомления: //
// Подробная информация о подключении модуля к шине I2C: // http://wiki.iarduino.ru/page/i2c_connection/
// Подробная информация о функциях и методах библиотеки: // http://wiki.iarduino.ru/page/chasy-realnogo-vremeni-rtc-trema-modul/
//
#include <iarduino_RTC.h> // Подключаем библиотеку iarduino_RTC для работы с модулями реального времени.
// iarduino_RTC watch(RTC_DS1302, 2, 3, 4); // Объявляем объект watch для работы с RTC модулем на базе чипа DS1302, указывая выводы Arduino подключённые к выводам модуля RST, CLK, DAT.
// iarduino_RTC watch(RTC_DS1307); // Объявляем объект watch для работы с RTC модулем на базе чипа DS1307, используется шина I2C.
iarduino_RTC watch(RTC_DS3231); // Объявляем объект watch для работы с RTC модулем на базе чипа DS3231, используется шина I2C.
// iarduino_RTC watch(RTC_RX8025); // Объявляем объект watch для работы с RTC модулем на базе чипа RX8025, используется шина I2C.
//
uint8_t D, M, Y, h, m, s, W; // Объявляем переменные для получения следующих значений: D-день, M-месяц, Y-год, h-часы, m-минуты, s-секунды, W-день недели.
//
void setup(){ //
delay(300); // Ждем готовности модуля отвечать на запросы.
Serial.begin(9600); // Инициируем передачу данных в монитор последовательного порта на скорости 9600 бод.
watch.begin(); // Инициируем работу с модулем.
} //
void loop(){ //
if(millis()%1000==0){ // Если прошла 1 секунда.
watch.gettime(); // Считываем текущее время из модуля в буфер библиотеки.
D = watch.day; // Получаем из буфера библиотеки текущий день месяца 1-31.
M = watch.month; // Получаем из буфера библиотеки текущий месяц 1-12.
Y = watch.year; // Получаем из буфера библиотеки текущий год 0-99.
h = watch.Hours; // Получаем из буфера библиотеки текущие часы 0-23.
m = watch.minutes; // Получаем из буфера библиотеки текущие минуты 0-59.
s = watch.seconds; // Получаем из буфера библиотеки текущие секунды 0-59.
W = watch.weekday; // Получаем из буфера библиотеки текущий день недели 0-6.
Serial.println((String) D+"-"+M+"-"+Y+", "+h+":"+m+":"+s+", "+W); // Выводим время в монитор, одной строкой.
delay(1); // Приостанавливаем скетч на 1 мс, чтоб не выводить время несколько раз за 1мс.
} //
} //
//
// ================================================================== //
// ОПИСАНИЯ ПАРАМЕТРОВ ФУНКЦИЙ:
//
// • Подключение библиотеки:
// #include <iarduino_RTC.h>
// iarduino_RTC watch(название модуля [, вывод SS/RST [, вывод CLK [, вывод DAT]]]);
// - Если модуль работает на шине I2C или SPI, то достаточно указать 1 параметр, например: iarduino_RTC watch(RTC_DS3231);
// - Если модуль работает на шине SPI, а аппаратный вывод SS занят, то номер назначенного вывода SS для модуля указывается вторым параметром, например: iarduino_RTC watch(RTC_DS1305,22);
// - Если модуль работает на трехпроводной шине, то указываются номера всех выводов, например: iarduino_RTC watch(RTC_DS1302, 2, 3, 4); // RST, CLK, DAT.
//
// • Для работы с модулями, в библиотеке реализованы 7 функции:
// - Инициировать модуль begin();
// - Указать время settime(секунды [, минуты [, часы [, день [, месяц [, год [, день недели]]]]]]);
// - Получить время gettime(["строка с параметрами"]);
// - Мигать времем blinktime(0-не_мигать / 1-мигают_сек / 2-мигают_мин / 3-мигают_час / 4-мигают_дни / 5-мигают_мес / 6-мигает_год / 7-мигают_дни_недели / 8-мигает_полдень);
// - Разгрузить шину period(минуты);
// - Получить Unix время gettimeUnix();
// - Указать Unix время settimeUnix(секунды);
//
// • Функция begin():
// - Функция инициирует модуль: проверяет регистры модуля, запускает генератор модуля и т.д.
//
// • Функция settime(секунды [, минуты [, часы [, день [, месяц [, год [, день недели]]]]]]):
// - Функция записывает время в модуль.
// - Год указывается без учёта века, в формате 0-99.
// - Часы указываются в 24-часовом формате, от 0 до 23.
// - День недели указывается в виде числа: 0-воскресенье, 1-понедельник, 2-вторник ..., 6-суббота.
// - Если предыдущий параметр надо оставить без изменений, то можно указать отрицательное или заведомо большее значение.
// - Все параметры, кроме секунд, являются необязательными. Если параметр не указан, значит он не будет изменён.
// - Пример: watch.settime(-1, 10); // Установить 10 минут, а секунды, часы и дату, оставить без изменений.
// - Пример: watch.settime(0, 5, 13); // Установить 13 часов, 5 минут, 0 секунд, а дату оставить без изменений.
// - Пример: watch.settime(-1, -1, -1, 9, 2, 17); // Установить дату 09.02.2017, а время и день недели оставить без изменений.
//
// • Функция gettime(["строка с параметрами"]):
// - Функция получает и возвращает строку заменяя описанные ниже символы на текущее время:
// - Пример: watch.gettime("d-m-Y, H:i:s, D"); // Вернуть строку с датой и временем, например: "01-10-2015, 14:00:05, Thu".
// - Пример: watch.gettime("s"); // Вернуть строку с секундами, например: "05".
// - Указанные символы идентичны символам для функции date() в PHP:
// s - Вернуть секунды от 00 до 59 (два знака).
// i - Вернуть минуты от 00 до 59 (два знака).
// h - Вернуть часы в 12-часовом формате от 01 до 12 (два знака).
// H - Вернуть часы в 24-часовом формате от 00 до 23 (два знака).
// d - Вернуть день месяца от 01 до 31 (два знака).
// w - Вернуть день недели от 0 до 6 (один знак: 0-воскресенье, 6-суббота).
// D - Вернуть день недели наименование от Mon до Sun (три знака: Mon Tue Wed Thu Fri Sat Sun).
// m - Вернуть месяц от 01 до 12 (два знака).
// M - Вернуть месяц наименование от Jan до Dec (три знака: Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec).
// Y - Вернуть год от 2000 до 2099 (четыре знака).
// y - Вернуть год от 00 до 99 (два знака).
// a - Вернуть полдень am или pm (два знака, в нижнем регистре).
// A - Вернуть полдень AM или PM (два знака, в верхнем регистре).
//
// Если требуется получить время в виде цифр, то можно вызвать функцию gettime() без параметра, после чего получить время из переменных:
// - Пример: watch.gettime();
// Serial.print(watch.Hours); Serial.print(":"); // Вывести часы.
// Serial.print(watch.minutes); Serial.print(":"); // Вывести минуты.
// Serial.print(watch.seconds); Serial.println(""); // Вывести секунды.
// seconds - Переменная содержит секунды 0-59.
// minutes - Переменная содержит минуты 0-59.
// hours - Переменная содержит часы 1-12.
// Hours - Переменная содержит часы 0-23.
// midday - Переменная содержит полдень 0-1 (0-am, 1-pm).
// day - Переменная содержит день месяца 1-31.
// weekday - Переменная содержит день недели 0-6 (0-воскресенье, 6-суббота).
// month - Переменная содержит месяц 1-12.
// year - Переменная содержит год 0-99.
// Unix - Переменная содержит секунды прошедшие с начала эпохи Unix.
//
// • Функция blinktime(параметр [, частота ]):
// - Данная функция указывает функции gettime("строка с параметрами"); мигать одним из параметров времени (заменять параметр пробелами).
// - Эта функция может быть полезна, для отображения на дисплее, устанавливаемого параметра времени.
// Например, при установке минут, они начинают мигать, и Вам понятно, что именно Вы устанавливаете.
// - Первым аргументом функции указывается параметр в виде числа от 0 до 8:
// 0 - не мигать.
// 1 - мигают сек.
// 2 - мигают мин.
// 3 - мигают час.
// 4 - мигают дни.
// 5 - мигают мес.
// 6 - мигает год.
// 7 - мигают дни недели.
// 8 - мигает полдень.
// - Второй аргумент функции является необязательным, он указвает частоту миганий в Гц, по умолчанию 1Гц.
// - Пример: watch.blinktime(6); // При выводе на дисплей будет мигать год с частотой по умолчанию 1Гц.
// - Пример: watch.blinktime(6, 2); // При выводе на дисплей будет мигать год с частотой 2Гц.
//
// • Функция period(минуты):
// - Устанавливает минимальный период обращения к модулю в минутах (от 0 до 255).
// - Данная функция указывает функции gettime() откуда брать текущее время: из модуля (не чаще заданного периода), или рассчитать в библиотеке (без обращения к модулю).
// - Пример: watch.period(10); // Теперь функция gettime() будет получать время от модуля только 1 раз в 10 минут.
// Ответом на все остальные запросы к функции gettime(), будет рассчитанное время: сумма времени полученного от модуля и времени прошедшего с момента его получения.
//
// • Функция gettimeUnix():
// - Функция возвращает число равное количеству секунд прошедших с начала эпохи Unix (с полуночи 1 января 1970 года).
//
// • Функция settimeUnix(секунды):
// - Функция записывает время в модуль.
// - В качестве единственного параметра функции указывается количество секунд прошедших с начала эпохи Unix.
// - Пример: watch.settimeUnix(1577836800); // Установить время на 1577836800 сек больше даты 01.01.1970г 00:00:00, что соответствует дате 01.01.2020г 00:00:00.

View File

@@ -0,0 +1,137 @@
// Пример установки системного времени (вашего компьютера) //
//
// Раскомментируйте для программной реализации шины I2C: //
// #define pin_SW_SDA 3 // Назначение любого вывода Arduino для работы в качестве линии SDA программной шины I2C.
// #define pin_SW_SCL 9 // Назначение любого вывода Arduino для работы в качестве линии SCL программной шины I2C.
// Раскомментируйте для совместимости с большинством плат: //
// #include <Wire.h> // Библиотека iarduino_RTC будет использовать методы и функции библиотеки Wire.
// Ссылки для ознакомления: //
// Подробная информация о подключении модуля к шине I2C: // http://wiki.iarduino.ru/page/i2c_connection/
// Подробная информация о функциях и методах библиотеки: // http://wiki.iarduino.ru/page/chasy-realnogo-vremeni-rtc-trema-modul/
//
#include <iarduino_RTC.h> // Подключаем библиотеку iarduino_RTC для работы с модулями реального времени.
// iarduino_RTC watch(RTC_DS1302, 2, 3, 4); // Объявляем объект watch для работы с RTC модулем на базе чипа DS1302, указывая выводы Arduino подключённые к выводам модуля RST, CLK, DAT.
// iarduino_RTC watch(RTC_DS1307); // Объявляем объект watch для работы с RTC модулем на базе чипа DS1307, используется шина I2C.
iarduino_RTC watch(RTC_DS3231); // Объявляем объект watch для работы с RTC модулем на базе чипа DS3231, используется шина I2C.
// iarduino_RTC watch(RTC_RX8025); // Объявляем объект watch для работы с RTC модулем на базе чипа RX8025, используется шина I2C.
//
// Определяем системное время: // Время загрузки скетча.
const char* strM="JanFebMarAprMayJunJulAugSepOctNovDec"; // Определяем массив всех вариантов текстового представления текущего месяца находящегося в предопределенном макросе __DATE__.
const char* sysT=__TIME__; // Получаем время компиляции скетча в формате "SS:MM:HH".
const char* sysD=__DATE__; // Получаем дату компиляции скетча в формате "MMM:DD:YYYY", где МММ - текстовое представление текущего месяца, например: Jul.
// Парсим полученные значения в массив: // Определяем массив «i» из 6 элементов типа int, содержащий следующие значения: секунды, минуты, часы, день, месяц и год компиляции скетча.
const int i[6] {(sysT[6]-'0')*10+(sysT[7]-'0'), (sysT[3]-'0')*10+(sysT[4]-'0'), (sysT[0]-'0')*10+(sysT[1]-'0'), (sysD[4]-'0')*10+(sysD[5]-'0'), ((int)memmem(strM,36,sysD,3)+3-(int)&strM[0])/3, (sysD[9]-'0')*10+(sysD[10]-'0')};
//
void setup(){ //
delay(300); // Ждем готовности модуля отвечать на запросы.
Serial.begin(9600); // Инициируем передачу данных в монитор последовательного порта на скорости 9600 бод.
watch.begin(); // Инициируем работу с модулем.
watch.settime(i[0],i[1],i[2],i[3],i[4],i[5]); // Устанавливаем время в модуль: i[0] сек, i[1] мин, i[2] час, i[3] день, i[4] месяц, i[5] год, без указания дня недели.
// watch.settime(i[0],i[1],i[2],i[3],i[4],i[5], 2); // Можно установить время с указанием дня недели, где последний параметр, это день недели (указывается вручную) в формате: 0-воскресенье, 1-понедельник, ... , 6-суббота.
} //
void loop(){ //
if(millis()%1000==0){ // Если прошла 1 секунда.
Serial.println(watch.gettime("d-m-Y, H:i:s, D")); // Выводим время.
delay(1); // Приостанавливаем скетч на 1 мс, чтоб не выводить время несколько раз за 1мс.
} //
} //
//
// ====================================================== //
// ОПИСАНИЯ ПАРАМЕТРОВ ФУНКЦИЙ:
//
// • Подключение библиотеки:
// #include <iarduino_RTC.h>
// iarduino_RTC watch(название модуля [, вывод SS/RST [, вывод CLK [, вывод DAT]]]);
// - Если модуль работает на шине I2C или SPI, то достаточно указать 1 параметр, например: iarduino_RTC watch(RTC_DS3231);
// - Если модуль работает на шине SPI, а аппаратный вывод SS занят, то номер назначенного вывода SS для модуля указывается вторым параметром, например: iarduino_RTC watch(RTC_DS1305,22);
// - Если модуль работает на трехпроводной шине, то указываются номера всех выводов, например: iarduino_RTC watch(RTC_DS1302, 2, 3, 4); // RST, CLK, DAT.
//
// • Для работы с модулями, в библиотеке реализованы 7 функции:
// - Инициировать модуль begin();
// - Указать время settime(секунды [, минуты [, часы [, день [, месяц [, год [, день недели]]]]]]);
// - Получить время gettime(["строка с параметрами"]);
// - Мигать времем blinktime(0-не_мигать / 1-мигают_сек / 2-мигают_мин / 3-мигают_час / 4-мигают_дни / 5-мигают_мес / 6-мигает_год / 7-мигают_дни_недели / 8-мигает_полдень);
// - Разгрузить шину period(минуты);
// - Получить Unix время gettimeUnix();
// - Указать Unix время settimeUnix(секунды);
//
// • Функция begin():
// - Функция инициирует модуль: проверяет регистры модуля, запускает генератор модуля и т.д.
//
// • Функция settime(секунды [, минуты [, часы [, день [, месяц [, год [, день недели]]]]]]):
// - Функция записывает время в модуль.
// - Год указывается без учёта века, в формате 0-99.
// - Часы указываются в 24-часовом формате, от 0 до 23.
// - День недели указывается в виде числа: 0-воскресенье, 1-понедельник, 2-вторник ..., 6-суббота.
// - Если предыдущий параметр надо оставить без изменений, то можно указать отрицательное или заведомо большее значение.
// - Все параметры, кроме секунд, являются необязательными. Если параметр не указан, значит он не будет изменён.
// - Пример: watch.settime(-1, 10); // Установить 10 минут, а секунды, часы и дату, оставить без изменений.
// - Пример: watch.settime(0, 5, 13); // Установить 13 часов, 5 минут, 0 секунд, а дату оставить без изменений.
// - Пример: watch.settime(-1, -1, -1, 9, 2, 17); // Установить дату 09.02.2017, а время и день недели оставить без изменений.
//
// • Функция gettime(["строка с параметрами"]):
// - Функция получает и возвращает строку заменяя описанные ниже символы на текущее время:
// - Пример: watch.gettime("d-m-Y, H:i:s, D"); // Вернуть строку с датой и временем, например: "01-10-2015, 14:00:05, Thu".
// - Пример: watch.gettime("s"); // Вернуть строку с секундами, например: "05".
// - Указанные символы идентичны символам для функции date() в PHP:
// s - Вернуть секунды от 00 до 59 (два знака).
// i - Вернуть минуты от 00 до 59 (два знака).
// h - Вернуть часы в 12-часовом формате от 01 до 12 (два знака).
// H - Вернуть часы в 24-часовом формате от 00 до 23 (два знака).
// d - Вернуть день месяца от 01 до 31 (два знака).
// w - Вернуть день недели от 0 до 6 (один знак: 0-воскресенье, 6-суббота).
// D - Вернуть день недели наименование от Mon до Sun (три знака: Mon Tue Wed Thu Fri Sat Sun).
// m - Вернуть месяц от 01 до 12 (два знака).
// M - Вернуть месяц наименование от Jan до Dec (три знака: Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec).
// Y - Вернуть год от 2000 до 2099 (четыре знака).
// y - Вернуть год от 00 до 99 (два знака).
// a - Вернуть полдень am или pm (два знака, в нижнем регистре).
// A - Вернуть полдень AM или PM (два знака, в верхнем регистре).
//
// Если требуется получить время в виде цифр, то можно вызвать функцию gettime() без параметра, после чего получить время из переменных:
// - Пример: watch.gettime();
// Serial.print(watch.Hours); Serial.print(":"); // Вывести часы.
// Serial.print(watch.minutes); Serial.print(":"); // Вывести минуты.
// Serial.print(watch.seconds); Serial.println(""); // Вывести секунды.
// seconds - Переменная содержит секунды 0-59.
// minutes - Переменная содержит минуты 0-59.
// hours - Переменная содержит часы 1-12.
// Hours - Переменная содержит часы 0-23.
// midday - Переменная содержит полдень 0-1 (0-am, 1-pm).
// day - Переменная содержит день месяца 1-31.
// weekday - Переменная содержит день недели 0-6 (0-воскресенье, 6-суббота).
// month - Переменная содержит месяц 1-12.
// year - Переменная содержит год 0-99.
// Unix - Переменная содержит секунды прошедшие с начала эпохи Unix.
//
// • Функция blinktime(параметр [, частота ]):
// - Данная функция указывает функции gettime("строка с параметрами"); мигать одним из параметров времени (заменять параметр пробелами).
// - Эта функция может быть полезна, для отображения на дисплее, устанавливаемого параметра времени.
// Например, при установке минут, они начинают мигать, и Вам понятно, что именно Вы устанавливаете.
// - Первым аргументом функции указывается параметр в виде числа от 0 до 8:
// 0 - не мигать.
// 1 - мигают сек.
// 2 - мигают мин.
// 3 - мигают час.
// 4 - мигают дни.
// 5 - мигают мес.
// 6 - мигает год.
// 7 - мигают дни недели.
// 8 - мигает полдень.
// - Второй аргумент функции является необязательным, он указвает частоту миганий в Гц, по умолчанию 1Гц.
// - Пример: watch.blinktime(6); // При выводе на дисплей будет мигать год с частотой по умолчанию 1Гц.
// - Пример: watch.blinktime(6, 2); // При выводе на дисплей будет мигать год с частотой 2Гц.
//
// • Функция period(минуты):
// - Устанавливает минимальный период обращения к модулю в минутах (от 0 до 255).
// - Данная функция указывает функции gettime() откуда брать текущее время: из модуля (не чаще заданного периода), или рассчитать в библиотеке (без обращения к модулю).
// - Пример: watch.period(10); // Теперь функция gettime() будет получать время от модуля только 1 раз в 10 минут.
// Ответом на все остальные запросы к функции gettime(), будет рассчитанное время: сумма времени полученного от модуля и времени прошедшего с момента его получения.
//
// • Функция gettimeUnix():
// - Функция возвращает число равное количеству секунд прошедших с начала эпохи Unix (с полуночи 1 января 1970 года).
//
// • Функция settimeUnix(секунды):
// - Функция записывает время в модуль.
// - В качестве единственного параметра функции указывается количество секунд прошедших с начала эпохи Unix.
// - Пример: watch.settimeUnix(1577836800); // Установить время на 1577836800 сек больше даты 01.01.1970г 00:00:00, что соответствует дате 01.01.2020г 00:00:00.

View File

@@ -0,0 +1,129 @@
// Пример установки времени модуля: //
//
// Раскомментируйте для программной реализации шины I2C: //
// #define pin_SW_SDA 3 // Назначение любого вывода Arduino для работы в качестве линии SDA программной шины I2C.
// #define pin_SW_SCL 9 // Назначение любого вывода Arduino для работы в качестве линии SCL программной шины I2C.
// Раскомментируйте для совместимости с большинством плат: //
// #include <Wire.h> // Библиотека iarduino_RTC будет использовать методы и функции библиотеки Wire.
// Ссылки для ознакомления: //
// Подробная информация о подключении модуля к шине I2C: // http://wiki.iarduino.ru/page/i2c_connection/
// Подробная информация о функциях и методах библиотеки: // http://wiki.iarduino.ru/page/chasy-realnogo-vremeni-rtc-trema-modul/
//
#include <iarduino_RTC.h> // Подключаем библиотеку iarduino_RTC для работы с модулями реального времени.
// iarduino_RTC watch(RTC_DS1302, 2, 3, 4); // Объявляем объект watch для работы с RTC модулем на базе чипа DS1302, указывая выводы Arduino подключённые к выводам модуля RST, CLK, DAT.
// iarduino_RTC watch(RTC_DS1307); // Объявляем объект watch для работы с RTC модулем на базе чипа DS1307, используется шина I2C.
iarduino_RTC watch(RTC_DS3231); // Объявляем объект watch для работы с RTC модулем на базе чипа DS3231, используется шина I2C.
// iarduino_RTC watch(RTC_RX8025); // Объявляем объект watch для работы с RTC модулем на базе чипа RX8025, используется шина I2C.
//
void setup(){ //
delay(300); // Ждем готовности модуля отвечать на запросы.
Serial.begin(9600); // Инициируем передачу данных в монитор последовательного порта на скорости 9600 бод.
watch.begin(); // Инициируем работу с модулем.
watch.settime(0,51,21,27,10,15,2); // Записываем время в модуль: 0 сек, 51 мин, 21 час, 27, октября, 2015 года, вторник.
} //
void loop(){ //
if(millis()%1000==0){ // Если прошла 1 секунда.
Serial.println(watch.gettime("d-m-Y, H:i:s, D")); // Выводим время.
delay(1); // Приостанавливаем скетч на 1 мс, чтоб не выводить время несколько раз за 1мс.
} //
} //
//
// ====================================================== //
// ОПИСАНИЯ ПАРАМЕТРОВ ФУНКЦИЙ:
//
// • Подключение библиотеки:
// #include <iarduino_RTC.h>
// iarduino_RTC watch(название модуля [, вывод SS/RST [, вывод CLK [, вывод DAT]]]);
// - Если модуль работает на шине I2C или SPI, то достаточно указать 1 параметр, например: iarduino_RTC watch(RTC_DS3231);
// - Если модуль работает на шине SPI, а аппаратный вывод SS занят, то номер назначенного вывода SS для модуля указывается вторым параметром, например: iarduino_RTC watch(RTC_DS1305,22);
// - Если модуль работает на трехпроводной шине, то указываются номера всех выводов, например: iarduino_RTC watch(RTC_DS1302, 2, 3, 4); // RST, CLK, DAT.
//
// • Для работы с модулями, в библиотеке реализованы 7 функции:
// - Инициировать модуль begin();
// - Указать время settime(секунды [, минуты [, часы [, день [, месяц [, год [, день недели]]]]]]);
// - Получить время gettime(["строка с параметрами"]);
// - Мигать времем blinktime(0-не_мигать / 1-мигают_сек / 2-мигают_мин / 3-мигают_час / 4-мигают_дни / 5-мигают_мес / 6-мигает_год / 7-мигают_дни_недели / 8-мигает_полдень);
// - Разгрузить шину period(минуты);
// - Получить Unix время gettimeUnix();
// - Указать Unix время settimeUnix(секунды);
//
// • Функция begin():
// - Функция инициирует модуль: проверяет регистры модуля, запускает генератор модуля и т.д.
//
// • Функция settime(секунды [, минуты [, часы [, день [, месяц [, год [, день недели]]]]]]):
// - Функция записывает время в модуль.
// - Год указывается без учёта века, в формате 0-99.
// - Часы указываются в 24-часовом формате, от 0 до 23.
// - День недели указывается в виде числа: 0-воскресенье, 1-понедельник, 2-вторник ..., 6-суббота.
// - Если предыдущий параметр надо оставить без изменений, то можно указать отрицательное или заведомо большее значение.
// - Все параметры, кроме секунд, являются необязательными. Если параметр не указан, значит он не будет изменён.
// - Пример: watch.settime(-1, 10); // Установить 10 минут, а секунды, часы и дату, оставить без изменений.
// - Пример: watch.settime(0, 5, 13); // Установить 13 часов, 5 минут, 0 секунд, а дату оставить без изменений.
// - Пример: watch.settime(-1, -1, -1, 9, 2, 17); // Установить дату 09.02.2017, а время и день недели оставить без изменений.
//
// • Функция gettime(["строка с параметрами"]):
// - Функция получает и возвращает строку заменяя описанные ниже символы на текущее время:
// - Пример: watch.gettime("d-m-Y, H:i:s, D"); // Вернуть строку с датой и временем, например: "01-10-2015, 14:00:05, Thu".
// - Пример: watch.gettime("s"); // Вернуть строку с секундами, например: "05".
// - Указанные символы идентичны символам для функции date() в PHP:
// s - Вернуть секунды от 00 до 59 (два знака).
// i - Вернуть минуты от 00 до 59 (два знака).
// h - Вернуть часы в 12-часовом формате от 01 до 12 (два знака).
// H - Вернуть часы в 24-часовом формате от 00 до 23 (два знака).
// d - Вернуть день месяца от 01 до 31 (два знака).
// w - Вернуть день недели от 0 до 6 (один знак: 0-воскресенье, 6-суббота).
// D - Вернуть день недели наименование от Mon до Sun (три знака: Mon Tue Wed Thu Fri Sat Sun).
// m - Вернуть месяц от 01 до 12 (два знака).
// M - Вернуть месяц наименование от Jan до Dec (три знака: Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec).
// Y - Вернуть год от 2000 до 2099 (четыре знака).
// y - Вернуть год от 00 до 99 (два знака).
// a - Вернуть полдень am или pm (два знака, в нижнем регистре).
// A - Вернуть полдень AM или PM (два знака, в верхнем регистре).
//
// Если требуется получить время в виде цифр, то можно вызвать функцию gettime() без параметра, после чего получить время из переменных:
// - Пример: watch.gettime();
// Serial.print(watch.Hours); Serial.print(":"); // Вывести часы.
// Serial.print(watch.minutes); Serial.print(":"); // Вывести минуты.
// Serial.print(watch.seconds); Serial.println(""); // Вывести секунды.
// seconds - Переменная содержит секунды 0-59.
// minutes - Переменная содержит минуты 0-59.
// hours - Переменная содержит часы 1-12.
// Hours - Переменная содержит часы 0-23.
// midday - Переменная содержит полдень 0-1 (0-am, 1-pm).
// day - Переменная содержит день месяца 1-31.
// weekday - Переменная содержит день недели 0-6 (0-воскресенье, 6-суббота).
// month - Переменная содержит месяц 1-12.
// year - Переменная содержит год 0-99.
// Unix - Переменная содержит секунды прошедшие с начала эпохи Unix.
//
// • Функция blinktime(параметр [, частота ]):
// - Данная функция указывает функции gettime("строка с параметрами"); мигать одним из параметров времени (заменять параметр пробелами).
// - Эта функция может быть полезна, для отображения на дисплее, устанавливаемого параметра времени.
// Например, при установке минут, они начинают мигать, и Вам понятно, что именно Вы устанавливаете.
// - Первым аргументом функции указывается параметр в виде числа от 0 до 8:
// 0 - не мигать.
// 1 - мигают сек.
// 2 - мигают мин.
// 3 - мигают час.
// 4 - мигают дни.
// 5 - мигают мес.
// 6 - мигает год.
// 7 - мигают дни недели.
// 8 - мигает полдень.
// - Второй аргумент функции является необязательным, он указвает частоту миганий в Гц, по умолчанию 1Гц.
// - Пример: watch.blinktime(6); // При выводе на дисплей будет мигать год с частотой по умолчанию 1Гц.
// - Пример: watch.blinktime(6, 2); // При выводе на дисплей будет мигать год с частотой 2Гц.
//
// • Функция period(минуты):
// - Устанавливает минимальный период обращения к модулю в минутах (от 0 до 255).
// - Данная функция указывает функции gettime() откуда брать текущее время: из модуля (не чаще заданного периода), или рассчитать в библиотеке (без обращения к модулю).
// - Пример: watch.period(10); // Теперь функция gettime() будет получать время от модуля только 1 раз в 10 минут.
// Ответом на все остальные запросы к функции gettime(), будет рассчитанное время: сумма времени полученного от модуля и времени прошедшего с момента его получения.
//
// • Функция gettimeUnix():
// - Функция возвращает число равное количеству секунд прошедших с начала эпохи Unix (с полуночи 1 января 1970 года).
//
// • Функция settimeUnix(секунды):
// - Функция записывает время в модуль.
// - В качестве единственного параметра функции указывается количество секунд прошедших с начала эпохи Unix.
// - Пример: watch.settimeUnix(1577836800); // Установить время на 1577836800 сек больше даты 01.01.1970г 00:00:00, что соответствует дате 01.01.2020г 00:00:00.

View File

@@ -0,0 +1,129 @@
// Пример установки времени модуля значением Unix time: //
//
// Раскомментируйте для программной реализации шины I2C: //
// #define pin_SW_SDA 3 // Назначение любого вывода Arduino для работы в качестве линии SDA программной шины I2C.
// #define pin_SW_SCL 9 // Назначение любого вывода Arduino для работы в качестве линии SCL программной шины I2C.
// Раскомментируйте для совместимости с большинством плат: //
// #include <Wire.h> // Библиотека iarduino_RTC будет использовать методы и функции библиотеки Wire.
// Ссылки для ознакомления: //
// Подробная информация о подключении модуля к шине I2C: // http://wiki.iarduino.ru/page/i2c_connection/
// Подробная информация о функциях и методах библиотеки: // http://wiki.iarduino.ru/page/chasy-realnogo-vremeni-rtc-trema-modul/
//
#include <iarduino_RTC.h> // Подключаем библиотеку iarduino_RTC для работы с модулями реального времени.
// iarduino_RTC watch(RTC_DS1302, 2, 3, 4); // Объявляем объект watch для работы с RTC модулем на базе чипа DS1302, указывая выводы Arduino подключённые к выводам модуля RST, CLK, DAT.
// iarduino_RTC watch(RTC_DS1307); // Объявляем объект watch для работы с RTC модулем на базе чипа DS1307, используется шина I2C.
iarduino_RTC watch(RTC_DS3231); // Объявляем объект watch для работы с RTC модулем на базе чипа DS3231, используется шина I2C.
// iarduino_RTC watch(RTC_RX8025); // Объявляем объект watch для работы с RTC модулем на базе чипа RX8025, используется шина I2C.
//
void setup(){ //
delay(300); // Ждем готовности модуля отвечать на запросы.
Serial.begin(9600); // Инициируем передачу данных в монитор последовательного порта на скорости 9600 бод.
watch.begin(); // Инициируем работу с модулем.
watch.settimeUnix(1577836800); // Записываем время в модуль: 01.01.1970 00:00:00 (дата начала эпохи Unix) + 1577836800 сек = 01.01.2020 00:00:00.
} //
void loop(){ //
if(millis()%1000==0){ // Если прошла 1 секунда.
Serial.println(watch.gettime("d-m-Y, H:i:s, D")); // Выводим время.
delay(1); // Приостанавливаем скетч на 1 мс, чтоб не выводить время несколько раз за 1мс.
} //
} //
//
// ====================================================== //
// ОПИСАНИЯ ПАРАМЕТРОВ ФУНКЦИЙ:
//
// • Подключение библиотеки:
// #include <iarduino_RTC.h>
// iarduino_RTC watch(название модуля [, вывод SS/RST [, вывод CLK [, вывод DAT]]]);
// - Если модуль работает на шине I2C или SPI, то достаточно указать 1 параметр, например: iarduino_RTC watch(RTC_DS3231);
// - Если модуль работает на шине SPI, а аппаратный вывод SS занят, то номер назначенного вывода SS для модуля указывается вторым параметром, например: iarduino_RTC watch(RTC_DS1305,22);
// - Если модуль работает на трехпроводной шине, то указываются номера всех выводов, например: iarduino_RTC watch(RTC_DS1302, 2, 3, 4); // RST, CLK, DAT.
//
// • Для работы с модулями, в библиотеке реализованы 7 функции:
// - Инициировать модуль begin();
// - Указать время settime(секунды [, минуты [, часы [, день [, месяц [, год [, день недели]]]]]]);
// - Получить время gettime(["строка с параметрами"]);
// - Мигать времем blinktime(0-не_мигать / 1-мигают_сек / 2-мигают_мин / 3-мигают_час / 4-мигают_дни / 5-мигают_мес / 6-мигает_год / 7-мигают_дни_недели / 8-мигает_полдень);
// - Разгрузить шину period(минуты);
// - Получить Unix время gettimeUnix();
// - Указать Unix время settimeUnix(секунды);
//
// • Функция begin():
// - Функция инициирует модуль: проверяет регистры модуля, запускает генератор модуля и т.д.
//
// • Функция settime(секунды [, минуты [, часы [, день [, месяц [, год [, день недели]]]]]]):
// - Функция записывает время в модуль.
// - Год указывается без учёта века, в формате 0-99.
// - Часы указываются в 24-часовом формате, от 0 до 23.
// - День недели указывается в виде числа: 0-воскресенье, 1-понедельник, 2-вторник ..., 6-суббота.
// - Если предыдущий параметр надо оставить без изменений, то можно указать отрицательное или заведомо большее значение.
// - Все параметры, кроме секунд, являются необязательными. Если параметр не указан, значит он не будет изменён.
// - Пример: watch.settime(-1, 10); // Установить 10 минут, а секунды, часы и дату, оставить без изменений.
// - Пример: watch.settime(0, 5, 13); // Установить 13 часов, 5 минут, 0 секунд, а дату оставить без изменений.
// - Пример: watch.settime(-1, -1, -1, 9, 2, 17); // Установить дату 09.02.2017, а время и день недели оставить без изменений.
//
// • Функция gettime(["строка с параметрами"]):
// - Функция получает и возвращает строку заменяя описанные ниже символы на текущее время:
// - Пример: watch.gettime("d-m-Y, H:i:s, D"); // Вернуть строку с датой и временем, например: "01-10-2015, 14:00:05, Thu".
// - Пример: watch.gettime("s"); // Вернуть строку с секундами, например: "05".
// - Указанные символы идентичны символам для функции date() в PHP:
// s - Вернуть секунды от 00 до 59 (два знака).
// i - Вернуть минуты от 00 до 59 (два знака).
// h - Вернуть часы в 12-часовом формате от 01 до 12 (два знака).
// H - Вернуть часы в 24-часовом формате от 00 до 23 (два знака).
// d - Вернуть день месяца от 01 до 31 (два знака).
// w - Вернуть день недели от 0 до 6 (один знак: 0-воскресенье, 6-суббота).
// D - Вернуть день недели наименование от Mon до Sun (три знака: Mon Tue Wed Thu Fri Sat Sun).
// m - Вернуть месяц от 01 до 12 (два знака).
// M - Вернуть месяц наименование от Jan до Dec (три знака: Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec).
// Y - Вернуть год от 2000 до 2099 (четыре знака).
// y - Вернуть год от 00 до 99 (два знака).
// a - Вернуть полдень am или pm (два знака, в нижнем регистре).
// A - Вернуть полдень AM или PM (два знака, в верхнем регистре).
//
// Если требуется получить время в виде цифр, то можно вызвать функцию gettime() без параметра, после чего получить время из переменных:
// - Пример: watch.gettime();
// Serial.print(watch.Hours); Serial.print(":"); // Вывести часы.
// Serial.print(watch.minutes); Serial.print(":"); // Вывести минуты.
// Serial.print(watch.seconds); Serial.println(""); // Вывести секунды.
// seconds - Переменная содержит секунды 0-59.
// minutes - Переменная содержит минуты 0-59.
// hours - Переменная содержит часы 1-12.
// Hours - Переменная содержит часы 0-23.
// midday - Переменная содержит полдень 0-1 (0-am, 1-pm).
// day - Переменная содержит день месяца 1-31.
// weekday - Переменная содержит день недели 0-6 (0-воскресенье, 6-суббота).
// month - Переменная содержит месяц 1-12.
// year - Переменная содержит год 0-99.
// Unix - Переменная содержит секунды прошедшие с начала эпохи Unix.
//
// • Функция blinktime(параметр [, частота ]):
// - Данная функция указывает функции gettime("строка с параметрами"); мигать одним из параметров времени (заменять параметр пробелами).
// - Эта функция может быть полезна, для отображения на дисплее, устанавливаемого параметра времени.
// Например, при установке минут, они начинают мигать, и Вам понятно, что именно Вы устанавливаете.
// - Первым аргументом функции указывается параметр в виде числа от 0 до 8:
// 0 - не мигать.
// 1 - мигают сек.
// 2 - мигают мин.
// 3 - мигают час.
// 4 - мигают дни.
// 5 - мигают мес.
// 6 - мигает год.
// 7 - мигают дни недели.
// 8 - мигает полдень.
// - Второй аргумент функции является необязательным, он указвает частоту миганий в Гц, по умолчанию 1Гц.
// - Пример: watch.blinktime(6); // При выводе на дисплей будет мигать год с частотой по умолчанию 1Гц.
// - Пример: watch.blinktime(6, 2); // При выводе на дисплей будет мигать год с частотой 2Гц.
//
// • Функция period(минуты):
// - Устанавливает минимальный период обращения к модулю в минутах (от 0 до 255).
// - Данная функция указывает функции gettime() откуда брать текущее время: из модуля (не чаще заданного периода), или рассчитать в библиотеке (без обращения к модулю).
// - Пример: watch.period(10); // Теперь функция gettime() будет получать время от модуля только 1 раз в 10 минут.
// Ответом на все остальные запросы к функции gettime(), будет рассчитанное время: сумма времени полученного от модуля и времени прошедшего с момента его получения.
//
// • Функция gettimeUnix():
// - Функция возвращает число равное количеству секунд прошедших с начала эпохи Unix (с полуночи 1 января 1970 года).
//
// • Функция settimeUnix(секунды):
// - Функция записывает время в модуль.
// - В качестве единственного параметра функции указывается количество секунд прошедших с начала эпохи Unix.
// - Пример: watch.settimeUnix(1577836800); // Установить время на 1577836800 сек больше даты 01.01.1970г 00:00:00, что соответствует дате 01.01.2020г 00:00:00.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,196 @@
Модуль часов реального времени RX-8025 SA/NB:
НАЗНАЧЕНИЕ ВЫВОДОВ:
+-------+-----+----------------------------------------------------------------------------------------------------------------------------------------------+
| Вывод | I/O | Назначение: |
+-------+-----+----------------------------------------------------------------------------------------------------------------------------------------------+
| SCL | I | Линия тактирования шины I2C. |
| SDA | I/O | Линия данных шины I2C. |
+-------+-----+----------------------------------------------------------------------------------------------------------------------------------------------+
| FOUT | O | Выход тактового сигнала (32,768 кГц), работает при наличии 1 на выводе FOE. Если на FOE уровень 0 или OPEN, то FOUT=0. |
| FOE | I | Вход управления выводом FOUT. Если FOE=1 то FOUT=32.768кГц. Если FOE=0 то FOUT=0. Вывод FOE толерантен к 5.5В, он внутрисхемно прижат к GND. |
+-------+-----+----------------------------------------------------------------------------------------------------------------------------------------------+
| /INTA | O | N-канальный выходом с открытым стоком, предназначен для вывода прерываний будильника Alarm_D и периодических прерываний. |
| /INTB | O | N-канальный выходом с открытым стоком, предназначен для вывода прерываний будильника Alarm_W. |
+-------+-----+----------------------------------------------------------------------------------------------------------------------------------------------+
| TEST | | Вывод используется производителем для тестирования. Обязательно подключите к Vcc. |
| VDD | | Vcc от +1.7В до +5.5В, номинально 3.0В. |
| GND | | GND. |
| N.C. | | На чипе RX-8025NB контакты N.C. соеденены друг с другом. Оставьте их неподключёнными или подключите все к Vcc или все к GND. |
+-------+-----+----------------------------------------------------------------------------------------------------------------------------------------------+
ЛОГИЧЕСКИЕ УРОВНИ:
Vin 0 = 0В...0,2Vcc
Vin 1 = 0,8Vcc...5,5В
ФУНКЦИИ МОДУЛЯ:
1) ТЕКУЩЕЕ ВРЕМЯ:
Модуль позволяет устанавливать, синхронизировать и отображать данные, включая год (последние две цифры), месяц, дату, день, час, минуту и ​​секунду.
Любой (двузначный) год, кратный 4, считается високосным и рассчитывается автоматически до 2099 года.
2) ФУНКЦИЯ РЕГУЛИРОВКИ ТОЧНОСТИ ЧАСОВ:
Точность часов можно отрегулировать вперед или назад изменив частоту с кварца 32,768 кГц с шагом ±3,05 × 10^6.
Для регулировки требуется записать в регистр Digital Offset знаковое значение в 7-битном двоичном коде (от 62 до +63).
На предделитель часов поступит частота = 32768 Гц - DigitalOffset * 3,05 × 10^6.
Примечание: Можно настроить только точность часов. Настройки не влияют на выходной сигнал 32,768 кГц с вывода FOUT.
3) ФУНКЦИЯ ПЕРИОДИЧЕСКОГО ПРЕРЫВАНИЯ:
В дополнение к функции будильника Alarm_D через вывод /INTA могут выводиться периодические прерывания.
Периодическое прерывание настраивается битами CT2-CT0 регистра Control-1.
При срабатывании прерывания устанавливается флаг CTFG регистра Control-2, а на выводе /INTA устанавливается уровень логического 0.
Сброс флага CTFG освобождает вывод /INTA до следующего прерывания.
Биты CT2-CT0 позволяют выбрать частоту прерываний: 2 Гц (пол секунды), 1 Гц (ежесекундно), 1/60 Гц (ежеминутно), ежечасно или ежемесячно.
4) ФУНКЦИИ БУДИЛЬНИКА:
Модуль оснащен двумя будильниками (Alarm_D и Alarm_W), которые выводят сигнал прерывания (на выводы /INTA, /INTB) при совпадении времени.
• Будильник Alarm_W на основе дня недели, часа и минут, выводит сигнал прерывания через вывод /INTB. Будильник позволяет выбрать несколько деней недели.
Будильник срабатывает если он включён битом WALE регистра Control-1, при совпадении времени будильника с текущим временем.
При срабатывании будильника устанавливается флаг WAFG регистра Control-2, а на выводе /INTB устанавливается уровень логического 0.
Сброс флага WAFG освобождает вывод /INTB до следующего прерывания.
Если для будильника установить текущее время, то он сработает не немедленно, а при следующем совпадении времени.
Для установки нового времени будильника рекомендуется его отключить WALE=0, установить время будильника Alarm_W Minute/Hour/Day, сбросить прерывание будильника WAFG=0, включить будильник WALE=1.
• Будильник Alarm_D использует только часы и минуты, выводит сигнал прерывания через вывод /INTA.
Будильник срабатывает если он включён битом DALE регистра Control-1, при совпадении времени будильника с текущим временем.
При срабатывании будильника устанавливается флаг DAFG регистра Control-2, в на выводе /INTA устанавливается уровень логического 0.
Сброс флага DAFG освобождает вывод /INTA до следующего прерывания.
Если для будильника установить текущее время, то он сработает не немедленно, а при следующем совпадении времени.
Для установки нового времени будильника рекомендуется его отключить DALE=0, установить время будильника Alarm_D Minute/Hour, сбросить прерывание будильника DAFG=0, включить будильник DALE=1.
5) ФУНКЦИЯ ОБНАРУЖЕНИЯ ОСТАНОВКИ КОЛЕБАНИЙ:
При обнаружении остановки колебаний устанавливается флаг /XST регистра Control-2 (активный уровень 0) и остаётся в таком состоянии до его сброва в 1 по шине I2C.
Это позволяет определить, что данные часов стали некорректными.
6) ФУНКЦИЯ ОБНАРУЖЕНИЯ ПАДЕНИЯ МОЩНОСТИ (КОНТРОЛЬ НАПРЯЖЕНИЯ):
При снижении Vcc ниже порогового уровня, устанавливается флаг VDET регистра Control-2 и остаётся в таком состоянии до его перезаписи в 0 по шине I2C.
Выборка напряжения выполняется один раз в секунду.
Пороговый уровень выбирается битом VDSL регистра Control-2, доступны значения 1.3В и 2.1 В.
7) ФУНКЦИЯ ОБНАРУЖЕНИЯ СБРОСА ПРИ ВКЛЮЧЕНИИ ПИТАНИЯ:
При подаче питания происходит сброс регистров в значение по умолчанию и установка флага PON регистра Control-2 в значение 1, это значение остается до его перезаписи в 0 по шине I2C.
Пока флаг PON установлен в 1, все биты регистров Digital-Offset, Control-1 и Control-2 (кроме PON и /XST) сбрасываются в «0». Это также приводит к остановке прерываний на выводах /INTA и /INTB.
Для начала работы необходимо сбросить флаг PON в 0, что перезапустит функцию обнаружения сброса при включении питания.
8) ТАКТОВЫЙ ВЫХОД 32,768 кГц
Тактовая частота 32,768 кГц (с точностью, равной точности встроенного кварцевого генератора) может выводиться через вывод с открытым стоком FOUT.
Вывод FOUT включается подачей 1 на вход FOE. Если на вход FOE подать 0, то и на выходе FOUT будет 0.
9) ИНТЕРФЕЙС
Данные считываются и записываются через интерфейс шины I2C. Максимальная тактовая частота 400 кГц (при Vcc ≥ 1,7 В).
КАРТА РЕГИСТРОВ:
+-------+-------------------+---------------------------------------------------------------------------------------------------+
|Address| Function | 7 6 5 4 3 2 1 0 |
+-------+-------------------+---------------------------------------------------------------------------------------------------+
| 0 | Seconds | (0) S40 S20 S10 S8 S4 S2 S1 |
| 1 | Minutes | (0) M40 M20 M10 M8 M4 M2 M1 |
| 2 | Hours | (0) (0) H20 P,/A H10 H8 H4 H2 H1 |
| 3 | Days | (0) (0) (0) (0) (0) W4 W2 W1 | Так написано в datasheet
| | | (0) Сб Пт Чт Ср Вт Пн Вс | А так на самом деле. И модуль не определяет день недели, а тупо его увеличивает после 23:59:59
| 4 | Days | (0) (0) D20 D10 D8 D4 D2 D1 |
| 5 | Months | «0» (0) (0) MO10 MO8 MO4 MO2 MO1 |
| 6 | Years | Y80 Y40 Y20 Y10 Y8 Y4 Y2 Y1 |
+-------+-------------------+---------------------------------------------------------------------------------------------------+
| 7 | Digital Offset | «0» F6 F5 F4 F3 F2 F1 F0 | Значения по умолчанию (с момента установки бита PON) 00000000
+-------+-------------------+---------------------------------------------------------------------------------------------------+
| 8 | Alarm_W Minute | (0) WM40 WM20 WM10 WM8 WM4 WM2 WM1 |
| 9 | Alarm_W Hour | (0) (0) WH20 WP,/A WH10 WH8 WH4 WH2 WH1 |
| A | Alarm_W Day | (0) WW6 WW5 WW4 WW3 WW2 WW1 WW0 |
| B | Alarm_D Minute | (0) DM40 DM20 DM10 DM8 DM4 DM2 DM1 |
| C | Alarm_D Hour | (0) (0) DH20 DP,/A DH10 DH8 DH4 DH2 DH1 |
+-------+-------------------+---------------------------------------------------------------------------------------------------+
| D | Reserved | - - - - - - - - |
+-------+-------------------+---------------------------------------------------------------------------------------------------+
| E | Control-1 | WALE DALE /12,24 • TEST CT2 CT1 CT0 | Значения по умолчанию (с момента установки бита PON) 00000000
| F | Control-2 | VDSL VDET /XST PON • CTFG WAFG DAFG | Значения по умолчанию (с момента установки бита PON) 00?10000
+-------+-------------------+---------------------------------------------------------------------------------------------------+
Осторожно:
Бит PON Является битом флага сброса при включении питания. Устанавливается в 1, когда происходит сброс, например, при первоначальном включении питания или при восстановлении после падения напряжения питания.
При этом все биты в регистрах Control-1 и Control-2, кроме битов PON и /XST, сбрасываются в 0.
Примечание: Пока бит PON не установится в 1 все остальные значения регистров не определены, поэтому обязательно выполните сброс перед использованием модуля.
Кроме того, избегайте ввода неверных данных о дате и времени, так как работа часов не гарантируется, если данные о времени неверны.
Бит TEST Используется производителем для тестирования. Убедитесь, что для этого бита установлено значение «0».
Reserved Регистр с адресом D используется для заводских настроек. Не читайте и не записывайте в этот регистр.
Биты «0» Должны быть установлены в 0 при записи. Их значение при чтении будет 0.
Биты (0) Доступны только для чтения. Их значение при чтении всегда равно 0.
Биты • Являются битами ОЗУ, которые могут содержать любое значение и доступны для чтения/записи. Однако эти биты сбрасываются в 0, когда значение бита PON равно 1.
0) Seconds Регистр счётчика секунд в двоично-десятичном формате (0b X101 1001 = 59сек).
1) Minutes Регистр счётчика минут в двоично-десятичном формате (0b X101 1001 = 59мин).
2) Hours Регистр счётчика часов в двоично-десятичном формате (0b XX01 1001 = 19час).
H20 P,/A В 24-часовом формате бит функционирует как H20
В 12-часовом формате бит функционирует как P,/A (0-AM, 1-PM).
Формат часов задаёт бит /12,24 регистра Control-1.
3) Days Регистр счётчика дней недели (1-Пн, 6-Сб, 0-Вс). Значение 7-недопустимо. Так написано в datasheet, типа у регистра активны только 3 младших бита формирующих число от 0 до 6.
А на самом деле регистр хранит 7 значащих бит. Установленный бит указывает на день недели: 0-бит Вс, 1-бит Пн, 2-бит Вт, ... 6-бит Сб, 7-бит всегда 0.
4) Days Регистр счётчика дней в двоично-десятичном формате (0b XX11 0001 = 31день).
5) Months Регистр счётчика месяцев в двоично-десятичном формате (0b XXX1 0010 = 12мес = декабрь).
6) Years Регистр счётчика лет в двоично-десятичном формате (0b 1001 1001 = 99год).
7) Digital Offset Регистр регулировки точности часов. Хранит знаковое значение в 7-битном двоичном коде (от 62 = 0bX1000010, до +63 = 0bX0111111)
Частота поступающая на предделитель = 32768 Гц - DigitalOffset * 3,05 × 10^6. (32768Гц62*3,05×10^6 = 32768Гц+189.1×10^6)
Функция цифрового смещения корректирует количество тактовых импульсов каждые 20 сек. (в 00сек, 20сек и 40сек каждой минуты)
Частота на выходе FOUT не изменяется.
8) Alarm_W Minute Регистр минут будильника Alarm_W. Формат хранения данных аналогичен регистру Minutes.
9) Alarm_W Hour Регистр часов будильника Alarm_W. Формат хранения данных аналогичен регистру Hours.
WH20 WP,/A В 24-часовом формате бит функционирует как WH20
В 12-часовом формате бит функционирует как WP,/A (0-AM, 1-PM).
Формат часов задаёт бит /12,24 регистра Control-1.
A) Alarm_W Day Регистр дней недели будильника Alarm_W. Позволяет выбрать 1 до 7 дней недели.
WW6-WW0 WW1-Пн, WW2-Вт, WW3-ср, WW4-Чт, WW5-Пт, WW6-Сб, WW0-Вс.
Если все биты установлены в 0, то будильник Alarm_W выключен.
B) Alarm_D Minute Регистр минут будильника Alarm_D. Формат хранения данных аналогичен регистру Minutes.
C) Alarm_D Hour Регистр часов будильника Alarm_D. Формат хранения данных аналогичен регистру Hours.
DH20 DP,/A В 24-часовом формате бит функционирует как DH20
В 12-часовом формате бит функционирует как DP,/A (0-AM, 1-PM).
Формат часов задаёт бит /12,24 регистра Control-1.
E) Control-1 Регистр управления 1
WALE Бит разрешения работы будильника Alarm_W.
0 - будильник Alarm_W отключён.
1 - будильник Alarm_W включён, при совпадении времени на выводе /INTB появляется прерывание.
DALE Бит разрешения работы будильника Alarm_D.
0 - будильник Alarm_D отключён.
1 - будильник Alarm_D включён, при совпадении времени на выводе /INTA появляется прерывание.
/12,24 Бит выбора формата часов текущего времени и будильников.
0 - Часы текущего времени и будильников хранятся в 12-часовом формате.
1 - Часы текущего времени и будильников хранятся в 24-часовом формате.
TEST
CT2-CT0 Биты настройки периодического прерывания на выводе /INTA.
000 Периодическое прерывание отключено, вывод /INTA отключён.
001 Периодическое прерывание отключено, на выволе /INTA уровень 0.
010 - Периодическое прерывание работает на частоте 2 Гц с коэффициентом заполнения 50%.
011 - Периодическое прерывание работает на частоте 1 Гц с коэффициентом заполнения 50%.
100 - Периодическое прерывание срабатывает в начале каждой секунды.
101 - Периодическое прерывание срабатывает в начале 00 секунды каждой минуты.
110 - Периодическое прерывание срабатывает в начале 00 секунды, 00 минуты каждого часа.
111 - Периодическое прерывание срабатывает в начале 00 секунды, 00 минуты 00 часа каждого первого числа месяца.
F) Control-2 Регистр управления 2
VDSL Выбор порогового значения напряжения для функции обнаружения падения мощности.
0 - 2,1 В в качестве порога функции обнаружения падения мощности.
1 - 1,3 В в качестве порога функции обнаружения падения мощности.
VDET Флаг функции обнаружения падения мощности. Устанавливается в 1 после падения Vcc ниже порога.
Чтение: 0 - Падение мощности не обнаружено.
1 - Обнаружено падение Vcc ниже порогового. Флаг остаётся 1 до его перезаписи в 0 по шине I2C.
Запись: 0 - Сброс флага в 0 и перезапуск функции обнаружения падения мощности.
1 - ЗАПРЕЩЕНО! НЕ ЗАПИСЫВАЙТЕ 1 ДАЖЕ ЕСЛИ ЭТО НЕ ИМЕЕТ ЭФФЕКТА.
/XST Флаг функции обнаружения остановки колебаний.
Чтение: 0 - Обнаружена остановка колебаний. Флаг остаётся 0 до его перезаписи в 1 по шине I2C.
1 - Остановка колебаний не обнаружено.
Запись: 0 - ЗАПРЕЩЕНО! НЕ ЗАПИСЫВАЙТЕ 0 ДАЖЕ ЕСЛИ ЭТО НЕ ИМЕЕТ ЭФФЕКТА.
1 - Сброс флага в 1 и перезапуск функции обнаружения остановки колебаний.
PON Флаг функции обнаружения сброса при включении питания.
Чтение: 0 - Сброс при включении питания не обнаружен.
1 - Обнаружен сброс при включении питания. Флаг остаётся 1 до его перезаписи в 0 по шине I2C.
Пока флаг установлен в 1, все биты регистров Digital-Offset, Control-1 и Control-2 (кроме PON и /XST) сбрасываются в «0». Это также приводит к остановке прерываний на выводах /INTA и /INTB.
Запись: 0 - Сброс флага в 0 и перезапуск функции обнаружения сброса при включении питания.
1 - ЗАПРЕЩЕНО! НЕ ЗАПИСЫВАЙТЕ 1 ДАЖЕ ЕСЛИ ЭТО НЕ ИМЕЕТ ЭФФЕКТА.
• Бит является битом ОЗУ, он может содержать любое значение и доступен для чтения/записи. Бит сбрасывается в 0 если обнаружен сброс при включении питания (PON=1).
CTFG Флаг наличия периодического прерывания на выводе /INTA.
Чтение: 0 - На выходе /INTA нет сигнала периодического прерывания.
1 - На выходе /INTA установлен сигнал периодического прерывания.
Запись: 0 - Сброс флага в 0 и освобождение /INTA до следующего прерывания. Сброс возможен если не поступает очередное прерывание и не срабатывает будильник Alarm_D.
1 - ЗАПРЕЩЕНО! НЕ ЗАПИСЫВАЙТЕ 1 ДАЖЕ ЕСЛИ ЭТО НЕ ИМЕЕТ ЭФФЕКТА.
WAFG Флаг будильника Alarm_W. Значение флага актуально если бит WALE регистра Control-1 равен 1.
Чтение: 0 - Будильник Alarm_W не сработал или бит WALE регистра Control-1 равен 0.
1 - Сработал будильник Alarm_W. Флаг остаётся 1 до его перезаписи в 0 по шине I2C.
Запись: 0 - Сброс флага в 0 и отключение прерывания на выводе /INTB.
1 - ЗАПРЕЩЕНО! НЕ ЗАПИСЫВАЙТЕ 1 ДАЖЕ ЕСЛИ ЭТО НЕ ИМЕЕТ ЭФФЕКТА.
DAFG Флаг будильника Alarm_D. Значение флага актуально если бит DALE регистра Control-1 равен 1.
Чтение: 0 - Будильник Alarm_D не сработал или бит DALE регистра Control-1 равен 0.
1 - Сработал будильник Alarm_D. Флаг остаётся 1 до его перезаписи в 0 по шине I2C.
Запись: 0 - Сброс флага в 0 и отключение прерывания на выводе /INTA.
1 - ЗАПРЕЩЕНО! НЕ ЗАПИСЫВАЙТЕ 1 ДАЖЕ ЕСЛИ ЭТО НЕ ИМЕЕТ ЭФФЕКТА.

View File

@@ -0,0 +1,30 @@
# ####################################################
# СИНТАКСИЧЕСКАЯ РАСКРАСКА ДЛЯ БИБИЛИОТЕКИ:
# iarduino_RTC
# ####################################################
# ТИПЫ ДАННЫХ: (KEYWORD1)
iarduino_RTC KEYWORD1
# ####################################################
# МЕТОДЫ И ФУНКЦИИ: (KEYWORD2)
begin KEYWORD2
settime KEYWORD2
gettime KEYWORD2
settimeUnix KEYWORD2
gettimeUnix KEYWORD2
blinktime KEYWORD2
period KEYWORD2
seconds KEYWORD2
minutes KEYWORD2
hours KEYWORD2
Hours KEYWORD2
midday KEYWORD2
day KEYWORD2
weekday KEYWORD2
month KEYWORD2
year KEYWORD2
Unix KEYWORD2
# ####################################################
# КОНСТАНТЫ: (LITERAL1)
RTC_DS1302 LITERAL1
RTC_DS1307 LITERAL1
RTC_DS3231 LITERAL1

View File

@@ -0,0 +1,10 @@
name = iarduino RTC (часы реального времени)
version = 2.0.0
author = iarduino <shop@iarduino.ru>
maintainer = Панькин Павел <shop@iarduino.ru>
sentence = Библиотека для работы с часами реального времени.
paragraph = Поддерживает часы на чипах: DS1302, DS1307, DS3231, RX8025, есть возможность добавлять часы на других чипах. Библиотека позволяет устанавливать и считывать дату/время. Преимуществом данной библиотеки является удобная реализация получения времени. Считывание даты/времени можно осуществить как через переменные (year, month, day, hours, minutes, seconds и т.д.), так и одной строкой в которую попадут значения в соответствии с указанным Вами шаблоном.
category = Timing
url = http://iarduino.ru/file/235.html
architectures = avr,esp8266,esp32
includes = iarduino_RTC.h

View File

@@ -0,0 +1,134 @@
#include "iarduino_RTC.h"
// Вывод даты и времени
char* iarduino_RTC::gettime(String i){char j[i.length()+1]; i.toCharArray(j, i.length()); j[i.length()]=0; return gettime(j);}
char* iarduino_RTC::gettime(const char* i){
uint8_t j, k, n; bool f; // Объявляем локальные переменные
if(valRequest > millis()){valRequest=0;} // Избавляемся от переполнения millis()
// Получаем текущее время:
if(valPeriod == 0) {funcReadTime();}else // Если минимальный период опроса модуля == 0 минут, то получаем время из регистров модуля, иначе ...
if(valRequest == 0 || (valPeriod+valRequest <= millis())) {funcReadTime();}else // Если время последнего опроса модуля превысило минимальный период опроса модуля, то получаем время из регистров модуля, иначе ...
{funcCalculationTime();} // Получаем время без обращения к модулю (время рассчитывая исходя из millis и valRequest)
funcSetMoreTime(); // Преобразуем переменные не читаемые из модуля
// Вычисляем размер блока памяти под строку с ответом:
n=strlen(i)+1; // Определяем размер равный введённой строке (i) + 1 символ конца строки
for(j=0; j<strlen(i); j++) { // Проходим по символам полученной строки
for(k=0; k<strlen(charInput); k++) { // Проходим по служебным символам строки charInput
if (i[j]==charInput[k]) { // Если символы обеих строк совпали, то ...
if(k>0){n++;} if(k>9){n++;} if(k>11){n++;} // Увеличиваем размер (n) в соостветствии со значениём найденного служебного символа
}}}
// Выделяем блок памяти под строку с ответом:
free(charReturn); // Освобождаем ранее созданный блок памяти
charReturn = (char*) malloc(n); // Выделяем новый блок памяти размером n байт
// Заполняем выделенный блок памяти:
n=0; // Определяем позицию в блоке памяти для следующего подставляемого значения
for(j=0; j<strlen(i); j++) { // Проходим по символам полученной строки
if(i[j]==charInput[0] /* w */ ) {funcFillChar( weekday ,0,n,7); n+=1;}else // Подставляем день недели от 0 до 6 (один знак: 0-воскресенье, 6-суббота)
if(i[j]==charInput[1] /* a */ ) {funcFillChar( midday*2 ,2,n,8); n+=2;}else // Подставляем полдень am или pm (два знака, в нижнем регистре)
if(i[j]==charInput[2] /* A */ ) {funcFillChar((midday+2)*2 ,2,n,8); n+=2;}else // Подставляем полдень AM или PM (два знака, в верхнем регистре)
if(i[j]==charInput[3] /* d */ ) {funcFillChar( day ,1,n,4); n+=2;}else // Подставляем день месяца от 01 до 31 (два знака)
if(i[j]==charInput[4] /* h */ ) {funcFillChar( hours ,1,n,3); n+=2;}else // Подставляем часы от 01 до 12 (два знака)
if(i[j]==charInput[5] /* H */ ) {funcFillChar( Hours ,1,n,3); n+=2;}else // Подставляем часы от 00 до 23 (два знака)
if(i[j]==charInput[6] /* i */ ) {funcFillChar( minutes ,1,n,2); n+=2;}else // Подставляем минуты от 00 до 59 (два знака)
if(i[j]==charInput[7] /* m */ ) {funcFillChar( month ,1,n,5); n+=2;}else // Подставляем месяц от 01 до 12 (два знака)
if(i[j]==charInput[8] /* s */ ) {funcFillChar( seconds ,1,n,1); n+=2;}else // Подставляем секунды от 00 до 59 (два знака)
if(i[j]==charInput[9] /* y */ ) {funcFillChar( year ,1,n,6); n+=2;}else // Подставляем год от 00 до 99 (два знака)
if(i[j]==charInput[10] /* M */ ) {funcFillChar((month+6)*3 ,3,n,5); n+=3;}else // Подставляем имя месяца от Jan до Dec (три знака: Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec)
if(i[j]==charInput[11] /* D */ ) {funcFillChar( weekday*3 ,3,n,7); n+=3;}else // Подставляем имя деня недели от Mon до Sun (три знака: Mon Tue Wed Thu Fri Sat Sun)
if(i[j]==charInput[12] /* Y */ ) {funcFillChar( year ,4,n,6); n+=4;}else // Подставляем год от 2000 до 2099 (четыре знака)
{charReturn[n]=i[j]; n+=1;} // Если символ полученной строки не совпал со служебными, то подставляем его в блок памяти как есть, без изменений
} charReturn[n]='\0'; return charReturn; // Устанавливаем символ конца строки и возвращаем указатель на блок памяти с результатом
}
// Заполняем значением определённую позицию блока памяти:
void iarduino_RTC::funcFillChar(uint8_t i, uint8_t j, uint8_t n, uint8_t k){ // (данные, тип данных, позиция для вставки, мигание)
bool f=valBlink==k; if((millis()%valFrequency)<(valFrequency/2)){f=false;} // Устанавливаем флаг мигания, если значение valBlink равно значению параметра k
switch (j){
/* 1 знак */ case 0: if(i>6 ){i=6; } charReturn[n]=f?32:i+48; break;
/* 2 знака */ case 1: if(i>99){i=99;} charReturn[n]=f?32:i/10+48; charReturn[n+1]=f?32:i%10+48; break;
/* AM / PM */ case 2: if(i>6 ){i=6; } charReturn[n]=f?32:charMidday[i]; charReturn[n+1]=f?32:charMidday[i+1]; break;
/* дн / мес */ case 3: if(i>54){i=54;} charReturn[n]=f?32:charDayMon[i]; charReturn[n+1]=f?32:charDayMon[i+1]; charReturn[n+2]=f?32:charDayMon[i+2]; break;
/* 4 знака */ case 4: if(i>99){i=99;} charReturn[n]=f?32:(valCentury-1)/10+48; charReturn[n+1]=f?32:(valCentury-1)%10+48; charReturn[n+2]=f?32:i/10+48; charReturn[n+3]=f?32:i%10+48; break;
}
}
// Установка даты и времени
void iarduino_RTC::settime(int i1, int i2, int i3, int i4, int i5, int i6, int i7){ // (сек, мин, час, день, мес, год, день_недели)
funcWriteTime(i1, i2, i3, i4, i5, i6, i7); // Записываем дату и время в регистры модуля
funcReadTime(); // Читаем дату и время из регистров модуля
funcSetMoreTime(); // Корректируем переменные не читаемые из модуля (hours, midday)
}
// Установка даты и времени от начала эпохи Unix
void iarduino_RTC::settimeUnix(uint32_t i){ // (сек)
uint32_t j; uint8_t k; bool f=true; // Объявляем временные переменные.
seconds = i % 60; // Получаем текущее значение секунд. (остаток от деления секунд прошедших с начала эпохи Unix на количество секунд в минуте)
i = (i-seconds) / 60; // Получаем количество минут прошедших с начала эпохи Unix.
minutes = i % 60; // Получаем текущее значение минут. (остаток от деления минут прошедших с начала эпохи Unix на количество минут в часе)
i = (i-minutes) / 60; // Получаем количество часов прошедших с начала эпохи Unix.
Hours = i % 24; // Получаем текущее значение часов. (остаток от деления часов прошедших с начала эпохи Unix на количество часов в дне)
i = (i-Hours) / 24; // Получаем количество дней прошедших с начала эпохи Unix.
j = 0; while((((j+1)*365)+((j+2)/4))<=i){j++;} // Получаем количество лет прошедших с начала эпохи Unix.
weekday = (i+4) % 7; // Получаем текущий день недели. (0-воскресенье, 1-понедельник, ... , 6-суббота)
i = i - (j*365) - ((j+1)/4); // Получаем количество дней прошедших в текущем году.
valCentury = ((1970+j)/100)+1; // Получаем текущий век.
year = (1970+j)%100; // Получаем две последние цифры текущего года.
k = ((1970+j)%4)==0?29:28; // Получаем количество дней в феврале текущего года.
month = 0; while(f){month++; j=month; j=(((j+1)%2)^(j<8))?31:(j==2?k:30); if(i>=j){i-=j;}else{f=false;}}
day = i+1; // Получаем текущий день.
// Устанавливаем время:
settime(seconds, minutes, Hours, day, month, year, weekday);
}
// Чтение даты и времени в переменные из регистров модуля:
void iarduino_RTC::funcReadTime(void){ // (без параметров)
seconds = arrCalculationTime[0] = funcConvertCodeToNum(objClass -> funcReadTimeIndex(0)); // Получаем секунды
minutes = arrCalculationTime[1] = funcConvertCodeToNum(objClass -> funcReadTimeIndex(1)); // Получаем минуты
Hours = arrCalculationTime[2] = funcConvertCodeToNum(objClass -> funcReadTimeIndex(2)); // Получаем часы
day = arrCalculationTime[3] = funcConvertCodeToNum(objClass -> funcReadTimeIndex(3)); // Получаем день
month = arrCalculationTime[4] = funcConvertCodeToNum(objClass -> funcReadTimeIndex(4)); // Получаем месяц
year = arrCalculationTime[5] = funcConvertCodeToNum(objClass -> funcReadTimeIndex(5)); // Получаем год
weekday = arrCalculationTime[6] = funcConvertCodeToNum(objClass -> funcReadTimeIndex(6))-1; // Получаем день недели (в регистре значение от 1 до 7, а в переменной от 0 до 6)
Unix = funcCalculationUnix(); // Получаем количество секунд (прошедших с начала эпохи Unix)
valRequest = millis(); // Сохраняем время данного запроса
}
// Запись даты и времени в регистры модуля:
void iarduino_RTC::funcWriteTime(int i1, int i2, int i3, int i4, int i5, int i6, int i7){ //
if(i1<=60 && i1>=0){objClass -> funcWriteTimeIndex(0, funcConvertNumToCode(i1 ));} // Сохраняем секунды
if(i2<=60 && i2>=0){objClass -> funcWriteTimeIndex(1, funcConvertNumToCode(i2 ));} // Сохраняем минуты
if(i3<=23 && i3>=0){objClass -> funcWriteTimeIndex(2, funcConvertNumToCode(i3 ));} // Сохраняем часы
if(i4<=31 && i4>=1){objClass -> funcWriteTimeIndex(3, funcConvertNumToCode(i4 ));} // Сохраняем день
if(i5<=12 && i5>=1){objClass -> funcWriteTimeIndex(4, funcConvertNumToCode(i5 ));} // Сохраняем месяц
if(i6<=99 && i6>=0){objClass -> funcWriteTimeIndex(5, funcConvertNumToCode(i6 ));} // Сохраняем год
if(i7<= 6 && i7>=0){objClass -> funcWriteTimeIndex(6, funcConvertNumToCode(i7+1));} // Сохраняем день недели (в регистре значение от 1 до 7, а в переменной от 0 до 6)
}
// Расчёт времени без обращения к модулю:
void iarduino_RTC::funcCalculationTime(void){ // (без параметров)
uint32_t i=(millis()-valRequest)/1000; // Определяем количество секунд (прошедших после последнего обращения к модулю)
uint8_t j=30 + ( (arrCalculationTime[4] + (arrCalculationTime[4]>7?1:0)) % 2 ); // Определяем количество дней в месяце (31, 30, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31)
if(arrCalculationTime[4]==2){j=28+((((uint16_t)valCentury-1)*100+arrCalculationTime[5])%4?0:1);}// Если текущий месяц - февраль, то меняем на ... (31, 28/29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31)
i+=arrCalculationTime[0]; seconds = i%60; i/=60; // Добавляем к прошедним секундам (i) посление прочитанные секунды (arrCalculationTime[0]), результатом будет остаток, а значение i превращаем в минуты
i+=arrCalculationTime[1]; minutes = i%60; i/=60; // Добавляем к прошедним минутам (i) посление прочитанные минуты (arrCalculationTime[1]), результатом будет остаток, а значение i превращаем в часы
i+=arrCalculationTime[2]; Hours = i%24; i/=24; // Добавляем к прошедним часам (i) посление прочитанные часы (arrCalculationTime[2]), результатом будет остаток, а значение i превращаем в дни
weekday = arrCalculationTime[6]+i; if(weekday>6){weekday=0;} // День недели увеличится на (i) от прочитанного дня недели (arrCalculationTime[6])
i+=arrCalculationTime[3]; day = i%(j+1); i/=(j+1); day+=i; // Добавляем к прошедним дням (i) посление прочитанные дни (arrCalculationTime[3]), результатом будет остаток, а значение i превращаем в месяцы
i+=arrCalculationTime[4]; month = i%13; i/=13; month+=i; // Добавляем к прошедним месяцам (i) посление прочитанные месяцы (arrCalculationTime[4]), результатом будет остаток, а значение i превращаем в годы
i+=arrCalculationTime[5]; year = i%100; // Добавляем к прошедним годам (i) посление прочитанные годы (arrCalculationTime[5]), результатом будет остаток, а значение i превращаем в дни
Unix = funcCalculationUnix(); // Получаем количество секунд прошедших с начала эпохи Unix
}
// Расчёт количества cекунд прошедших с начала эпохи Unix:
uint32_t iarduino_RTC::funcCalculationUnix(void){ // (без параметров)
uint32_t i; // Объявляем переменную для хранения результата. (рассчёты производятся из значений переменных: seconds, minutes, Hours, day, month, year и valCentury).
uint32_t j = (uint32_t)(valCentury-1) * 100 + year; // Определяем текущий год с учётом века. (valCentury - век, year - последние два знака текущего года).
i = j - 1970; // Определяем количество прошедших лет (с 01.01.1970 г.)
i = i * 365 + ((i+1)/4); // Определяем количество дней в прошедших годах ((i+1)/4) - количество прошедших високосных лет (без учёта текущего года).
i += (month-1)*30 + ( (month + (month<9?0:1) )/2 ); // Добавляем количество дней в прошедших месяцах ((month+(month<9?0:1))/2) - количество прошедших месяцев текущего года, содержащих 31 день.
i -= month>2? (j%4==0?1:2) : 0; // Вычитаем 1 или 2 дня из февраля текущего года ((month>2) - если февраль уже прошел, j%4==0 - если текущий год високосный)
i += day-1; // Добавляем количество прошедших дней этого месяца
i *= 86400; // Получаем количество секунд прошедших дней
i += (uint32_t)Hours * 3600 + (uint32_t)minutes * 60 + seconds; // Добавляем количество секунд текущего дня
return i; // Возвращаем результат
}

View File

@@ -0,0 +1,107 @@
// Библиотека для работы с часами реального времени: (на чипе DS1302) https://iarduino.ru/shop/Expansion-payments/rtc-modul-ds1302.html
// (на чипе DS1307) https://iarduino.ru/shop/Expansion-payments/kroshechnye-rtc-modul-realnogo-vremeni.html
// https://iarduino.ru/shop/Expansion-payments/chasy-realnogo-vremeni-rtc-trema-modul.html
// (на чипе DS3231) https://iarduino.ru/shop/Expansion-payments/chasy-realnogo-vremeni-ds3231.html
// https://iarduino.ru/shop/Expansion-payments/chasy-realnogo-vremeni-rtc-trema-modul-v2-0.html
// (на чипе RX8025)
// Версия: 2.0.0
// Последнюю версию библиотеки Вы можете скачать по ссылке: https://iarduino.ru/file/235.html
// Подробное описание функции бибилиотеки доступно по ссылке: https://wiki.iarduino.ru/page/chasy-realnogo-vremeni-rtc-trema-modul/
// Библиотека является собственностью интернет магазина iarduino.ru и может свободно использоваться и распространяться!
// При публикации устройств или скетчей с использованием данной библиотеки, как целиком, так и её частей,
// в том числе и в некоммерческих целях, просим Вас опубликовать ссылку: https://iarduino.ru
// Автор библиотеки: Панькин Павел
// Если у Вас возникли технические вопросы, напишите нам: shop@iarduino.ru
#ifndef iarduino_RTC_h //
#define iarduino_RTC_h //
//
#define RTC_UNDEFINED 0 // Модуль часов реального времени не определён
//
#if defined(ARDUINO) && (ARDUINO >= 100) //
#include <Arduino.h> //
#else //
#include <WProgram.h> //
#endif //
//
#include "memorysaver.h" // Подключаем файл «хранитель памяти» (внутри файла есть комментарий поясняющий как сэкономить мапять)
//
class iarduino_RTC_BASE{ // Объявляем полиморфный класс
public: //
virtual void begin (void); // Объявляем функцию инициализации модуля (без параметров)
virtual uint8_t funcReadTimeIndex (uint8_t); // Объявляем функцию чтения 1 значения из регистров даты и времени (0-секунды / 1-минуты / 2-часы / 3-день / 4-месяц / 5-год / 6-день недели)
virtual void funcWriteTimeIndex (uint8_t, uint8_t); // Объявляем функцию записи 1 значения в регистры даты и времени (0-секунды / 1-минуты / 2-часы / 3-день / 4-месяц / 5-год / 6-день недели, значение)
}; //
//
#include "iarduino_RTC_DS1302.h" // Подключаем файл iarduino_RTC_DS1302.h
#include "iarduino_RTC_DS1307.h" // Подключаем файл iarduino_RTC_DS1307.h
#include "iarduino_RTC_DS3231.h" // Подключаем файл iarduino_RTC_DS3231.h
#include "iarduino_RTC_RX8025.h" // Подключаем файл iarduino_RTC_RX8025.h
//
class iarduino_RTC{ //
public: //
/** Конструктор класса **/ //
iarduino_RTC(uint8_t i, uint8_t j=SS, uint8_t k=SCK, uint8_t n=MOSI){ // Конструктор основного класса (название [, вывод SS/RST [, вывод SCK/CLK [, вывод MOSI/DAT]]])
switch(i){ // Тип выбранного модуля
#ifdef RTC_ENABLE_DS1302 //
case RTC_DS1302: objClass = new iarduino_RTC_DS1302(j,k,n); break; // Если используется модуль на базе чипа DS1302, то присваеиваем указателю objClass ссылку на новый объект производного класса iarduino_RTC_DS1302 переопределяя на него все виртуальные функции полиморфного класса iarduino_RTC_BASE
#endif //
#ifdef RTC_ENABLE_DS1307 //
case RTC_DS1307: objClass = new iarduino_RTC_DS1307; break; // Если используется модуль на базе чипа DS1307, то присваеиваем указателю objClass ссылку на новый объект производного класса iarduino_RTC_DS1307 переопределяя на него все виртуальные функции полиморфного класса iarduino_RTC_BASE
#endif //
#ifdef RTC_ENABLE_DS3231 //
case RTC_DS3231: objClass = new iarduino_RTC_DS3231; break; // Если используется модуль на базе чипа DS3231, то присваеиваем указателю objClass ссылку на новый объект производного класса iarduino_RTC_DS3231 переопределяя на него все виртуальные функции полиморфного класса iarduino_RTC_BASE
#endif //
#ifdef RTC_ENABLE_RX8025 //
case RTC_RX8025: objClass = new iarduino_RTC_RX8025; break; // Если используется модуль на базе чипа RX8025, то присваеиваем указателю objClass ссылку на новый объект производного класса iarduino_RTC_RX8025 переопределяя на него все виртуальные функции полиморфного класса iarduino_RTC_BASE
#endif //
} //
} //
/** Пользовательские функции **/ //
void begin (void) {objClass -> begin(); gettime();} // Определяем функцию инициализации модуля (без параметров)
void period (uint8_t i) {valPeriod=i; valPeriod*=60000;} // Определяем функцию задания минимального периода обращения к модулю (i = период в минутах)
void blinktime (uint8_t i, float j=1) {valBlink=i; valFrequency=uint32_t(1000/j);} // Определяем функцию позволяющую мигать одним из параметров времени (i = 0-нет / 1-сек / 2-мин / 3-час / 4-день / 5-мес / 6-год / 7-день_недели / 8-полдень , j = частота мигания в Гц)
void gettime (void) {gettime("");} // Определяем функцию получения даты и времени из переменных (без параметров)
char* gettime (String); // Объявляем функцию «дублёр» получения даты и времени из переменных (строка с параметрами)
char* gettime (const char*); // Объявляем функцию получения даты и времени ввиде строки (строка с параметрами)
void settime (int, int=-1, int=-1, int=-1, int=-1, int=-1, int=-1); // Объявляем функцию установки даты и времени (сек, мин, час, день, мес, год, день_недели)
uint32_t gettimeUnix (void) {gettime(""); return Unix;} // Определяем функцию получения cекунд прошедших с начала эпохи Unix (без параметров)
void settimeUnix (uint32_t); // Объявляем функцию установки cекунд прошедших с начала эпохи Unix (сек)
//
/** Переменные доступные для пользователя **/ //
uint8_t seconds = 0; // Секунды 0-59
uint8_t minutes = 0; // Минуты 0-59
uint8_t hours = 1; // Часы 1-12
uint8_t Hours = 0; // Часы 0-23
uint8_t midday = 0; // Полдень 0-1 (0-am, 1-pm)
uint8_t day = 1; // День месяца 1-31
uint8_t weekday = 0; // День недели 0-6 (0-воскресенье, 1-понедельник, ... , 6-суббота)
uint8_t month = 1; // Месяц 1-12
uint8_t year = 0; // Год 0-99 (без учёта века)
uint32_t Unix = 0; // Секунды прошедшие с начала эпохи Unix (01.01.1970 00:00:00 GMT)
//
/** Внутренние переменные **/ //
iarduino_RTC_BASE* objClass; // Объявляем указатель на объект полиморфного класса (функции данного класса будут переопределены, т.к. указателю будет присвоена ссылка на производный класс)
char* charReturn = (char*) malloc(1); // Определяем указатель на символьную область памяти в 1 байт (указатель будет ссылаться на строку вывода времени)
const char* charInput = "waAdhHimsyMDY"; // Определяем константу-строку с символами требующими замены (данные символы заменяются функцией gettime на значение времени)
const char* charMidday = "ampmAMPM"; // Определяем константу-строку для вывода полудня (am / pm / AM / PM)
const char* charDayMon = "SunMonTueWedThuFriSatJanFebMarAprMayJunJulAugSepOctNovDec"; // Определяем константу-строку для вывода дня недели или месяца (Mon ... Sun / Jan ... Dec)
uint8_t arrCalculationTime[7]; // Объявляем массив для рассчёта времени без обращения к модулю (для хранения последних, прочитанных из модуля, значений даты и времени)
uint8_t valBlink = 0; // Определяем параметр времени, который должен мигать (1-сек / 2-мин / 3-час / 4-день / 5-мес / 6-год / 7-день_недели / 8-полдень)
uint32_t valFrequency = 1000; // Определяем частоту мигания параметра времени для функции blinktime (по умолчанию 1 Гц)
uint8_t valCentury = 21; // Определяем переменную для хранения текущего века (по умолчанию 21 век)
uint16_t valPeriod = 0; // Определяем минимальный период опроса модуля (в минутах, от 00 до 255)
uint32_t valRequest = 0; // Определяем время последнего чтения регистров времени
private: //
/** Внутренние функции **/ //
void funcReadTime (void); // Объявляем функцию чтения даты и времени из регистров модуля (без параметров)
void funcWriteTime (int, int, int, int, int, int, int); // Объявляем функцию записи даты и времени в регистры модуля (без параметров)
uint8_t funcConvertCodeToNum (uint8_t i) {return (i >> 4)*10 + (i & 0x0F);} // Определяем функцию преобразования двоично-десятичного кода в число (код)
uint8_t funcConvertNumToCode (uint8_t i) {return ((i/10) << 4) + (i%10);} // Определяем функцию преобразования числа в двоично-десятичный код (число)
void funcSetMoreTime (void){hours=(Hours%12)?(Hours%12):12; midday=(Hours<12)?0:1;} // Корректировка переменных не читаемых из модуля (без параметров)
void funcCalculationTime (void); // Объявляем функцию расчёта времени без обращения к модулю (без параметров)
uint32_t funcCalculationUnix (void); // Объявляем функцию расчёта cекунд прошедших с начала эпохи Unix (без параметров)
void funcFillChar (uint8_t, uint8_t, uint8_t, uint8_t); // Объявляем функцию заполнения строки вывода времени (данные, тип данных, позиция для вставки, мигание)
}; //
//
#endif //

View File

@@ -0,0 +1,67 @@
#ifndef iarduino_RTC_DS1302_h //
#define iarduino_RTC_DS1302_h //
#define RTC_DS1302 1 // Модуль часов реального времени с протоколом передачи данных SI3, памятью 040x8 (31 байт которой доступны для хранения данных пользователя)
//
class iarduino_RTC_DS1302: public iarduino_RTC_BASE{ //
public: //
/** Конструктор класса **/ //
iarduino_RTC_DS1302(uint8_t i=SS, uint8_t j=SCK, uint8_t k=MOSI){pinRES=i; pinCLK=j; pinDAT=k;} // (вывод RST, вывод CLK, вывод DAT)
/** функции доступные пользователю **/ //
// Инициализация модуля: //
void begin(void){ // (без параметров)
// Инициализация работы с трехпроводной шиной: //
funcBegin(); // (без параметров)
// Установка флагов управления и состояния модуля: //
varI=funcReadReg(0x81); if( varI & 0b10000000){funcWriteReg(0x81, (varI&~0b10000000));} // (если установлен 7 бит в 129 регистре, то сбрасываем его - запускаем генератор)
varI=funcReadReg(0x85); if( varI & 0b10000000){funcWriteReg(0x85, (varI&~0b10000000));} // (если установлен 7 бит в 133 регистре, то сбрасываем его - переводим модуль в 24 часовой режим)
varI=funcReadReg(0x8F); if( varI & 0b10000000){funcWriteReg(0x8F, (varI&~0b10000000));} // (если установлен 7 бит в 143 регистре, то сбрасываем его - разрешаем запись в регистры модуля)
} //
//
// Чтение одного значения из регистров даты и времени модуля: //
uint8_t funcReadTimeIndex(uint8_t i){ // (i = 0-секунды / 1-минуты / 2-часы / 3-день / 4-месяц / 5-год / 6-день недели)
delay(1); return funcReadReg(arrTimeRegAddr[i]) & arrTimeRegMack[i]; //
} //
//
// Запись одного значения в регистры даты и времени модуля: //
void funcWriteTimeIndex(uint8_t i, uint8_t j){ // (i = 0-секунды / 1-минуты / 2-часы / 3-день / 4-месяц / 5-год / 6-день недели, j = значение)
varI=funcReadTimeIndex(i); // Читаем данные из регистра i
j |= ~arrTimeRegMack[i] & varI; // Устанавливаем биты значения j по маске arrTimeRegMack[i] в прочитанные из регистра i
j &= arrTimeRegMack[i] | varI; // Сбрасываем биты значения j по маске arrTimeRegMack[i] в прочитанные из регистра i
funcWriteReg(arrTimeRegAddr[i], j); // Сохраняем значение j в регистр arrTimeRegAddr[i]
} //
//
private: //
/** Внутренние переменные **/ //
uint8_t pinRES = 0; // Определяем переменную для хранения номера вывода RST трехпроводной шины
uint8_t pinCLK = 0; // Определяем переменную для хранения номера вывода CLK трехпроводной шины
uint8_t pinDAT = 0; // Определяем переменную для хранения номера вывода DAT трехпроводной шины
uint8_t arrTimeRegAddr[7] = {0x81,0x83,0x85,0x87,0x89,0x8D,0x8B}; // Определяем массив с адресами регистров чтения даты и времени (сек, мин, час, день, месяц, год, день недели)
uint8_t arrTimeRegMack[7] = {0x7F,0x7F,0x3F,0x3F,0x1F,0xFF,0x07}; // Определяем маскировочный массив для регистров даты и времени (при чтении/записи, нужно совершить побитовое «и»)
uint8_t busRate = 10; // Скорость передачи данных трехпроводной шине в кГц (до 255 кГц)
uint8_t varI; //
//
/** Внутренние функции **/ //
// Функция чтения данных из регистра модуля: //
uint8_t funcReadReg(uint8_t i){ // Определяем функцию читения данных из регистра модуля (аргумент: адрес_регистра)
varI=1; // Предустанавливаем переменную varI в значение 1, чтоб не вывести: 45 апреля 255 часов 127 минут и 200 секунд
digitalWrite (pinRES, 1); // Устанавливаем линию RES в активное состояние
funcWriteByte (i); // Отправляем адрес регистра
varI=funcReadByte (true); // Читаем байт из регистра с учётом предустановленного бита
digitalWrite (pinRES, 0); // Устанавливаем линию RES в неактивное состояние
return varI; // Возвращаем значение переменной varI
} //
// Функция записи данных в регистр модуля: //
void funcWriteReg(uint8_t i, uint8_t j){ // Определяем функцию записи данных в регистр модуля (аргументы: адрес_регистра, байт_данных)
digitalWrite (pinRES, 1); // Устанавливаем линию RES в активное состояние
funcWriteByte (i-1); // Отправляем адрес регистра (при чтении указывается адрес-1)
funcWriteByte (j); // Отправляем байт данных
digitalWrite (pinRES, 0); // Устанавливаем линию RES в неактивное состояние
} //
//
/** функции для работы с трехпроводной шиной **/ //
void funcWriteByte (uint8_t j) /* Передача одного байта (байт для передачи) */ {uint8_t i=0, n=500/busRate+1; pinMode(pinDAT, OUTPUT); while(i>=0 && i<8){digitalWrite(pinDAT, (j & _BV(i))); delayMicroseconds(n); digitalWrite(pinCLK, 1); delayMicroseconds(n); digitalWrite(pinCLK, 0); i++;} pinMode(pinDAT, INPUT);}
uint8_t funcReadByte (bool j) /* Получение одного байта (флаг чтения предустановленного бита с линии DAT) */ {uint8_t i=0, k=0, n=500/busRate+1; pinMode(pinDAT, INPUT); if(j){if(digitalRead(pinDAT)){k |= _BV(i);} i++;} while(i>=0 && i<8){digitalWrite(pinCLK, 1); delayMicroseconds(n); digitalWrite(pinCLK, 0); delayMicroseconds(n); if(digitalRead(pinDAT)){k |= _BV(i);} i++;} return k;}
void funcBegin (void) /* Подготовка выводов шины (без параметров) */ {pinMode(pinRES, OUTPUT); pinMode(pinCLK, OUTPUT); pinMode(pinDAT, INPUT); digitalWrite(pinCLK, 0); digitalWrite(pinRES, 0);}
}; //
//
#endif //

View File

@@ -0,0 +1,42 @@
#ifndef iarduino_RTC_DS1307_h //
#define iarduino_RTC_DS1307_h //
#define RTC_DS1307 2 // Модуль часов реального времени с протоколом передачи данных I2C, памятью 064x8 (56 байт которой доступны для хранения данных пользователя)
#include "iarduino_RTC_I2C.h" // Подключаем файл iarduino_RTC_I2C.h - для работы с шиной I2C
//
class iarduino_RTC_DS1307: public iarduino_RTC_BASE{ //
public: //
/** функции доступные пользователю **/ //
// Инициализация модуля: //
void begin(void){ // (без параметров)
// Инициализация работы с шиной I2C: //
objI2C.begin(100); // (скорость шины в кГц)
// Установка флагов управления и состояния модуля: //
varI=objI2C.readByte(valAddress, 0x00); if( varI & 0b10000000 ){objI2C.writeByte(valAddress, 0x00, (varI&~0b10000000) );} // (если установлен 7 бит в 0 регистре, то сбрасываем его - запускаем генератор)
varI=objI2C.readByte(valAddress, 0x02); if( varI & 0b01000000 ){objI2C.writeByte(valAddress, 0x02, (varI&~0b01000000) );} // (если установлен 6 бит в 2 регистре, то сбрасываем его - переводим модуль в 24 часовой режим)
varI=objI2C.readByte(valAddress, 0x07); if((varI & 0b00000011) || !(varI & 0b00010000)){objI2C.writeByte(valAddress, 0x07, (varI&~0b00000011)|0b00010000 );} // (если установлены 1 и 0 биты или сброшен 4 бит в 7 регистре, то сбрасываем 1 с 0 битами, а 4 устанавливаем - выводим меандр с частотой 1 Гц на выводе SQW/OUT модуля)
} //
//
// Чтение одного значения из регистров даты и времени модуля: //
uint8_t funcReadTimeIndex(uint8_t i){ // (i = 0-секунды / 1-минуты / 2-часы / 3-день / 4-месяц / 5-год / 6-день недели)
delay(1); //
return objI2C.readByte(valAddress, arrTimeRegAddr[i]) & arrTimeRegMack[i]; //
} //
//
// Запись одного значения в регистры даты и времени модуля: //
void funcWriteTimeIndex(uint8_t i, uint8_t j){ // (i = 0-секунды / 1-минуты / 2-часы / 3-день / 4-месяц / 5-год / 6-день недели, j = значение)
varI=funcReadTimeIndex(i); // Читаем данные из регистра i
j |= ~arrTimeRegMack[i] & varI; // Устанавливаем биты значения j по маске arrTimeRegMack[i] в прочитанные из регистра i
j &= arrTimeRegMack[i] | varI; // Сбрасываем биты значения j по маске arrTimeRegMack[i] в прочитанные из регистра i
objI2C.writeByte(valAddress, arrTimeRegAddr[i], j); // Сохраняем значение j в регистр arrTimeRegAddr[i]
} //
//
private: //
/** Внутренние переменные **/ //
iarduino_I2C objI2C; // Создаём объект для работы с шиной I2C
uint8_t valAddress = 0x68; // Адрес модуля на шине I2C
uint8_t arrTimeRegAddr[7] = {0x00,0x01,0x02,0x04,0x05,0x06,0x03}; // Определяем массив с адресами регистров даты и времени (сек, мин, час, день, месяц, год, день недели)
uint8_t arrTimeRegMack[7] = {0x7F,0x7F,0x3F,0x3F,0x1F,0xFF,0x07}; // Определяем маскировочный массив для регистров даты и времени (при чтении/записи, нужно совершить побитовое «и»)
uint8_t varI; //
}; //
//
#endif //

View File

@@ -0,0 +1,42 @@
#ifndef iarduino_RTC_DS3231_h //
#define iarduino_RTC_DS3231_h //
#define RTC_DS3231 3 // Модуль часов реального времени с протоколом передачи данных I2C, памятью 019x8, температурной компенсацией, двумя будильниками и встроенным кварцевым резонатором
#include "iarduino_RTC_I2C.h" // Подключаем файл iarduino_RTC_I2C.h - для работы с шиной I2C
//
class iarduino_RTC_DS3231: public iarduino_RTC_BASE{ //
public: //
/** функции доступные пользователю **/ //
// Инициализация модуля: //
void begin(void){ // (без параметров)
// Инициализация работы с шиной I2C: //
objI2C.begin(100); // (скорость шины в кГц)
// Установка флагов управления и состояния модуля: //
varI=objI2C.readByte(valAddress, 0x02); if( varI & 0b01000000 ){objI2C.writeByte(valAddress, 0x02, (varI&~0b01000000) );} // (если установлен 6 бит в 2 регистре, то сбрасываем его - переводим модуль в 24 часовой режим)
varI=objI2C.readByte(valAddress, 0x0E); if( varI & 0b11011111 ){objI2C.writeByte(valAddress, 0x0E, (varI&~0b11011111) );} // (если установлены 7,6,4,3,2,1 и 0 биты в 14 регистре, то сбрасываем их - разрешаем генератору работать от батарейки, запрещаем выводу SQW работать от батарейки, выводим меандр с частотой 1Гц на вывод SQW, переводим вывод INT/SQW в режим SQW, запрещаем прерывания будильников)
varI=objI2C.readByte(valAddress, 0x0F); if((varI & 0b10000011) || !(varI & 0b00001000)){objI2C.writeByte(valAddress, 0x0F, (varI&~0b10000011)|0b00001000 );} // (если установлены 7,1 и 0 биты или сброшен 3 бит в 15 регистре, то сбрасываем 7,1 и 0 биты, а 3 устанавливаем - сбрасываем флаг остановки генератора, разрешаем меандр с частотой 32768Гц на выводе 32kHz, сбрасываем флаги будильников)
} //
//
// Чтение одного значения из регистров даты и времени модуля: //
uint8_t funcReadTimeIndex(uint8_t i){ // (i = 0-секунды / 1-минуты / 2-часы / 3-день / 4-месяц / 5-год / 6-день недели)
delay(1); //
return objI2C.readByte(valAddress, arrTimeRegAddr[i]) & arrTimeRegMack[i]; //
} //
//
// Запись одного значения в регистры даты и времени модуля: //
void funcWriteTimeIndex(uint8_t i, uint8_t j){ // (i = 0-секунды / 1-минуты / 2-часы / 3-день / 4-месяц / 5-год / 6-день недели, j = значение)
varI=funcReadTimeIndex(i); // Читаем данные из регистра i
j |= ~arrTimeRegMack[i] & varI; // Устанавливаем биты значения j по маске arrTimeRegMack[i] в прочитанные из регистра i
j &= arrTimeRegMack[i] | varI; // Сбрасываем биты значения j по маске arrTimeRegMack[i] в прочитанные из регистра i
objI2C.writeByte(valAddress, arrTimeRegAddr[i], j); // Сохраняем значение j в регистр arrTimeRegAddr[i]
} //
//
private: //
/** Внутренние переменные **/ //
iarduino_I2C objI2C; // Создаём объект для работы с шиной I2C
uint8_t valAddress = 0x68; // Адрес модуля на шине I2C
uint8_t arrTimeRegAddr[7] = {0x00,0x01,0x02,0x04,0x05,0x06,0x03}; // Определяем массив с адресами регистров даты и времени (сек, мин, час, день, месяц, год, день недели)
uint8_t arrTimeRegMack[7] = {0x7F,0x7F,0x3F,0x3F,0x1F,0xFF,0x07}; // Определяем маскировочный массив для регистров даты и времени (при чтении/записи, нужно совершить побитовое «и»)
uint8_t varI; //
}; //
//
#endif //

View File

@@ -0,0 +1,461 @@
#ifndef iarduino_I2C_h // Разрешаем включить данный код в скетч, только если он не был включён ранее
#define iarduino_I2C_h // Запрещаем повторное включение данного кода в скетч
//
// Определяем тип реализации шины I2C: //
#define iarduino_I2C_SW // Объявляем константу iarduino_I2C_SW - Возможна программная реализация шины I2C.
#if (!defined(pin_SW_SDA) || !defined(pin_SW_SCL)) // Если выводы не определены пользователем, то ...
#undef iarduino_I2C_SW // Отменяем объявление константы iarduino_I2C_SW - Программная реализация шины I2C не возможна (так как выводы не указаны).
#if defined(ESP8266) || defined(ESP32) // Если используются указанные платы, то ...
#include <Wire.h> // Подключаем библиотеку Wire.
#define pin_SW_SDA 255 // № вывода SDA не определён
#define pin_SW_SCL 255 // № вывода SCL не определён
#define iarduino_I2C_TW // Объявляем константу iarduino_I2C_TW - Будет использована аппаратная реализация шины I2C под управлением библиотеки Wire.
#elif defined(TwoWire_h) // Проверяем не подключена ли библиотека Wire.
#define pin_SW_SDA 255 // № вывода SDA не определён
#define pin_SW_SCL 255 // № вывода SCL не определён
#define iarduino_I2C_TW // Объявляем константу iarduino_I2C_TW - Будет использована аппаратная реализация шины I2C под управлением библиотеки Wire.
#elif (defined(SDA) && defined(SCL)) // Определяем выводы для шины I2C
#define pin_SW_SDA SDA // № вывода SDA = SDA
#define pin_SW_SCL SCL // № вывода SCL = SCL
#define iarduino_I2C_HW // Объявляем константу iarduino_I2C_HW - Будет использована аппаратная реализация шины I2C.
#elif (defined(PIN_WIRE_SDA) && defined(PIN_WIRE_SCL)) // Определяем выводы для шины I2C
#define pin_SW_SDA PIN_WIRE_SDA // № вывода SDA = PIN_WIRE_SDA
#define pin_SW_SCL PIN_WIRE_SCL // № вывода SCL = PIN_WIRE_SCL
#define iarduino_I2C_HW // Объявляем константу iarduino_I2C_HW - Будет использована аппаратная реализация шины I2C.
#elif (defined(SDA1) && defined(SCL1)) // Определяем выводы для шины I2C-1
#define pin_SW_SDA SDA1 // № вывода SDA = SDA1
#define pin_SW_SCL SCL1 // № вывода SCL = SCL1
#define iarduino_I2C_HW_1 // Объявляем константу iarduino_I2C_HW_1 - Будет использована аппаратная реализация шины I2C-1.
#else // Если выводы определить не удалось, то ...
#define pin_SW_SDA 255 // № вывода SDA не определён - Аппаратная реализация шины I2C не возможна.
#define pin_SW_SCL 255 // № вывода SCL не определён - Аппаратная реализация шины I2C не возможна.
#endif //
#endif //
//
class iarduino_I2C_BASE{ // Определяем полиморфный класс
public: // Доступные методы и функции:
// ОСНОВНЫЕ ФУНКЦИИ: (поддерживаются библиотекой Wire) //
virtual void begin (uint32_t); // Объявляем функцию указания скорости шины I2C. Аргументы: скорость в кГц.
virtual uint8_t readByte (uint8_t, uint8_t ); // Объявляем функцию чтения байта данных из регистра модуля. Аргументы: адресодуля, адрес_регистра. (адрес регистра указывает модулю, данные какого регистра требуется отправить мастеру)
virtual bool writeByte (uint8_t, uint8_t, uint8_t); // Объявляем функцию записи байта данных в регистр модуля. Аргументы: адресодуля, адрес_регистра, байт_данных. (адрес регистра указывает модулю, в какой регистр требуется сохранить данные)
virtual uint8_t readByte (uint8_t ); // Объявляем функцию чтения байта данных из модуля. Аргументы: адресодуля (функция отличается тем, что она не отправляет модулю адрес регистра)
virtual bool writeByte (uint8_t, uint8_t); // Объявляем функцию записи байта данных в модуль. Аргументы: адресодуля, байт_данных. (функция отличается тем, что она не отправляет модулю адрес регистра)
virtual bool readBytes (uint8_t, uint8_t, uint8_t*, uint8_t); // Объявляем функцию чтения байтов данных из регистров модуля. Аргументы: адресодуля, адрес_первого_регистра, указатель_наассив, количество_байт. (адрес первого регистра указывает модулю, с какого регистра требуется начать передачу данных мастеру)
virtual bool writeBytes (uint8_t, uint8_t, uint8_t*, uint8_t); // Объявляем функцию записи байтов данных в регистры модуля. Аргументы: адресодуля, адрес_первого_регистра, указатель_наассив, количество_байт. (адрес первого регистра указывает модулю, начиная с какого регистра требуется сохранять данные)
virtual bool readBytes (uint8_t, uint8_t*, uint8_t); // Объявляем функцию чтения байтов данных из модуля. Аргументы: адресодуля, указатель_наассив, количество_байт. (функция отличается тем, что она не отправляет модулю адрес первого регистра, а начинает цикл чтения сразу после отправки адреса модуля.)
virtual bool writeBytes (uint8_t, uint8_t*, uint8_t); // Объявляем функцию записи байтов данных в модуль. Аргументы: адресодуля, указатель_наассив, количество_байт. (функция отличается тем, что после отправки адреса модуля она сразу начинает цикл отправки данных, без передачи адреса первого регистра.)
// ДОПОЛНИТЕЛЬНЫЕ ФУНКЦИИ: (поддерживаются библиотекой Wire) //
virtual uint8_t getType (void); // Объявляем функцию получения типа реализации шины I2C. Аргументы: отсутствуют.
virtual bool checkAddress(uint8_t); // Объявляем функцию поиска модуля на шине I2C. Аргументы: адресодуля.
// ФУНКЦИИ НИЖНЕГО УРОВНЯ: (не поддерживаются библиотекой Wire) //
virtual bool start (void); // Объявляем функцию установки состояния START. Аргументы: отсутствуют.
virtual bool reStart (void); // Объявляем функцию установки состояния RESTART. Аргументы: отсутствуют.
virtual void stop (void); // Объявляем функцию установки состояния STOP. Аргументы: отсутствуют.
virtual bool sendID (uint8_t, bool); // Объявляем функцию передачи адреса модуля. Аргументы: ID-адрес модуля, бит RW (0-запись, 1-чтение).
virtual bool setByte (uint8_t); // Объявляем функцию передачи байта данных. Аргументы: байт для передачи.
virtual uint8_t getByte (bool); // Объявляем функцию получения байта данных. Аргументы: бит подтверждения ACK/NACK
private: //
virtual bool setSCL (bool); // Объявляем функцию установки уровня на линии SCL. Аргументы: логический уровень.
virtual void setSDA (bool); // Объявляем функцию установки уровня на линии SDA. Аргументы: логический уровень.
virtual bool getSDA (void); // Объявляем функцию чтения уровня с линии SDA. Аргументы: отсутствуют.
}; //
//
class iarduino_I2C: public iarduino_I2C_BASE{ // Определяем производный класс
public: // Доступные методы и функции:
//
/** ОСНОВНЫЕ ФУНКЦИИ: **/ //
//
// Функция подготовки шины I2C: // Определяем функцию подготовки шины I2C.
void begin(uint32_t speed){ // Аргумент: скорость шины в кГц.
// _ _ _ _______ _ _ _ //
// SCL: _?_?_/ OUTPUT //
// _ _ _ _ _____ _ _ _ //
// SDA: _?_?_ _/ OUTPUT //
// //
#if defined(iarduino_I2C_TW) //
// Если используется шина I2C под управлением библиотеки Wire: //
Wire.setClock(speed*1000L); // Устанавливаем скорость передачи данных по шине I2C.
Wire.begin(); // Инициируем работу на шине I2C в качестве мастера.
#elif defined(iarduino_I2C_HW) //
// Если используется аппаратная шина I2C: //
pinMode(pin_SDA, INPUT ); digitalWrite(pin_SDA, HIGH); // Определяем вывод pin_SDA как вход и подтягиваем его к Vcc.
pinMode(pin_SCL, INPUT ); digitalWrite(pin_SCL, HIGH); // Определяем вывод pin_SCL как вход и подтягиваем его к Vcc.
TWBR=((F_CPU/(speed*1000L))-16)/2; // Определяем значение регистра скорости связи TWBR: speed = F_CPU / (16 + 2 * TWBR * 4^TWPS). Значит TWBR = (F_CPU/speed - 16) / (2 * 4^TWPS), но так как биты предделителя TWPS мы далее сбросим в 0, то формула упростится до: TWBR = (F_CPU/speed - 16) / 2. Так как speed указана в кГц, а F_CPU в Гц, то умножаем speed на 1000.
if(TWBR<10){TWBR=10;} // Если значение регистра скорости TWBR стало меньше 10 (параметр speed > 400 кГ) то оставляем значение этого регистра равным 10 иначе шина будет работать нестабильно.
TWSR&=(~(_BV(TWPS1)|_BV(TWPS0))); // Определяем значение регистра статуса TWSR: оставляем все его биты не тронутыми, кроме двух битов предделитея TWPS сбрасывая их в 0.
#elif defined(iarduino_I2C_SW) //
// Если используется программная шина I2C: //
port_SDA = digitalPinToPort (pin_SDA); // Определяем номер порта для вывода pin_SDA.
port_SCL = digitalPinToPort (pin_SCL); // Определяем номер порта для вывода pin_SCL.
mask_SDA = digitalPinToBitMask (pin_SDA); // Определяем маску для вывода pin_SDA. в переменной mask_SDA будет установлен только тот бит который соответствует позиции бита управления выводом pin_SDA.
mask_SCL = digitalPinToBitMask (pin_SCL); // Определяем маску для вывода pin_SCL. в переменной mask_SCL будет установлен только тот бит который соответствует позиции бита управления выводом pin_SCL.
mod_SDA = portModeRegister (port_SDA); // Определяем указатель на адрес регистра конфигурации направления работы выводов порта port_SDA.
mod_SCL = portModeRegister (port_SCL); // Определяем указатель на адрес регистра конфигурации направления работы выводов порта port_SCL.
inp_SDA = portInputRegister (port_SDA); // Определяем указатель на адрес регистра входных значений для управления портом port_SDA.
inp_SCL = portInputRegister (port_SCL); // Определяем указатель на адрес регистра входных значений для управления портом port_SCL.
out_SDA = portOutputRegister (port_SDA); // Определяем указатель на адрес регистра выходных значений для управления портом port_SDA.
out_SCL = portOutputRegister (port_SCL); // Определяем указатель на адрес регистра выходных значений для управления портом port_SCL.
setSCL(1); // Переводим вывод SCL в режим входа с подтяжкой к Vcc
setSDA(1); // Переводим вывод SDA в режим входа с подтяжкой к Vcc
#endif //
} //
//
// Функция чтения одного байта из регистра модуля: //
uint8_t readByte(uint8_t adr, uint8_t reg){ // Определяем функцию чтения одного байта данных из регистра модуля (аргументы: адресодуля, адрес_регистра)
uint8_t i=0; readBytes(adr, reg, &i, 1); return i; // Объявляем переменную i и указываем её ссылку для получения 1 байта из регистра reg модуля с адресом adr
} //
//
// Функция чтения одного байта из модуля: //
uint8_t readByte(uint8_t adr){ // Определяем функцию чтения одного байта данных из регистра модуля (аргументы: адресодуля)
uint8_t i=0; readBytes(adr, &i, 1); return i; // Объявляем переменную i и указываем её ссылку для получения 1 байта из модуля с адресом adr
} //
//
// Функция записи одного байта в регистр модуля: //
bool writeByte(uint8_t adr, uint8_t reg, uint8_t data){ // Определяем функцию записи одного байта данных в регистр модуля (аргументы: адресодуля, адрес_регистра, байт_данных)
return writeBytes(adr, reg, &data, 1); // Запысываем 1 байт по ссылке на переменную data в регистр reg модуля с адресом adr
} //
//
// Функция записи одного байта в модуль: //
bool writeByte(uint8_t adr, uint8_t data){ // Определяем функцию записи одного байта данных в регистр модуля (аргументы: адресодуля, байт_данных)
return writeBytes(adr, &data, 1); // Запысываем 1 байт по ссылке на переменную data в модуль с адресом adr
} //
//
// Функция пакетного чтения нескольких байт данных из регистров модуля: //
bool readBytes(uint8_t adr, uint8_t reg, uint8_t *data, uint8_t sum){ // Определяем функцию пакетного чтения нескольких байт данных из регистров модуля (аргументы: адресодуля, адрес_первого_регистра, указатель_наассив, количество_байт)
#if defined(iarduino_I2C_TW) //
// Если используется шина I2C под управлением библиотеки Wire: //
uint8_t i=0; // Предустанавливаем переменную i в значение 0 - это ответ по умолчанию.
Wire.beginTransmission(adr); // Инициируем передачу данных по шине I2C к устройству с адресом adr и битом RW=0 => запись. При этом сама передача не начнётся.
Wire.write(reg); // Определяем значение первого байта (reg - адреса регистра) который будет отправлен после байта адреса. Функция write() поместит указанный байт в буфер для передачи.
i=Wire.endTransmission(false); if(i){return 0;} // Выполняем инициированную ранее передачу данных (без установки состояния STOP). Функция endTransmission() возвращает: 0-передача успешна / 1 - переполнен буфер для передачи / 2 - получен NACK при передаче адреса / 3 - получен NACK при передаче данных / 4 - другая ошибка.
if(!Wire.requestFrom( adr, sum )) {return i;} // Читаем (запрашиваем) sum байт данных от устройства с адресом adr и битом RW=1 => чтение. Функция requestFrom() возвращает количество реально принятых байтов. Так как предыдущая функция не установила состояние STOP, то состояние START данной функции будет расценено как RESTART.
while(Wire.available() && i<sum){data[i]=Wire.read(); i++;} // Читаем sum принятых байт из буфера для полученных данных в массив по указателю data.
while(Wire.available()){Wire.read();}return i==sum; // Если в буфере для полученных данных есть еще принятые байты, то чистим буфер. Возвращаем true если удалось прочитать sum байт.
#else //
// Если шина управляется функциями нижнего уровня данного класса: //
uint8_t i=0; // Предустанавливаем переменную i в значение 0 - это результат записи.
if ( start () ) { i=1; // Если на шине I2C установилось состояние START, то ...
if ( sendID (adr,0) ) { i=2; // Если модуль ответил ACK на получение адреса устройства adr с битом RW=0 (запись), то ...
if ( setByte (reg) ) { i=3; // Если модуль ответил ACK на получение адреса регистра i, то ...
if ( reStart () ) { i=4; // Если на шине I2C установилось состояние RESTART, то ...
if ( sendID (adr,1) ) { i=5; // Если модуль ответил ACK на получение адреса устройства adr с битом RW=1 (чтение), то ...
while(sum>0){ *data=getByte(sum>1); // Получаем по одному байту из очередного регистра за каждый проход цикла while. Прочитанный байт записываются по указателю data. Аргумент функции getByte имеет значение true на всех проходах цикла кроме последнего
data++; sum--; // Увеличиваем адрес указателя data, и уменьшаем сумму прочитанных байт sum.
#if defined(iarduino_I2C_HW) // Проверить корректность чтения каждого байта можно только на аппаратном уровне
if (sum) { if(TWSR&0xF8!=0x50) { i=0;}} // Если после чтения очередного байта пакета значение регистра состояния шины I2C Arduino TWSR с маской 0xF8 не равно 0x50 значит произошла ошибка при чтении
else { if(TWSR&0xF8!=0x58) { i=0;}} // Если после чтения последного байта пакета значение регистра состояния шины I2C Arduino TWSR с маской 0xF8 не равно 0x58 значит произошла ошибка при чтении
#endif //
}}}}}} stop (); return i==5; // Отправляем команду STOP и возвращаем результат успешности чтения
#endif //
} //
//
// Функция пакетного чтения нескольких байт данных из модуля: //
bool readBytes(uint8_t adr, uint8_t *data, uint8_t sum){ // Определяем функцию пакетного чтения нескольких байт данных из модуля (аргументы: адресодуля, указатель_наассив, количество_байт)
#if defined(iarduino_I2C_TW) //
// Если используется шина I2C под управлением библиотеки Wire: //
uint8_t i=0; // Предустанавливаем переменную i в значение 0 - это ответ по умолчанию.
if(!Wire.requestFrom( adr, sum )) {return i;} // Читаем (запрашиваем) sum байт данных от устройства с адресом adr и битом RW=1 => чтение. Функция requestFrom() возвращает количество реально принятых байтов.
while(Wire.available() && i<sum){data[i]=Wire.read(); i++;} // Читаем sum принятых байт из буфера для полученных данных в массив по указателю data.
while(Wire.available()){Wire.read();}return i==sum; // Если в буфере для полученных данных есть еще принятые байты, то чистим буфер. Возвращаем true если удалось прочитать sum байт.
#else //
// Если шина управляется функциями нижнего уровня данного класса: //
uint8_t i=0; // Предустанавливаем переменную i в значение 0 - это результат записи.
if ( start () ) { i=1; // Если на шине I2C установилось состояние START, то ...
if ( sendID (adr,1) ) { i=2; // Если модуль ответил ACK на получение адреса устройства adr с битом RW=1 (чтение), то ...
while(sum>0){ *data=getByte(sum>1); // Получаем по одному байту из очередного регистра за каждый проход цикла while. Прочитанный байт записываются по указателю data. Аргумент функции getByte имеет значение true на всех проходах цикла кроме последнего
data++; sum--; // Увеличиваем адрес указателя data, и уменьшаем сумму прочитанных байт sum.
#if defined(iarduino_I2C_HW) // Проверить корректность чтения каждого байта можно только на аппаратном уровне
if (sum) { if(TWSR&0xF8!=0x50) { i=0;}} // Если после чтения очередного байта пакета значение регистра состояния шины I2C Arduino TWSR с маской 0xF8 не равно 0x50 значит произошла ошибка при чтении
else { if(TWSR&0xF8!=0x58) { i=0;}} // Если после чтения последного байта пакета значение регистра состояния шины I2C Arduino TWSR с маской 0xF8 не равно 0x58 значит произошла ошибка при чтении
#endif //
}}} stop (); return i==2; // Отправляем команду STOP и возвращаем результат успешности чтения
#endif //
} //
//
// Функция пакетной записи нескольких байт данных в регистр модуля: //
bool writeBytes(uint8_t adr, uint8_t reg, uint8_t *data, uint8_t sum){ // Определяем функцию пакетной записи нескольких байт данных в регистры модуля (аргументы: адресодуля, адрес_первого_регистра, указатель_наассив, количество_байт)
#if defined(iarduino_I2C_TW) //
// Если используется шина I2C под управлением библиотеки Wire: //
uint8_t i=0; // Предустанавливаем переменную i в значение 0 - это результат записи
Wire.beginTransmission(adr); // Инициируем передачу данных по шине I2C к устройству с адресом adr и битом RW=0 => запись. При этом сама передача не начнётся.
Wire.write(reg); // Определяем значение первого байта (reg - адреса регистра) который будет отправлен после байта адреса. Функция write() поместит указанный байт в буфер для передачи.
Wire.write(data, sum); // Определяем значения следующих байт (data - массив данных) который будет отправлен после байта регистра. Функция write() поместит sum элементов массива data в буфер для передачи.
i = Wire.endTransmission(); return i==0; // Выполняем инициированную ранее передачу данных. Функция endTransmission() возвращает: 0-передача успешна / 1 - переполнен буфер для передачи / 2 - получен NACK при передаче адреса / 3 - получен NACK при передаче данных / 4 - другая ошибка. В качестве параметра функция endTransmission() может принимать флаг установки стсояния STOP - по умолчанию true.
#else //
// Если шина управляется функциями нижнего уровня данного класса: //
uint8_t i=0; // Предустанавливаем переменную i в значение 0 - это результат записи
if ( start () ) { i=1; // Если на шине I2C установилось состояние START, то ...
if ( sendID (adr,0) ) { i=2; // Если модуль ответил ACK на получение адреса устройства adr с битом RW=0 (запись), то ...
if ( setByte (reg) ) { i=3; // Если модуль ответил ACK на получение адреса регистра reg, то ...
while(sum>0){if(!setByte(*data )) { i=0;} // Передаём один байт из массива по указателю data в очередной регистр за каждый проход цикла while. Увеличиваем адрес указателя data, и уменьшаем сумму переданных байт sum.
data++; sum--; // Увеличиваем адрес указателя data, и уменьшаем сумму переданных байт sum.
}}}} stop (); return i==3; // Отправляем команду STOP и возвращаем результат записи.
#endif //
} //
//
// Функция пакетной записи нескольких байт данных в модуль: //
bool writeBytes(uint8_t adr, uint8_t *data, uint8_t sum){ // Определяем функцию пакетной записи нескольких байт данных в модуль (аргументы: адресодуля, указатель_наассив, количество_байт)
#if defined(iarduino_I2C_TW) //
// Если используется шина I2C под управлением библиотеки Wire: //
uint8_t i=0; // Предустанавливаем переменную i в значение 0 - это результат записи
Wire.beginTransmission(adr); // Инициируем передачу данных по шине I2C к устройству с адресом adr и битом RW=0 => запись. При этом сама передача не начнётся.
Wire.write(data, sum); // Указываем массив данных который будет отправлен после байта адреса. Функция write() поместит sum элементов массива data в буфер для передачи.
i = Wire.endTransmission(); return i==0; // Выполняем инициированную ранее передачу данных. Функция endTransmission() возвращает: 0-передача успешна / 1 - переполнен буфер для передачи / 2 - получен NACK при передаче адреса / 3 - получен NACK при передаче данных / 4 - другая ошибка. В качестве параметра функция endTransmission() может принимать флаг установки стсояния STOP - по умолчанию true.
#else //
// Если шина управляется функциями нижнего уровня данного класса: //
uint8_t i=0; // Предустанавливаем переменную i в значение 0 - это результат записи
if ( start () ) { i=1; // Если на шине I2C установилось состояние START, то ...
if ( sendID (adr,0) ) { i=2; // Если модуль ответил ACK на получение адреса устройства adr с битом RW=0 (запись), то ...
while(sum>0){if(!setByte(*data )) { i=0;} // Передаём один байт из массива по указателю data в очередной регистр за каждый проход цикла while. Увеличиваем адрес указателя data, и уменьшаем сумму переданных байт sum.
data++; sum--; // Увеличиваем адрес указателя data, и уменьшаем сумму переданных байт sum.
}}} stop (); return i==2; // Отправляем команду STOP и возвращаем результат записи.
#endif //
} //
//
/** ДОПОЛНИТЕЛЬНЫЕ ФУНКЦИИ: **/ //
//
// Функция получения типа реализации шины I2C: // Определяем функцию получения типа шины Ш2С.
uint8_t getType(void){ // Аргументы: отсутсвуют.
#if defined(iarduino_I2C_TW) //
return 4; // Используется аппаратная реализация шины I2C под управлением библиотеки Wire.
#elif defined(iarduino_I2C_HW) //
return 3; // Используется аппаратная реализация шины I2C.
#elif defined(iarduino_I2C_HW_1) //
return 2; // Используется аппаратная реализация шины I2C-1.
#elif defined(iarduino_I2C_SW) //
return 1; // Используется программная реализация шины I2C.
#else //
return 0; // Тип реализации шины I2C не определён.
#endif //
} //
//
// Функция проверки наличия ведомого по его адресу: //
bool checkAddress(uint8_t adr){ // Определяем функцию записи одного байта данных в регистр модуля (аргументы: адрес_регистра, байт_данных)
#if defined(iarduino_I2C_TW) //
// Если используется шина I2C под управлением библиотеки Wire: //
uint8_t i=0; // Предустанавливаем переменную i в значение 0 - это результат проверки.
Wire.beginTransmission(adr); // Инициируем передачу данных по шине I2C к устройству с адресом adr и битом RW=0 => запись. При этом сама передача не начнётся.
i=Wire.endTransmission(); return i==0; // Выполняем инициированную ранее передачу но без данных (отправится только START, байт адреса, STOP). Функция endTransmission() возвращает: 0-передача успешна / 1 - переполнен буфер для передачи / 2 - получен NACK при передаче адреса / 3 - получен NACK при передаче данных / 4 - другая ошибка. В качестве параметра функция endTransmission() может принимать флаг установки стсояния STOP - по умолчанию true.
#else //
// Если шина управляется функциями нижнего уровня данного класса: //
uint8_t i=0; // Предустанавливаем переменную i в значение 0 - это результат записи.
if ( start () ) { i=1; // Если на шине I2C установилось состояние START, то ...
if ( sendID (adr,0) ) { i=2; // Если модуль ответил ACK на получение адреса устройства adr с битом RW=0 (запись), то ...
}} stop (); return i==2; // Отправляем команду STOP и возвращаем результат записи.
#endif //
} //
//
/** ФУНКЦИИ НИЖНЕГО УРОВНЯ: **/ //
//
// Функция нижнего уровня - установка состояния START: // Определяем функцию установки состояния START.
bool start(void){ // Аргументы: отсутствуют.
// _ _ _ _____:___ _ _ _ //
// SCL: : \___ _ _ _ _ _/ //
// _ _ _ _____: _ _ _ _ _ _ // Спад логического уровня на линии SDA с «1» в «0», при наличии уровня логической «1» на линии SCL
// SDA: :\______ _ _/_ _ _ _ _ _ //
// //
#if defined(iarduino_I2C_HW) //
// Если используется аппаратная шина I2C: //
uint16_t i=60000L; // Определяем счётчик указывая максимальное количество циклов для ожидания установки состояния start.
TWCR = _BV(TWINT) | _BV(TWEN) | _BV(TWSTA); // Определяем значение регистра управления TWCR: устанавливаем биты TWINT (флаг прерывания), TWEN (бит разрешения работы шины), TWSTA (бит условия START).
while((!(TWCR & _BV(TWINT))) && i){i--;} // Ждём сброса флага прерывания TWINT в регистре управления TWCR, но не дольше чем i циклов.
if((TWSR & 0xF8)==0x08){return true;} // Проверяем значение регистра статуса TWSR: если его значение с маской 0xF8 равно 0x08, значит состояние START установилось на шине I2C.
return false; // Если предыдущая строка не вернула true, значит состояние START не установилось на шине I2C, возвращаем false.
#elif defined(iarduino_I2C_SW) //
// Если используется программная шина I2C: //
bool i= setSCL(1); // Устанавливаем «1» на линии SCL. Если ведомый удерживает линию SCL прижатой, то функция ждёт освобождения линии и, если не дождётся, то возвращает false.
setSDA(0); // Устанавливаем «0» на линии SDA
setSCL(0); // Устанавливаем «0» на линии SCL
return i; // Если счетчик i не дошел до 0 при ожидании «1» на линии SCL, то вернётся true.
#else //
// Если тип шины I2C не поддерживается или не определён: //
return false; // Возвращаем false.
#endif //
} //
//
// Функция нижнего уровня - установка состояния RESTART: // Определяем функцию установки состояния RESTART.
bool reStart(void){ // Аргументы: отсутствуют.
// _ _ _ ___:___ _ _ _ //
// SCL: \_ _ _ _ / : \___ _ _ _ _ _/ //
// _ _ _ _ _ ________: _ _ _ _ _ _ // Спад логического уровня на линии SDA с «1» в «0», при наличии уровня логической «1» на линии SCL
// SDA: _ _ _ _ _/ :\______ _ _/_ _ _ _ _ _ // Сигнал рестрат аналогичен сигналу старт и отличается лишь тем, что ему не предшествует сигнал STOP
// //
#if defined(iarduino_I2C_HW) //
// Если используется аппаратная шина I2C: //
uint16_t i=60000L; // Определяем счётчик указывая максимальное количество циклов для ожидания установки состояния RESTART.
TWCR = _BV(TWINT) | _BV(TWEN) | _BV(TWSTA); // Определяем значение регистра управления TWCR: устанавливаем биты TWINT (флаг прерывания), TWEN (бит разрешения работы шины), TWSTA (бит условия START).
while((!(TWCR & _BV(TWINT))) && i){i--;} // Ждём сброса флага прерывания TWINT в регистре управления TWCR, но не дольше чем i циклов.
if((TWSR & 0xF8)==0x10){return true;} // Проверяем значение регистра статуса TWSR: если его значение с маской 0xF8 равно 0x10, значит состояние RESTART установилось на шине I2C.
return false; // Если предыдущая строка не вернула true, значит состояние RESTART не установилось на шине I2C, возвращаем false.
#elif defined(iarduino_I2C_SW) //
// Если используется программная шина I2C: //
return start(); // Программная реализация состояния RESTART идентична программной реализации состояния START.
#else //
// Если тип шины I2C не поддерживается или не определён: //
return false; // Возвращаем false.
#endif //
} //
//
// Функция нижнего уровня - установка состояния STOP: // Определяем функцию установки состояния STOP.
void stop(void){ // Аргументы: отсутствуют.
// _ _ _ ___:____ _ _ _ //
// SCL: \_ _ _ _/ : //
// _ _ _ _ _ :____ _ _ _ // Подъём логического уровня на линии SDA с «0» в «1», при наличии уровня логической «1» на линии SCL
// SDA: _ _ _ _ _\______/: //
// //
#if defined(iarduino_I2C_HW) //
// Если используется аппаратная шина I2C: //
uint16_t i=60000L; // Определяем счётчик указывая максимальное количество циклов для ожидания установки состояния STOP
TWCR = _BV(TWINT) | _BV(TWEN) | _BV(TWSTO); // Определяем значение регистра управления TWCR: устанавливаем биты TWINT (флаг прерывания), TWEN (бит разрешения работы шины), TWSTO (бит условия STOP).
while((!(TWCR & _BV(TWSTO))) && i){i--;} // Ждём сброса бита условия стоп TWSTO в регистре управления TWCR, но не дольше чем i циклов
// if((TWSR & 0xF8)==0xA0){return true;} // Проверяем значение регистра статуса TWSR: если его значение с маской 0xF8 равно 0xA0, значит состояние STOP установилось на шине I2C.
delayMicroseconds(20); // Данная функция не возвращает результат, но в любом случае делаем задержку меджу завершением текущего пакета и возможным началом следующего
#elif defined(iarduino_I2C_SW) //
// Если используется программная шина I2C: //
setSDA(0); // Устанавливаем «0» на линии SDA
setSCL(1); // Устанавливаем «1» на линии SCL. Если ведомый удерживает линию SCL прижатой, то функция ждёт освобождения линии и, если не дождётся, то возвращает false.
setSDA(1); // Устанавливаем «1» на линии SDA
#endif //
} //
//
// Функция нижнего уровня - передача первого байта АДРЕС+RW: // Определяем функцию передачи первого байта после cигнала START. Это байт адреса модуля с битом RW
bool sendID(uint8_t adr, bool rw){ // Аргументы: ID-адрес модуля, бит RW (0-запись, 1-чтение)
// 1 2 3 4 5 6 7 8 9 //
// SCL: _ _ _ _____/\_/\_/\_/\_/\_/\_/\_/\__/\_____ _ _ _ //
// ________________________ // Передача 7-битного адреса и 1 бита RW. На 9 тактирубщем импульсе модуль отвечает ACK («0» - «я сдесь»), или NACK («1» - «нет»)
// SDA: _ _ _ ___/________ADDRESS_______RW>----____ _ _ _ //
// вход //
#if defined(iarduino_I2C_HW) //
// Если используется аппаратная шина I2C: //
uint16_t i=60000L; // Определяем счётчик указывая максимальное количество циклов для ожидания получения подтверждения от ведомого ввиде бита ACK.
TWDR = (adr<<1)+rw; // Определяем значение регистра данных TWDR: записываем в него адрес adr сдвигая его на 1 бит влево, при этом младший бит (освободившийся) займёт бит RW (0-запись / 1-чтение)
TWCR = _BV(TWINT) | _BV(TWEN); // Определяем значение регистра управления TWCR: устанавливаем биты TWINT (флаг прерывания) и TWEN (бит разрешения работы шины).
while((!(TWCR & _BV(TWINT))) && i){i--;} // Ждём сброса флага прерывания TWINT в регистре управления TWCR, но не дольше чем i циклов
if((TWSR & 0xF8)==0x40 && rw){return true;} // Проверяем значение регистра статуса TWSR: если его значение с маской 0xF8 равно 0x40, значит ведомый опознал свой адрес с битом RW=1 и отправил бит подтверждения ACK (в противном случае значение регистра TWSR будет равно 0x48).
if((TWSR & 0xF8)==0x18 && !rw){return true;} // Проверяем значение регистра статуса TWSR: если его значение с маской 0xF8 равно 0x18, значит ведомый опознал свой адрес с битом RW=0 и отправил бит подтверждения ACK (в противном случае значение регистра TWSR будет равно 0x20).
return false; // Если предыдущая строка не вернула true, значит на шине нет ведомых у сказанным адресом, возвращаем false.
#elif defined(iarduino_I2C_SW) //
// Если используется программная шина I2C: //
bool i=true; // Определяем флаг возвращаемый данной функцией.
uint8_t j=7; // Определяем счётчик количества переданных бит адреса.
while(j){ j--; // Передаём 7 бит адреса adr в цикле
setSDA(adr & bit(j)); // Устанавливаем очередной бит адреса на линии SDA
if(!setSCL(1) ) {i=false;} // Устанавливаем «1» на линии SCL (Фронт тактирующего импульса). Если ведомый удерживает линию SCL прижатой, то функция ждёт освобождения линии и, если не дождётся, то возвращает false.
setSCL(0); // Устанавливаем «0» на линии SCL (Спад тактирубщего импульса)
} setSDA(rw); // Устанавливаем бит RW на линии SDA
if(!setSCL(1) ) {i=false;} // Устанавливаем «1» на линии SCL (Фронт тактирующего импульса). Если ведомый удерживает линию SCL прижатой, то функция ждёт освобождения линии и, если не дождётся, то возвращает false.
setSCL(0); // Устанавливаем «0» на линии SCL (Спад тактирубщего импульса)
setSDA(1); // Переводим вывод SDA в режим входа с подтяжкой к Vcc
if(!setSCL(1) ) {i=false;} // Устанавливаем «1» на линии SCL (Фронт тактирующего импульса). Если ведомый удерживает линию SCL прижатой, то функция ждёт освобождения линии и, если не дождётся, то возвращает false.
if( getSDA( ) ) {i=false;} // Если на линии SDA установлена «1» значит ведомый ответил NACK
setSCL(0); // Устанавливаем «0» на линии SCL (Спад тактирубщего импульса)
return i; // Если линия SCL была занята или модуль ответил NACK, то вернётся false.
#else //
// Если тип шины I2C не поддерживается или не определён: //
return false; // Возвращаем false
#endif //
} //
//
// Функция нижнего уровня - передача одного байта данных: // Определяем функцию передачи одного байта (в любом месте между байтом адреса с битом RW=0 и сигналом STOP).
bool setByte(uint8_t data){ // Аргумент: байт для передачи.
// 1 2 3 4 5 6 7 8 9 //
// SCL: _ _ _ _____/\_/\_/\_/\_/\_/\_/\_/\__/\_____ _ _ _ //
// ________________________ // Передача 1 байта, каждый бит читается модулем по фронту тактирубщих импульсов. На 9 тактирубщем импульсе модуль отвечает ACK («0» - «принял»), или NACK («1» - «нет»)
// SDA: _ _ _ ___/__________DATA__________>----____ _ _ _ //
// вход //
#if defined(iarduino_I2C_HW) //
// Если используется аппаратная шина I2C: //
uint16_t i=60000L; // Определяем счётчик указывая максимальное количество циклов для ожидания получения подтверждения от ведомого ввиде бита ACK.
TWDR = data; // Определяем значение регистра данных TWDR: записываем в него байт для передачи по шине I2C.
TWCR = _BV(TWINT) | _BV(TWEN); // Определяем значение регистра управления TWCR: устанавливаем биты TWINT (флаг прерывания) и TWEN (бит разрешения работы шины).
while((!(TWCR & _BV(TWINT))) && i){i--;} // Ждём сброса флага прерывания TWINT в регистре управления TWCR, но не дольше чем i циклов
if((TWSR & 0xF8)==0x28){return true;} // Проверяем значение регистра статуса TWSR: если его значение с маской 0xF8 равно 0x28, значит ведомый отправил бит подтверждения приёма данных ACK (в противном случае значение регистра TWSR будет равно 0x30).
return false; // Если предыдущая строка не вернула true, значит ведомый не принял отправленный ему байт, возвращаем false.
#elif defined(iarduino_I2C_SW) //
// Если используется программная шина I2C: //
bool i=true; // Определяем флаг возвращаемый данной функцией.
uint8_t j=8; // Определяем счётчик количества переданных байт.
while(j){ j--; // Передаём 8 бит байта data в цикле
setSDA(data & bit(j)); // Устанавливаем очередной бит байта на линии SDA
if(!setSCL(1) ) {i=false;} // Устанавливаем «1» на линии SCL (Фронт тактирующего импульса). Если ведомый удерживает линию SCL прижатой, то функция ждёт освобождения линии и, если не дождётся, то возвращает false.
setSCL(0); // Устанавливаем «0» на линии SCL (Спад тактирубщего импульса)
} setSDA(1); // Переводим вывод SDA в режим входа с подтяжкой к Vcc
if(!setSCL(1) ) {i=false;} // Устанавливаем «1» на линии SCL (Фронт тактирующего импульса). Если ведомый удерживает линию SCL прижатой, то функция ждёт освобождения линии и, если не дождётся, то возвращает false.
if( getSDA( ) ) {i=false;} // Если на линии SDA установлена «1» значит ведомый ответил NACK
setSCL(0); // Устанавливаем «0» на линии SCL (Спад тактирубщего импульса)
return i; // Если счетчик i не дошел до 0 и не был сброшен в 0 при получении NACK, то вернётся true.
#else //
// Если тип шины I2C не поддерживается или не определён: //
return false; // Возвращаем false
#endif //
} //
//
// Функция нижнего уровня - получение одного байта данных: // Определяем функцию получения одного байта (в любом месте между байтом адреса с битом RW=1 и сигналом STOP).
uint8_t getByte(bool ack){ // Аргумент: бит подтверждения ACK/NACK
// 1 2 3 4 5 6 7 8 9 //
// SCL: _ _ _ _____/\_/\_/\_/\_/\_/\_/\_/\__/\_____ _ _ _ //
// __ // Получение 1 байта, каждый бит читается мастером по фронту тактирубщих импульсов. На 9 тактирубщем импульсе мастер отвечает ACK («0» - «давай еще»), или NACK («1» - «хватит»)
// SDA: _ _ _ ___/----------DATA-----------<__\____ _ _ _ //
// вход выход //
#if defined(iarduino_I2C_HW) //
// Если используется аппаратная шина I2C: //
uint16_t i=60000L; // Определяем счётчик указывая максимальное количество циклов для ожидания.
TWCR = _BV(TWINT) | _BV(TWEN) | ack<<TWEA; // Определяем значение регистра управления TWCR: устанавливаем биты TWINT (флаг прерывания) и TWEN (бит разрешения работы шины), а бит TWEA (бит разрешения подтверждения) устанавливаем только если мы собираемся отправить ведомому бит подтверждения получения данных ACK.
while((!(TWCR & _BV(TWINT))) && i){i--;} // Ждём сброса флага прерывания TWINT в регистре управления TWCR, но не дольше чем i циклов
if((TWSR & 0xF8)==0x50 && ack){return TWDR;} // Проверяем значение регистра статуса TWSR: если его значение с маской 0xF8 равно 0x50, значит данные приняты и сохранены в регистре TWDR, а ведомому отправлен бит ACK.
if((TWSR & 0xF8)==0x58 && !ack){return TWDR;} // Проверяем значение регистра статуса TWSR: если его значение с маской 0xF8 равно 0x58, значит данные приняты и сохранены в регистре TWDR, а ведомому отправлен бит NACK.
return 0; // Если предыдущая строка не вернула принятый байт из регистра данных TWDR, значит мы не приняли байт, возвращаем 0.
#elif defined(iarduino_I2C_SW) //
// Если используется программная шина I2C: //
bool i=true; // Определяем флаг возвращаемый данной функцией.
uint8_t j=8; // Определяем счётчик количества полученных битов байта.
uint8_t k=0; // Объявляем переменную для хранения прочитанного байта данных.
setSDA(1); // Переводим вывод SDA в режим входа с подтяжкой к Vcc
while(j){ j--; // Получаем 8 бит байта в цикле
if(!setSCL(1) ) {i=false;} // Устанавливаем «1» на линии SCL (Фронт тактирующего импульса). Если ведомый удерживает линию SCL прижатой, то функция ждёт освобождения линии и, если не дождётся, то возвращает false.
if( getSDA( ) ) { k |= (1<<j); } // Заполняем биты байта k в соотсетствии с уровнем на линии SDA
setSCL(0); // Устанавливаем «0» на линии SCL (Спад тактирубщего импульса)
} setSDA(!ack); // Устанавливаем бит «ACK/NACK» на линии SDA (ACK-прижимаем, NACK-отпускаем)
if(!setSCL(1) ) {i=false;} // Устанавливаем «1» на линии SCL (Фронт тактирующего импульса). Если ведомый удерживает линию SCL прижатой, то функция ждёт освобождения линии и, если не дождётся, то возвращает false.
setSCL(0); // Устанавливаем «0» на линии SCL (Спад тактирубщего импульса)
return i?k:0; // Если во время ожидания поднятия логического уровня на линии SCL, cчётчик i не дошел до 0, то функция вернёт байт из переменной k.
#else //
// Если тип шины I2C не поддерживается или не определён: //
return 0; // Возвращаем false
#endif //
} //
//
private: //
uint8_t pin_SDA = pin_SW_SDA; // Определяем вывод pin_SDA.
uint8_t pin_SCL = pin_SW_SCL; // Определяем вывод pin_SCL.
uint8_t port_SDA; // Объявляем переменную для хранения номера порта вывода pin_SDA.
uint8_t port_SCL; // Объявляем переменную для хранения номера порта вывода pin_SCL.
uint8_t mask_SDA; // Объявляем переменную для хранения позиции бита управления выводом pin_SDA.
uint8_t mask_SCL; // Объявляем переменную для хранения позиции бита управления выводом pin_SCL.
volatile uint8_t *mod_SDA; // Объявляем указатель на регистр направления работы выводов порта port_SDA.
volatile uint8_t *mod_SCL; // Объявляем указатель на регистр направления работы выводов порта port_SCL.
volatile uint8_t *inp_SDA; // Объявляем указатель на регистр входных значений порта port_SDA.
volatile uint8_t *inp_SCL; // Объявляем указатель на регистр входных значений порта port_SCL.
volatile uint8_t *out_SDA; // Объявляем указатель на регистр выходных значений порта port_SDA.
volatile uint8_t *out_SCL; // Объявляем указатель на регистр выходных значений порта port_SCL.
//
// функция установки уровня на линии SCL: // Определяем функцию установки уровня на линии SCL.
bool setSCL(bool f){ // Аргумент: логический уровень.
uint16_t i=60000L; // Определяем счётчик ожидания освобождения линии SCL.
if(!f) {*mod_SCL |= mask_SCL; *out_SCL &= ~mask_SCL;} // Устанавливаем «0» на линии SCL (Спад тактирубщего импульса) pinMode(pin_SCL, OUTPUT); digitalWrite(pin_SCL, LOW );
else {*mod_SCL &= ~mask_SCL; *out_SCL |= mask_SCL; // Устанавливаем «1» на линии SCL (Фронт тактирующего импульса) pinMode(pin_SCL, INPUT ); digitalWrite(pin_SCL, HIGH);
while((*inp_SCL & mask_SCL)==0 && i){i--;} } // Ждём поднятия логического уровня на линии SCL while(digitalRead(pin_SCL)==0 && i){ цикл выполняется пока на линии 0 или пока i не сброситя d 0}
return i; //
} //
//
// Функция установки уровня на линии SDA: // Определяем функцию установки уровня на линии SDA.
void setSDA(bool f){ // Аргумент: логический уровень.
if(!f) {*mod_SDA |= mask_SDA; *out_SDA &= ~mask_SDA;} // Устанавливаем «0» на линии SDA (если бит RW=«0») pinMode(pin_SDA, OUTPUT); digitalWrite(pin_SDA, LOW );
else {*mod_SDA &= ~mask_SDA; *out_SDA |= mask_SDA;} // Устанавливаем «1» на линии SDA (если бит RW=«1») pinMode(pin_SDA, INPUT ); digitalWrite(pin_SDA, HIGH );
} //
//
// Функция чтения уровня с линии SDA: // Определяем функцию чтения уровня с линии SDA. Перед чтением необходимо вызвать функцию setSDA(1) которая переведёт вывод SDA в режим входа
bool getSDA(void){ return (*inp_SDA & mask_SDA); } // Аргументы: отсутсвуют. digitalRead(pin_SDA);
}; //
//
#endif //

View File

@@ -0,0 +1,43 @@
#ifndef iarduino_RTC_RX8025_h //
#define iarduino_RTC_RX8025_h //
#define RTC_RX8025 4 // Модуль часов реального времени с протоколом передачи данных I2C, памятью 016x8, температурной компенсацией, двумя будильниками и встроенным кварцевым резонатором
#include "iarduino_RTC_I2C.h" // Подключаем файл iarduino_RTC_I2C.h - для работы с шиной I2C
//
class iarduino_RTC_RX8025: public iarduino_RTC_BASE{ //
public: //
/** функции доступные пользователю **/ //
// Инициализация модуля: //
void begin(void){ // (без параметров)
// Инициализация работы с шиной I2C: //
objI2C.begin(100); // (скорость шины в кГц)
// Установка флагов управления и состояния модуля: //
delay(10); objI2C.writeByte(valAddress, 0x0F, 0xA0); // Записываем байт 0xA0 (10100000) в регистр 0x0F (Control-2): VDSL=1 пороговое напряжение 1.3В, VDET=0 перезапуск определения падения мощности, /XST=1 перезапуск определения остановки колебаний, PON=0 перезапуск сброса при вкл питания, 0, CTFG=0 сброс периодического прерывания, WAFG=0 и DAFG=0 сброс прерываний будильников Alarm_D и Alarm_W
delay(10); objI2C.writeByte(valAddress, 0x0E, 0x20); // Записываем байт 0x20 (00100000) в регистр 0x0E (Control-1): WALE=0 и DALE=0 отключение будильников Alarm_W и Alarm_D, /12,24=1 переключение в 24-часовой формат, 00, CT2-0=000 отключение периодического прерывания.
} //
//
// Чтение одного значения из регистров даты и времени модуля: //
uint8_t funcReadTimeIndex(uint8_t i){ // (i = 0-секунды / 1-минуты / 2-часы / 3-день / 4-месяц / 5-год / 6-день недели)
delay(1); //
varI = objI2C.readByte(valAddress, arrTimeRegAddr[i]) & arrTimeRegMack[i]; // Читаем байт из регистра arrTimeRegAddr[i] с маской arrTimeRegMack[i] в переменную varI.
if(i==6){for(uint8_t j=1;j<8;j++){if(varI&bit(j-1)){return j;}} return 1;} // Если запрошен день недели, то возвращаем позицию (1...7) установленного бита в байте varI.
// if( i==6 ){ varI++; } // Если чип считает день недели как написано в datasheet, то раскомментируйте данную строку и закомментируйте предыдущую.
return varI; //
} //
//
// Запись одного значения в регистры даты и времени модуля: //
void funcWriteTimeIndex(uint8_t i, uint8_t j){ // (i = 0-секунды / 1-минуты / 2-часы / 3-день / 4-месяц / 5-год / 6-день недели, j = значение)
if( i==6 ){ if( (j==0)||(j>7) ){ j=1; } j=bit(j-1); } // Устанавливаем один бит в переменной j;
// if( i==6 ){j--;} // Если чип считает день недели как написано в datasheet, то раскомментируйте данную строку и закомментируйте предыдущую.
objI2C.writeByte(valAddress, arrTimeRegAddr[i], j&arrTimeRegMack[i]); // Сохраняем значение j в регистр arrTimeRegAddr[i] с маской arrTimeRegMack[i].
} //
//
private: //
/** Внутренние переменные **/ //
iarduino_I2C objI2C; // Создаём объект для работы с шиной I2C
uint8_t valAddress = 0x32; // Адрес модуля на шине I2C
uint8_t arrTimeRegAddr[7] = {0x00,0x01,0x02,0x04,0x05,0x06,0x03}; // Определяем массив с адресами регистров даты и времени (сек, мин, час, день, месяц, год, день недели)
uint8_t arrTimeRegMack[7] = {0x7F,0x7F,0x3F,0x3F,0x1F,0xFF,0x7F}; // Определяем маскировочный массив для регистров даты и времени (при чтении/записи, нужно совершить побитовое «и»)
uint8_t varI; //
}; //
//
#endif //

View File

@@ -0,0 +1,9 @@
// Файл: «ХРАНИТЕЛЬ ПАМЯТИ»
// Если закомментировать строки с названиями тех модулей которые не используются в Вашем устройстве, можно освободить около 50 байт флеш-памяти.
// Если закомментировать строку с названием используемого модуля, компилятор выдаст ошибку.
#define RTC_ENABLE_DS1302 1 // Модуль часов реального времени (RTC) на базе чипа DS1302, с протоколом передачи данных SI3, памятью 040x8 (31 байт которой доступны для хранения данных пользователя).
#define RTC_ENABLE_DS1307 1 // Модуль часов реального времени (RTC) на базе чипа DS1307, с протоколом передачи данных I2C, памятью 064x8 (56 байт которой доступны для хранения данных пользователя).
#define RTC_ENABLE_DS3231 1 // Модуль часов реального времени (RTC) на базе чипа DS3231, с протоколом передачи данных I2C, памятью 019x8, температурной компенсацией, двумя будильниками и встроенным кварцевым резонатором.
#define RTC_ENABLE_RX8025 1 // Модуль часов реального времени (RTC) на базе чипа RX8025, с протоколом передачи данных I2C, памятью 016x8, температурной компенсацией, двумя будильниками и встроенным кварцевым резонатором.