Сегодня мы продолжим поиски идеальной микросхемы часов реального времени (RTC). Часы будем изготавливать на основе DS3231. Индикация будет использоваться более удобная для разработки — LCD дисплей, на котором будет отображаться вся информация сразу кроме настроек. В таком виде часы удобно использовать как настольный вариант.
Итак, рассмотрим саму микросхему DS3231. DS3231 — это часы реального времени с экстремально точным ходом (подобрали же производители словечко) благодаря встроенному кварцевому резонатору с температурной компенсацией. Интерфейс передачи данных — I2C. В этой микросхеме есть также вход для напряжения резервной батареи, при отключении основного питания микросхема автоматически переключается на работу от резервной батареи, точность хода от резервной батареи не нарушается. Весьма радует, не правда ли? В DS3231 поддерживается подсчет секунд, минут, часов, дней месяца (даты), дней недели, месяцев и лет (с учетом високосного года для месяцев). Поддерживается работа в 12 и 24 часовом формате. Имеется 2 будильника с возможностью их настройки и отслеживания состояния. Подстройка точности температурной компенсации. А также два выхода — на 32 кГц (выход составляет 32.768 кГц) и программируемый выход от 1 Гц до 8.192 кГц. Имеется также вывод сброса — RST. микросхема часов реального времени выпускается в корпусе SO-16. Корпус достаточно крупный, но если учитывать что внутри уже имеется кварц, да ещё и температурно компенсируемый, то мне кажется, с размерами тут все отлично. У DS3231 есть близнец в виде DS3232, у которого, правда, на 2 ножки больше. Все это очень напоминает продукцию компании NXP — микросхемы часов PCA2129 и PCF2129. Аналогично температурно компенсируемый встроенных кварцевый резонатор, оба такие же близнецы лишь с разным количеством n.c. выводов и схожими функциями относительно DS3231 помимо хронометрожа времени.
RTC DS3231 имеются в продаже в виде модулей с необходимой обвязкой, а также до комплекта микросхемой EEPROM, которая чаще всего и даром не нужно, лишь веса добавляет:
Кроме необходимых деталей на плате модуля есть также светодиод, функция которого — индикация подключения питания к выводам. Наверно просто так доставили, для красоты.
Что важно знать при работе с такой микросхемой часов реального времени, так это как же извлечь из нее данные или записать их туда. Часы имеют интерфейс I2C. Для того чтобы осуществить запись данных (а это нужно и для того чтобы прочитать данные) нужно передать условие старта (эти команды осуществляются по средствам аппаратного или программного I2C для микроконтроллера), далее передать адрес микросхемы с битом записи, далее передать адрес регистра к которому будем обращаться и далее передать в этот регистр байт данных, если следом передать ещё байт данных, он запишется в следующий регистр и так далее. По окончании нужно передать условие остановки. Графическое изображение выше сказанного на рисунке:
Запись данных необходима для первоначальной настройки, а также для настройки текущего времени. Далее нам нужно постоянно получать данные о текущем времени и даты. Для этого необходимо осуществлять чтение из регистров хранения этой информации. Чтение состоит из 2-х процедур — установить указатель на нужный регистр и прочитать его. Чтобы установить указатель на нужный регистр, нужно передать условие старта, потом передать адрес микросхемы с битом записи и байт с адресом регистра. Далее либо условие остановки и следом условие старта, либо просто рестарт. Теперь вторая процедура — непосредственно чтение из регистров. Старт передан, далее нужно отправить адрес микросхемы с битом чтения и далее считывать регистры в необходимом количестве, по окончании передать условие остановки. Если информация из регистра была прочитана, то указатель автоматически переходит на следующий за ним регистр без лишних действий со стороны микроконтроллера (мастер устройства). На рисунке проиллюстрировано все выше сказанное относительно чтения регистров по средствам I2C интерфейса:
Адрес микросхемы:
- для записи — 0b11010000
- для чтения — 0b11010001
Программно код на языке Си будет выглядеть следующим образом:
// функции с часами =======================================================================================================
// инициализация начальных установок
void RTC_init(void){
i2c_start_cond(); // запуск i2c
i2c_send_byte(RTC_adr_write); // передача адреса устройства, режим записи
i2c_send_byte(0x0E); // передача адреса памяти
i2c_send_byte(0b00100000); // запустить преобразование температуры и выход на 1 Гц
i2c_send_byte(0b00001000); // разрешить выход 32 кГц
i2c_stop_cond(); // остановка i2c
}
// получение времени и даты
void RTC_read_time(void){
i2c_start_cond(); // запуск i2c
i2c_send_byte(RTC_adr_write); // передача адреса устройства, режим записи
i2c_send_byte(0x00); // передача адреса памяти
i2c_stop_cond(); // остановка i2c
i2c_start_cond(); // запуск i2c
i2c_send_byte(RTC_adr_read); // передача адреса устройства, режим чтения
sec = bcd(i2c_get_byte(0)); // чтение секунд, ACK
min = bcd(i2c_get_byte(0)); // чтение минут, ACK
hour = bcd(i2c_get_byte(0)); // чтение часов, ACK
wday = bcd(i2c_get_byte(0)); // чтение день недели, ACK
day = bcd(i2c_get_byte(0)); // чтение число, ACK
month = bcd(i2c_get_byte(0)); // чтение месяц, ACK
year = bcd(i2c_get_byte(1)); // чтение год, NACK
i2c_stop_cond(); // остановка i2c
}
// установка времени
void RTC_write_time(unsigned char hour1,unsigned char min1, unsigned char sec1){
i2c_start_cond(); // запуск i2c
i2c_send_byte(RTC_adr_write); // передача адреса устройства, режим записи
i2c_send_byte(0x00); // передача адреса памяти
i2c_send_byte(bin(sec1)); // 0x00 секунды (целесообразно ли задавать ещё и секунды?)
i2c_send_byte(bin(min1)); // 0x01 минуты
i2c_send_byte(bin(hour1)); // 0x02 часы
i2c_stop_cond(); // остановка i2c
}
// установка даты
void RTC_write_date(unsigned char wday, unsigned char day, unsigned char month, unsigned char year){
i2c_start_cond(); // запуск i2c
i2c_send_byte(RTC_adr_write); // передача адреса устройства, режим записи
i2c_send_byte(0x03); // передача адреса памяти
i2c_send_byte(bin(wday)); // 0x03 день недели (воскресенье — 1, пн 2, вт 3, ср 4, чт 5, пт 6, сб 7)
i2c_send_byte(bin(day)); // 0x04 день месяц
i2c_send_byte(bin(month)); // 0x05 месяц
i2c_send_byte(bin(year)); // 0x06 год
i2c_stop_cond(); // остановка i2c
}
// чтение температуры
void RTC_read_temper(void){
i2c_start_cond(); // запуск i2c
i2c_send_byte(RTC_adr_write); // передача адреса устройства, режим записи
i2c_send_byte(0x11); // передача адреса памяти
i2c_stop_cond(); // остановка i2c
i2c_start_cond(); // запуск i2c
i2c_send_byte(RTC_adr_read); // передача адреса устройства, режим чтения
t1 = i2c_get_byte(0); // чтение MSB температуры
t2 = i2c_get_byte(1); // чтение LSB температуры
i2c_stop_cond(); // остановка i2c
t2=(t2/128); // сдвигаем на 6 — точность 0,25 (2 бита)
// сдвигаем на 7 — точность 0,5 (1 бит)
t2=t2*5;
}
Это весь исходный код, использовавшийся для работы с микросхемой, подстройка хода часов не затрагивалась, потому что и без того часы не ушли ни на секунду за несколько дней.
Да — отличной фишкой DS3231 является то, что эта же микросхема выполняет функции термометра (а то как же ещё осуществлять температурную компенсацию) и возможность чтения текущей температуры. Максимальное разрешение температуры составляет 0.25 градусов Цельсия. Также период обновления температуры достаточно большой — около 1 минуты. Да нам быстро то не к чему обновлять ее.
Схема же всего устройства часов выглядит так:
Микроконтроллер был выбран Atmega8 за свою широкую распространенность и небольшую цену. Данный микроконтроллер можно использовать как в корпусе DIP-28, так и в SMD исполнении в корпусе TQFP-32. Резистор R3 необходим для предотвращения самопроизвольного перезапуска микроконтроллера в случае появления случайных помех на выводе PC6. Резистор R3 подтягивает плюс питания к этому выводу, надежно создавая потенциал на нем. Для индикации используется жидко кристаллический (ЖК или LCD) дисплей. Мною использовался дисплей 2004А — 4 строки по 20 символов больше для красоты, поэтому можно применять дисплей более привычный — 2 строки по 16 символов. ЖК дисплей подключается к микроконтроллеру по 4-х битной системе. Переменный резистор R2 необходим для регулировки контраста символов на дисплее. Вращением движка этого резистора добиваемся наиболее четких для нас показаний на экране. Подсветка ЖК дисплея организована через вывод «А» и «К» на плате дисплея. Подсветка включается через резистор, ограничивающий ток — R1. Чем больше номинал, тем более тускло будет подсвечиваться дисплей. Но пренебрегать этим резистором не стоит во избежание порчи подсветки. Кнопки S1 — S4 управляют настройками часов. Светодиод сигнализирует о том, что будильник сработал. Светодиод можно заменить на какую-либо звуковую схему. Резисторы R5 — R8 являются подтягивающими (pull-up) и необходимы для формирования прямоугольных импульсов на выводах микросхемы часов. Также это необходимо для правильной работы протокола I2C. Для питания схемы используется микросхема линейного стабилизатора L7805, ее можно заменить на отечественный аналог пяти вольтового линейного стабилизатора КР142ЕН5А, либо применить другу микросхему стабилизатора напряжения в соответствии с подключением ее в схеме (например LM317 или импульсные стабилизаторы LM2576, LM2596, MC34063 и так далее). Далее 5 вольт стабилизируются другой микросхемой — AMS1117 в исполнении, дающей на выходе 3,3 вольта. Микросхема часов, в соответствии с даташитом, питается от напряжения 3,3 вольта. Но максимальное напряжение составляет 5,5 вольта. Потому Данный стабилизатор можно использовать, а можно и нет, на ваше усмотрение. Стабилизатор напряжения AMS1117 можно также заменить на исполнение ADJ (AMS1117ADJ) — то есть регулируемый вариант, задать необходимое напряжение при таком выборе необходимо будет при помощи 2-х резисторов, подключаемых к микросхеме в соответствии с даташитом на нее.
Схема была собрана и отлажена с применением отладочной макетной платы для микроконтроллера ATmega8:
Назначение кнопок:
- S1 — отключает сигнал будильника, либо выходит в главное меню из любого меню настроек
- S2 — сброс микроконтроллера
- S3 — изменяет время или дату в меню настроек
- S4 — вход в меню настроек и перелистывание меню
Вывод 32 кГц может использоваться для контроля частоты кварцевого резонатора. Подключаем к этому выводу частотомер или осциллограф и контролируем частоту:
Как видно из скриншота осциллограммы, частота примерно соответствует 32,768 кГц (примерно в силу ограничения разрешения измерения частоты, а «на глаз» наслишь точно трудно определить).
В итоге получились часы со следующими характеристиками:
- индикация времени
- индикация даты
- индикация дня недели
- индикация активности будильника
- 1 будильник с выходом сигнала от микроконтроллера
- индикация температуры окружающей среды (программно реализована лишь положительная температура, отрицательная, думаю, нам ни к чему)
- настройки будильника
- настройки времени
- настройки даты
- LCD-дисплей с подсветкой
- сохранение настроек и продолжение хода часов при отключении основного питания
Подытожим. Микросхема часов реального времени DS3231 является отличным решением. Точность хода сравнительно c какой-нибудь DS1307 или PCF8523 выше, а вот PCA/PCF2129 ещё могут потягаться с ней. Среди рассмотренных мною микросхем часов реального времени данный экземпляр на сегодняшний день занимает первое место по функционалу и точности.
Для программирования микроконтроллера Atmega8 необходимо знать конфигурацию фьюз битов (скриншот сделан в программе AVR Studio):
К статье прилагается прошивка для микроконтроллера Atmega8, проект схемы в программе Proteus, а также видео работы часов (в самом начале сработает будильник — загорится светодиод).
Список радиоэлементовОбозначение
Тип
Номинал
Количество
ПримечаниеМагазинМой блокнот
IC1
МК AVR 8-битATmega81
IC2
Часы реального времени (RTC)DS32311
VR1
Линейный регуляторL7805AB1
VR2
Линейный регуляторAMS1117-3.31
VD1
Выпрямительный диод1N41481
C1
Электролитический конденсатор470 мкФ1
C2, C3, C5, C7
Конденсатор100 нФ4
C4
Электролитический конденсатор220 мкФ1
C6, C8
Электролитический конденсатор10 мкФ2
R1
Резистор22 Ом1
R2
Подстроечный резистор10 кОм1
3296W-1-103LFR3, R5-R8
Резистор10 кОм5
R4
Резистор390 Ом1
R9
Резистор220 Ом1
LED1
Светодиод1
HG1
LCD-дисплей2004A1
Можно заменить на SC1602S1-S4
Тактовая кнопкаTC-A1094
Элемент питанияCR20321
3 Вольт
Держатель CR20321
Добавить все
Скачать список элементов (PDF)
Прикрепленные файлы:
- 38.hex (9 Кб)
- prott.rar (35 Кб)
- плата от gnom 46.rar (75 Кб)