Микросхема DS3231 представляет собой высокоточные часы реального времени RTC, которая обладает встроенным кварцевым генератором с температурной компенсацией, благодаря чему уход времени составляет всего ±2 минуты за год. Дополнительно реализована функция будильника, также имеется выход прерываний. Часы можно приобрести в виде готового модуля под Arduino с элементами обвязки и отсеком для батареи.
Я заказывал модуль здесь. Схема представлена на картинке ниже:
Микросхема использует широко распространенный интерфейс передачи данных I2C. Поддерживается стандартная (100 кГц) и высокая (400 кГц) скорость передачи данных. Адрес микросхемы (7 бит) на шине I2C равен 1101000. Дополнительно на модуле установлена память I2C (24C32), на схеме не изображена.
Режимы электропитания
Напряжение питания микросхемы может находиться в пределах 2,3…5,5В, имеются две линии питания, для внешнего источника (линия Vcc), а также для батареи (Vbat). Напряжение внешнего источника постоянно отслеживается, при падении ниже порога Vpf=2,5В, происходит переключение на линию батареи. В следующей таблице представлены условия переключения между линиями питания:
Комбинации уровней напряжения | Активная линия питания |
Vcc < Vpf, Vcc < Vbat | Vbat |
Vcc < Vpf, Vcc > Vbat | Vcc |
Vcc > Vpf, Vcc < Vbat | Vcc |
Vcc > Vpf, Vcc > Vbat | Vcc |
Точность хода часов поддерживается за счет отслеживания температуры окружающей среды. В микросхеме запускается внутренняя процедура корректировки частоты тактового генератора, величина корректировки определяется по специальному графику зависимости частоты от температуры. Процедура запускается после подачи питания, а затем выполняется каждые 64 секунды.
В целях сохранения заряда, при подключении батареи (подача напряжения на линию Vbat), тактовый генератор не запускается до тех пор, пока напряжение на линии Vcc не превысит пороговое значение Vpf, или не будет передан корректный адрес микросхемы по интерфейсу I2C. Время запуска тактового генератора составляет менее одной секунды. Примерно через 2 секунды после подачи питания (Vcc), или получения адреса по интерфейсу I2C, запускается процедура коррекции частоты. После того как тактовый генератор запустился, он продолжает функционировать до тех пор, пока присутствует напряжение Vcc или Vbat. При первом включении регистры даты и времени сброшены, и имеют следующие значения 01/01/ 00 – 01 – 00/00/00 (день/месяц/год/ – день недели – час/минуты/секунды).
Ток потребления при питании от батареи напряжением 3,63В, составляет 3 мкА, при отсутствии передачи данных по интерфейсу I2C. Максимальный ток потребления может достигать 300 мкА, в случае использования внешнего источника питания напряжением 5,5В, и высокой скорости передачи данных I2C.
Функция внешнего сброса
Линия RST может использоваться для внешнего сброса, а также обладает функцией оповещения о низком уровне напряжения. Линия подтянута к высокому логическому уровню через внутренний резистор, внешняя подтяжка не требуется. Для использования функции внешнего сброса, между линией RST и общим проводом можно подключить кнопку, в микросхеме реализована защита от дребезга контактов. Функция оповещения активируется при снижении напряжения питания Vcc ниже порогового значения Vpf, при этом на линии RST устанавливается низкий логический уровень.
Описание регистров DS3231
Ниже в таблице представлен перечень регистров часов реального времени:
Адрес | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 | Функция | Пределы |
0x00 | 0 | 10 секунд | Секунды | Секунды | 00-59 | |||||
0x01 | 0 | 10 минут | Минуты | Минуты | 00-59 | |||||
0x02 | 0 | 12/24 | AM/PM | 10 часов | Час | Часы | 1-12 + AM/PM или 00-23 | |||
10 часов | ||||||||||
0x03 | 0 | 0 | 0 | 0 | 0 | День | День недели | 1-7 | ||
0x04 | 0 | 0 | 10 число | Число | Дата | 01-31 | ||||
0x05 | Century | 0 | 0 | 10 месяц | Месяц | Месяцы/век | 01-12 + Век | |||
0x06 | 10 лет | Год | Годы | 00-99 | ||||||
0x07 | A1M1 | 10 секунд | Секунды | Секунды, 1-й будильник | 00-59 | |||||
0x08 | A1M2 | 10 минут | Минуты | Минуты, 1-й будильник | 00-59 | |||||
0x09 | A1M3 | 12/24 | AM/PM | 10 часов | Час | Часы, 1-й будильник | 1-12 + AM/PM или 00-23 | |||
10 часов | ||||||||||
0x0A | A1M4 | DY/DT | 10 число | День | День недели, 1-й будильник | 1-7 | ||||
Число | Дата, 1-й будильник | 01-31 | ||||||||
0x0B | A2M2 | 10 минут | Минуты | Минуты, 2-й будильник | 00-59 | |||||
0x0C | A2M3 | 12/24 | AM/PM | 10 часов | Час | Часы, 2-й будильник | 1-12 + AM/PM или 00-23 | |||
10 часов | ||||||||||
0x0D | A2M4 | DY/DT | 10 число | День | День недели, 2-й будильник | 1-7 | ||||
Число | Дата, 2-й будильник | 01-31 | ||||||||
0x0E | EOSC | BBSQW | CONV | RS2 | RS1 | INTCN | A2IE | A1IE | Регистр настроек (Control) | |
0x0F | OSF | 0 | 0 | 0 | EN32kHz | BSY | A2F | A1F | Регистр статуса (Status) | |
0x10 | SIGN | DATA | DATA | DATA | DATA | DATA | DATA | DATA | Регистр подстройки частоты (Aging Offset) | |
0x11 | SIGN | DATA | DATA | DATA | DATA | DATA | DATA | DATA | Регистр температуры, старший байт | |
0x12 | DATA | DATA | 0 | 0 | 0 | 0 | 0 | 0 | Регистр температуры, младший байт |
Информация о времени хранится в двоично-десятичном формате, то есть каждый разряд десятичного числа (от 0 до 9) представляется группой из 4-х бит. В случае одного байта, младший полубайт отсчитывает единицы, старший десятки и т. д. Счет времени осуществляется в регистрах с адресами 0x00-0x06, для отсчета часов можно выбрать режим 12-ти или 24-х часов. Установка 6-го бита регистра часов (адрес 0x02), задает 12-ти часовой режим, в котором 5-й бит указывает на время суток, значению 1 соответствует время после полудня (PM), значению 0 до полудня (AM). Нулевое значение 6-го бита соответствует 24-х часовому режиму, здесь 5-й бит участвует в счете часов (значения 20-23).
Регистр дня недели инкрементируется в полночь, счет идет от 1 до 7, регистр месяцев (адрес 0x05) содержит бит века Century (7-й бит), который переключается при переполнении регистра счета лет (адрес 0x06), от 99 к 00.
В микросхеме DS3231 реализовано два будильника, 1-й будильник настраивается с помощью регистров с адресами 0x07-0x0A, 2-й будильник регистрами 0x0B-0x0D. Битами A1Mx и A2Mx можно настроить различные режимы для будильников, установка бита исключает соответствующий регистр из операции сравнения. Ниже в таблицах приведены комбинации битов для разных режимов будильника:
Будильник 1 | |||||
DY/DT | A1M4 | A1M3 | A1M2 | A1M1 | Режим будильника |
X | 1 | 1 | 1 | 1 | Сигнал каждую секунду |
X | 1 | 1 | 1 | 0 | Сигнал при совпадении секунд |
X | 1 | 1 | 0 | 0 | Сигнал при совпадении минут, секунд |
X | 1 | 0 | 0 | 0 | Сигнал при совпадении часа, минут, секунд |
0 | 0 | 0 | 0 | 0 | Сигнал при совпадении даты, часа, минут, секунд |
1 | 0 | 0 | 0 | 0 | Сигнал при совпадении дня недели, часа, минут, секунд |
Будильник 2 | ||||
DY/DT | A2M4 | A2M3 | A2M2 | Режим будильника |
X | 1 | 1 | 1 | Сигнал каждую минуту (при значении 00 секунд) |
X | 1 | 1 | 0 | Сигнал при совпадении минут |
X | 1 | 0 | 0 | Сигнал при совпадении часа, минут |
0 | 0 | 0 | 0 | Сигнал при совпадении даты, часа, минут |
1 | 0 | 0 | 0 | Сигнал при совпадении дня недели, часа, минут |
Комбинации битов не указанные в таблицах, приводят к некорректному функционированию будильников. Если бит DY/DT сброшен, то для будильника отслеживается совпадение даты (день месяца), при установке бита DY/DT, проверяется совпадение дня недели.
Большинство функций настраиваются в регистре Control. Бит EOSC управляет запуском тактового генератора, сброс бита запускает генератор. Установка бита останавливает генератор, только для режима питания от батареи (Vbat). При питании от внешнего источника (Vcc), генератор всегда запущен независимо от состояния бита EOSC. После включения, значение бита по умолчанию равно 0.
Установка бита BBSQW разрешает функционирование выхода INT/SQW (3-й вывод) в режиме питания от батареи, при отсутствии внешнего питания. При нулевом значении бита, выход INT/SQW переходит в 3-е состояние (деактивируется), если напряжение внешнего источника Vcc падает ниже порогового значения Vpf. После подачи питания, значение бита по умолчанию равно 0.
Бит CONV отвечает за принудительное измерение температуры, установка бита запускает процесс преобразования, во время которого также выполняется корректировка частоты тактового генератора, результат измерения находится в регистрах с адресами 0x11, 0x12. Запуск возможен только в случае окончания предыдущего преобразования, перед запуском необходимо проверить флаг занятости BSY. Принудительное преобразование температуры не влияет на внутренний 64-х секундный цикл корректировки частоты. Установка бита CONV не влияет на флаг BSY в течение 2 мс. Биты CONV и BSY сбрасываются автоматически после завершения преобразования.
Биты RS2, RS1 устанавливают частоту прямоугольных импульсов (меандр) на выходе INT/SQW. По умолчанию, при включении биты устанавливаются в 1. Ниже в таблице представлены возможные комбинации битов:
RS2 | RS1 | Частота прямоугольных импульсов на выходе INT/SQW |
0 | 0 | 1 Гц |
0 | 1 | 1,024 кГц |
1 | 0 | 4,096 кГц |
1 | 1 | 8,192 кГц |
Бит INTCN управляет выходом INT/SQW. Если бит сброшен, на выходе появляются прямоугольные импульсы (меандр), частота которых задается битами RS2, RS1. При установке бита INTCN, выход используется для генерации прерываний по сигналу будильника. По умолчанию, значение бита равно 1. Тип выхода INT/SQW – открытый сток, соответственно необходима подтяжка через резистор к высокому логическому уровню, активный уровень – низкий.
Установка битов A1IE, A2IE разрешает прерывания по сигналу 1-го и 2-го будильника соответственно. Сброс битов, запрещает прерывания. По умолчанию значение равно 0.
Регистр Status содержит флаги событий, и управляет выходом 32 kHz. Флаг OSF отражает состояние тактового генератора, значение 1, означает, что генератор остановлен, это событие может произойти в следующих случаях:
- В первое время после подачи питания
- Напряжение батареи или внешнего источника недостаточно для работы тактового генератора
- Генератор выключен установкой бита EOSC в режиме питания от батареи
- Внешние факторы, влияющие на кварцевый генератор (шум, утечка и т.д.)
После установки значение бита не меняется, необходимо сбросить бит вручную.
Установка бита EN32kHz разрешает генерирование прямоугольных импульсов (меандр) на выходе 32kHz (1-й вывод), частота импульсов фиксирована и равна 32,768 кГц. Сброс бита отключает данную функцию и переводит выход в 3-е состояние (с высоким входным сопротивлением). По умолчанию значение бита равно 1, после подачи питания на выходе появляются импульсы. Тип выхода 32kHz открытый сток, поэтому требуется подтяжка к высокому логическому уровню.
Флаг занятости BSY устанавливается во время процесса преобразования температуры и корректировки частоты тактового генератора. Флаг сбрасывается после завершения преобразования.
Флаги будильников A1F, A2F устанавливаются при совпадении значений регистров счета времени и регистров будильника. Если разрешены прерывания по сигналу будильников A1IE, A2IE, а также назначен выход прерывания (установлен бит INTCN), то на выходе INT/SQW появляется сигнал прерывания (переход от высокого к низкому логическому уровню). Флаги необходимо сбросить вручную, записав значение 0.
Регистр Aging Offset предназначен для подстройки частоты тактового генератора. Значение регистра добавляется к частоте генератора во время выполнения внутренней процедуры корректировки, если зафиксировано изменение температуры, а также при запуске преобразования температуры битом CONV. Величина смещения знаковая, то есть положительные значения (1-127) уменьшают частоту, отрицательные (128-255) увеличивают. Для одинакового смещения, изменение частоты будет различным в зависимости от температуры. При температуре +25°C, изменение частоты составит 0,1 ppm/LSB.
Текущее значение температуры хранится в регистрах с адресами 0x11 и 0x12, старший и младший байт соответственно, значение температуры в регистрах периодически обновляется. Установлено левое выравнивание, разрешение составляет 10 бит или 0,25°C/LSB, то есть в старшем байте находится целая часть температуры, а 6, 7-й биты в младшем регистры составляют дробную часть. В старшем байте 7-й бит указывает знак температуры, например, значению 00011011 01 соответствует температура +27,25 °C, значению 11111110 10 температура -2,5 °C.
При чтении регистров счета времени, рекомендуется использовать дополнительный буфер, то есть считывать сразу несколько регистров, а не по отдельности, так как между отдельными операциями чтения, регистры времени могут поменять свое значение. Это правило также рекомендуется соблюдать при записи новых данных в регистры счета. Запись нового значения в регистр секунд, приостанавливает ход часов на 1 секунду, остальные регистры должны быть перезаписаны в течение этого времени.
Подключение DS3231 к микроконтроллеру
Я подключил часы к микроконтроллеру PIC16F628A, для отображения времени использовал цифровое табло из семисегментных индикаторов на драйвере MAX7219. Схема подключения представлена ниже:
После подачи питания на индикаторах высвечиваются знаки тире (– – – – – –), далее выполняется инициализация часов, значение времени появляется на индикаторах с задержкой в 1 секунду, которая требуется для запуска тактового генератора часов. На индикаторы выводится значение часов, минут и секунд, разделенных десятичной точкой, формат времени 24-х часовой. Кнопкой SB1 “Индикация” можно сменить формат отображения, где на индикаторы будет выводиться температура, а также значение часов и минут, разделенных десятичной точкой, которая мигает с частотой 2 Гц. Температура отображается без дробной части, в программе считывается только старший байт хранения температуры по адресу 0x11.
Значение времени считывается из часов по прерыванию на линии SQW/INT, которая управляется сигналом 1-го будильника, в процессе инициализации часов будильник настраивается на ежесекундный сигнал. Светодиод HL1 служит в качестве индикатора и вспыхивает по сигналу прерывания каждую секунду. Светодиод HL2 загорается в случае ошибки передачи данных по интерфейсу I2C.
Дополнительно добавил в программу возможность настройки часов кнопками SB2 “Настройка”, SB3 “Установка”. Вход в режим настройки производится нажатием кнопки SB2, на индикаторах высвечивается 00 часов, и знаки тире вместо минут и секунд (00 – – – –). Кнопкой SB3 задается значение часов (инкремент при каждом нажатии), далее нажатием кнопки SB2 осуществляется переход на редактирование минут, вместо тире высветится 00 минут. Кнопкой SB3 также задается необходимое значение и так далее. После редактирования секунд и нажатия кнопки SB2, время в часах перезаписывается, на индикаторах отображается обновленное время.
Неполный код программы приведен ниже (полную версию можно скачать в конце статьи):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; #include <P16F628A.INC> LIST p=16F628A __CONFIG H'3F10' ;Конфигурация микроконтроллера errorlevel -302 ;не выводить сообщения с ошибкой 302 в листинге Sec equ 0020h ;вспомогательные регистры счета Sec1 equ 0021h ; Sec2 equ 0022h ; scetbit equ 0024h ;вспомогательный регистр счета кол-ва бит perem equ 0025h ;вспомогательный регистр приема/передачи байта по spi, i2c temp equ 0026h ;регистр температуры perem_1 equ 0027h ;вспомогательный регистр двоично-десятичного преобр. result equ 0028h ;вспомогательный регистр двоично-десятичного преобр. dat_ind equ 0029h ;регистр данных для передачи по протоколу spi adr_ind equ 002Ah ;регистр адреса для передачи по протоколу spi second equ 002Bh ;регистр хранения секунд для установки времени minut equ 002Ch ;регистр хранения минут для установки времени hour equ 002Dh ;регистр хранения часов для установки времени adr_i2c equ 002Eh ;регистры подпрограммы передачи данных интерфейса i2c tmp_i2c equ 002Fh slave_adr equ 0030h data_i2c equ 0031h flag equ 007Fh ;регистр флагов #DEFINE int PORTB,0 ;линия прерывания INT/SQW DS3231 #DEFINE sda PORTB,1 ;линия SDA для подключения DS3231 #DEFINE scl PORTB,2 ;линия SCL для подключения DS3231 #DEFINE sda_io TRISB,1 ;направление линии SDA #DEFINE scl_io TRISB,2 ;направление линии SCL #DEFINE datai PORTB,5 ;линия входа данных драйвера MAX7219 #DEFINE cs PORTB,6 ;линия выбора драйвера MAX7219 #DEFINE clk PORTB,7 ;линия тактирования драйвера MAX7219 #DEFINE led PORTB,4 ;светодиод ошибки i2c #DEFINE led_sec PORTB,3 ;светодиод индикации хода часов 1Гц #DEFINE regim PORTA,2 ;кнопка Индикация - смены режима индикации #DEFINE nast PORTA,3 ;кнопка Настройка - входа в режим настройки времени #DEFINE ust PORTA,4 ;кнопка Установка - установка значения часов ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; org 0000h ;начать выполнение программы с адреса 0000h goto Start ;переход на метку Start ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;Основная программа Start movlw b'00000000' ;установка значений выходных защелок порта A movwf PORTA ; movlw b'01000000' ;установка значений выходных защелок порта B movwf PORTB ; movlw b'00000111' ;выключение компараторов movwf CMCON ; bsf STATUS,RP0 ;выбрать 1-й банк movlw b'00000111' ;настройка линий ввода\вывода порта B movwf TRISB ;RB0-RB2 - на вход, остальные на выход movlw b'11111111' ;настройка линий ввода\вывода порта A movwf TRISA ;все линии на вход bcf STATUS,RP0 ;выбрать 0-й банк clrf flag ;сброс регистра флагов call init_lcd ;вызов подпрограммы инициализации драйвера (MAX7219) call viv_not ;вывод на индикаторы символов тире " ------ " ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; movlw b'11010000' ;адрес устройства (DS3231) movwf slave_adr ;Запись 4-х байт в регистры приема/передачи по i2c ;здесь выполняется настройка 1-го будильника, сигнал каждую секунду movlw data_i2c ;установка первого регистра приема/передачи по i2c movwf FSR ; movlw b'10000000' ;данные для регистра секунд 1-го будильника movwf INDF ; incf FSR,F ; movlw b'10000000' ;данные для регистра минут 1-го будильника movwf INDF ; incf FSR,F ; movlw b'10000000' ;данные для регистра часов 1-го будильника movwf INDF ; incf FSR,F ; movlw b'10000000' ;данные для регистра даты/дня недели 1-го будильника movwf INDF ; movlw .4 ;передача 4-х байта по i2c movwf tmp_i2c ; movlw 0x07 ;установка адреса регистра секунд 1-го будильника movwf adr_i2c ; call write_i2c ;вызов подпрограммы записи по интерфейсу i2c call err_prov ;проверка на ошибки записи/чтения I2C movlw .1 ;передача 1-го байта по i2c movwf tmp_i2c ; movlw 0x0E ;установка адреса регистра Control movwf adr_i2c ; movlw data_i2c ;установка первого регистра приема/передачи по i2c movwf FSR ; movlw b'00000101' ;запуск тактового генератора, запрет функционирования вывода INT/SQW для movwf INDF ;режима питания от батареи, частота импульсов на выходе INT/SQW 1Гц, ;выход INT/SQW задействован для генерации прерываний по будильнику, ;разрешение прерываний по 1-му будильнику call write_i2c ;вызов подпрограммы записи по интерфейсу i2c call err_prov ;проверка на ошибки записи/чтения I2C met_2 movlw .1 ;передача 1-го байта по i2c movwf tmp_i2c ; movlw 0x0F ;установка адреса регистра Status movwf adr_i2c ; movlw data_i2c ;установка первого регистра приема/передачи по i2c movwf FSR ; movlw b'00000000' ;сброс бита OSF, запрет генерирования импульсов на выходе EN32kHz, movwf INDF ;сброс флагов прерываний будильников A2F, A1F call write_i2c ;вызов подпрограммы записи по интерфейсу i2c call err_prov ;проверка на ошибки записи/чтения I2C met_1 btfsc int ;опрос линии прерывания будильника goto met_3 ; bsf led_sec ;включение светодиода индикации хода часов goto met_4 ; met_3 bcf led_sec ;выключение светодиода индикации хода часов btfsc nast ;опрос кнопки настройки часов goto met_5 ; call nast_time ;вызов подпрограммы установки времени goto met_2 ; met_5 btfsc regim ;опрос кнопки режима индикации goto met_1 ; met_6 call paus_knp ; btfss regim ; goto met_6 ; btfss flag,2 ;изменение значения флага режима индикации goto met_7 ; bcf flag,2 ;сброс флага индикации, режим отображения часов goto met_1 ; met_7 bsf flag,2 ;установка флага индикации, режим отображения температуры и часов goto met_1 ; met_4 movlw .1 ;передача 1-го байта по i2c movwf tmp_i2c ; movlw 0x11 ;установка адреса старшего регистра температуры movwf adr_i2c ; call read_i2c ;вызов подпрограммы чтения по I2C call err_prov ;проверка на ошибки записи/чтения I2C movf INDF,W ;копирование значения температуры в регистр temp movwf temp rd_time movlw .3 ;передача 3-х байт по i2c movwf tmp_i2c ; movlw 0x00 ;установка адреса регистра секунд movwf adr_i2c ; call read_i2c ;вызов подпрограммы чтения по I2C call err_prov ;проверка на ошибки записи/чтения I2C btfsc flag,2 ;опрос флага режима индикации goto met_8 ; call vivod ;вызов подпрограммы вывода значения часов на цифровое табло goto met_2 ; met_8 call vivod_temp ;вызов подпрограммы вывода температуры и часов на цифровое табло goto met_2 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
Интерфейс передачи данных I2C реализован программно. Инициализация часов состоит из следующих шагов:
- Настройка 1-го будильника на ежесекундный сигнал, то есть запись двоичного числа 10000000 в регистры с адресами 0x07-0x0A, тем самым выполняется установка битов A1M4-A1M
- Настройка регистра Control, где запрещаем функционирование вывода INT/SQW для режима питания от батареи. Выход INT/SQW задействуем для генерации прерываний по будильнику, и разрешаем прерывание по 1-му будильнику.
- Настройка регистра Status, где запрещаем генерирование импульсов на выходе EN32kHz, и сбрасываем флаги прерываний обоих будильников.
Далее опрашиваем линию INT/SQW, если уровень сменился на низкий, то произошло прерывание по сигналу будильника, считываем регистры отсчета времени с адресами 0x00-0x02 (секунды, минуты, час) и выводим на индикаторы. После чего снова сбрасываем флаги прерываний будильников, далее цикл повторяется.
Заключение
В целом часы довольно точные, за несколько дней я заметил, что на компьютере время ушло на несколько секунд, а на часах изменений практически нет, для сравнения использовал точное время из интернета. Таким образом, используя эти часы можно забыть о синхронизации на довольно длительное время. Этот модуль я применил в Солнечном трекере, где значение часов используются для расчета положения Солнца. Также я использовал этот модуль по прямому назначению, в самодельных часах на индикаторах ИВ-11, а также собрал часы на газоразрядных индикаторах.
Модуль часов можно приобрести здесь Модуль часов реального времени DS323.
Добрый день. Как обычно, замечательная статья.
Я правильно понял, что данный чип, как бонус, можно использовать как термометр?
Здравствуйте, как термометр использовать можно, если не требуется высокая точность, по даташиту погрешность может составлять ±3 градуса Цельсия
Здравствуйте.
Подскажите как при индикации температуры отобразить знак градуса,
и устанавливать будильник.
На вашем видео модуль 3231 работает без батарейки, у меня заработал
только с батарейкой, пробовал с 2 модулями.
Здравствуйте, применительно к индикатору на MAX7219 для вывода значка градуса нужно отключить декодирование индикатора на котором будет отображаться значок, далее записать байт в этот индикатор, где необходимо зажечь сегменты A, B, F, G. В этой статье есть ссылка на статью про драйвер и его описание.
В прошивке приведенной в этой статье будильник задействован на ежесекундный сигнал, можете посмотреть. Для установки будильника сначала надо настроить биты A1M4, A1M3, A1M2, A1M1, и одновременно записать значения секунд, минут, часов и т.д в регистры будильника. Установить бит INTCN, для использования выхода INT/SQW в качестве прерывания от будильника, Сбросить флаг прерывания будильника A1F, разрешить прерывания от 1-го будильника установкой бита A1IE. Далее при срабатывании будильника записать новое значение будильника и сбросить флаг прерывания A1F.
Модуль должен работать и без батарейки, проверьте напряжения питания на 2-ом выводе микросхемы DS3231, возможно напряжение ниже порогового значения 2,5В.
Здравствуйте, вопрос наверное не совсем в тему, но все же. Может подскажите возможно ли реализовать саму идею?
Суть в следующем: в большинстве бытовой техники сейчас встроенные часы. Как пример: духовка, микроволновка, печки, холодильник и т.д.. Но случаются ситуации с пропаданием электричества и в этом случае часы приходится выставлять с нуля. На многих устройствах это те еще танцы с бубном. Да и если их более трех в доме, то это тот еще ритуал.
Решить вопрос с бесперебойником, тоже не всегда возможно. Я так понимаю микроволновку к бесперебойнику нельзя подключать, да и печка в случае пропадания электричества в момент работы тут же его усадит в 0. Так что этот вариант отбрасываем.
Остается один более-менее нормальный вариант, это получение сигнала точного времени с интернет сервиса по Wi-Fi (посредством ESP8266). То есть после пропадания электричества и его восстановления устройство коннектится через роутер к инету и устанавливает время.
Правда здесь видио сложность будет в другом. Как правило эти часы многофункциональны (вернее табло). На нем же и может быть в определенный момент и оставшееся время, и истекшее время от начала чего-либо ну и так далее.
Собственно вопрос, это реально модернизировать сохранив прежний функционал?
Здравствуйте, а прежний функционал и не изменится, чтобы его изменить надо влезать в прошивку микроконтроллера который установлен в микроволновке, стиралке. Я так понимаю настройка времени будет производиться через кнопки, ну то есть ESP8266 будет через транзисторы коммутировать кнопки настройки времени. После факта пропадания напряжения, и дальнейшего восстановления, будет производиться вход в меню настройки времени и его обновление. Думаю что это можно реализовать.
А в автомате это как то можно реализовать? Без кнопок? Или я не так понял Вас?
Скажем по событию подачи питания на ту же плату Wi-Fi.
То есть: напряжение есть все работает как положено. Потом оно пропало. Тут все ясно. Нет напряжения – нет действия. Дальше оно появилось. Плата само собой запускается и конектится к роутеру, получает данные и выдает их в бытовое устройство. Тут я так понимаю в любом случае нужна ардуинка.
В автомате можно при появлении напряжения, но новое полученное время из интернета как-то загнать же надо в микроконтроллер микроволновки, а там неизвестно какой контроллер стоит, какая программа у него там, как его прошивать это все неизвестно, самый простой способ это через меню самой микроволновки, то есть симулируя нажатия кнопок микроволновки, дополнительные кнопки не нужны, просто к кнопкам микроволновки подключить транзисторы которые будут управляться от arduino например, или другого контроллера. Я просто не знаю что из себя представляет ESP8266, может ли он выполнять функции микроконтроллера.
А ну собственно я именно это и имел ввиду. Эмуляцию нажатия кнопок. В зависимости от времени нужное количество раз. Еще такой вопрос. Если не кнопки, а колесико? Я думаю это не сильно большая разница? И если кнопки сенсорные? А то у меня как раз весь зоопарк. Только что механических часов нет.
Если колесико, то это энкодер, у которого 2 выхода, там сигналы сдвинуты по фазе относительно друг друга, в этом случае придется эмулировать эти сигналы, что тоже выполнимо, у меня есть статья по энкодеру, можете почитать https://radiolaba.ru/microcotrollers/podklyuchenie-enkodera-k-mikrokontrolleru.html
Насчет сенсорных кнопок, надо смотреть по схеме как это реализовано, если там стоит специализированная микросхема которая подключена к контроллеру микроволновки, то в этом случае врятли можно что-то придумать, а если от каждой сенсорной кнопки есть вход в контроллер, то здесь как и с обычными кнопками.
Привет. Статья отличная, помогла мне освоить новую железку. Я адаптировал вашу программу под PIC16F84A и LCD дисплей 8х2 строки.
Интересно, почему вы использовали сигнал будильника в качестве прерывания для обновления информации на дисплее, а не воспользовались 1 секундным сигналом с выхода SQW?
Ведь тогда можно было бы исключить строчки кода по настройке первого будильника и в итоге уменьшить количество строк в программе.
Привет, рад что вам понравилась статья, да можно воспользоваться и ежесекундным сигналом на SQW, я решил использовать будильник, чтобы в основном показать пример его настройки, читателям это может пригодится.
Привет. У вас в статье написано, что: “Регистр дня недели инкрементируется в полночь, счет идет от 0 до 7”, но если при первоначальном включении и запуске микросхемы в регистрах устанавливается: “При первом включении регистры даты и времени сброшены, и имеют следующие значения 01/01/ 00 — 01 — 00/00/00 (день/месяц/год/ — день недели — час/минуты/секунды).”, то выходит, что счёт дней недели начинается с 1 до 7. Нет ли ошибки?
Вопрос в том, каким является значение дня недели ПОНЕДЕЛЬНИК? Это b’00000000′ или b’00000001′ ? Или это вообще не важно, то есть можно назначить первым днём вторник?
Привет, да там ошибочка, инкремент выполняется от 1 до 7 (статью подправлю), тут без разницы какое число к какому дню привязывать, просто в микроконтроллере надо прописать какое число к какому дню будет относится.
Привет. К часам прикрутил календарь, но вот закавыка с календарём такая, что не записывается установленное значение лет. Установка ДНЯ НЕДЕЛИ, ЧИСЛА МЕСЯЦА, НАЗВАНИЯ МЕСЯЦА и последовательная запись этих 3 байтов в DS3231 происходит корректно, но вот когда пытаюсь передать уже 4 байта подряд , то есть с установленным ГОДОМ, то четвёртый байт со значением ГОДА почемуто не записывается. В листинге программы есть участок, где происходит настройка 1 будильника – это 4 байта, они записываются корректно. Немогу понять, почему с четырьмя регистрами даты тоже самое не прокатывает?
И даже один байт со значением ГОДА пытался записывать в DS3231 по адресу 0х06, один фик не пишется в этот регистр.((
Привет, не записывается это как, в регистре остается неизменное значение после записи? пример кода можете привести
https://yadi.sk/i/uNVqws–3CqsFW
это часть кода настройка ГОДА и запись результата настроек календаря в микросхему часов.
в конце идёт возврат на метку с опросом кнопок управления.
ошибок в коде на первый взгляд не увидел, а что насчет считывания из часов, может там ошибка?
Что касается часов, то там всё без нареканий. Корректно считываются и сохраняются установленные значения.
как время будет, я проверю этот момент
Привет. Плюнул я на PIC16F84A. В неё всё равно вся программа с часами и календарём не влазила (я проверял работу программы по частям), пошёл в магазин и купил PIC16F648A. Вот теперь всё корректно работает.
Привет, отлично, получается не работало из-за нехватки памяти?
Вообще PIC16F84A старый МК, я когда только начинал программировать использовал его, сейчас уже и не помню когда последний раз программировал этот МК. Самый ходовой для небольших проектов это PIC16F628A.
Ну да. Вообщето програмка у меня получилась громоздкой из-за вывода на ЖК дисплей названий дней недели и названий месяцев начальными тремя буквами (хранятся в EEPROM), плюс к этому настройка календаря получилась громоздкой, с учётом количества дней в каждом месяце. https://yadi.sk/i/F7PEWXmI3DhcSV
Привет. Переделал вашу программу под вывод информации на матричные индикаторы 8х8. Для этого потребовалось увеличить частоту кварца до 20МГц. И теперь перестало работать определение наличия устройств на шине I2C, т.е. в подпрограмме предачи байта не происходит установка бита ошибки передачи в регистре Flags,6. Пробовал увеличить переменную “прием подтверждения 100 мкс”, ещё пробовал увеличить время задержки в подпрограмме pausi2c – не помогло. Что ещё нужно доработать в програмке при увеличении частоты кварца?
Приветствую, не совсем понял, после увеличения частоты кварца у вас пропала связь с часами по шине I2C?
Бит flag,6 устанавливается если нет подтверждения от ведомого устройства.
У меня две макетных платы. Первая с кварцем на 4 МГц и ЖК дисплеем и вторая с кварцем на 20 МГц с матричными индикатороми 8х8. Я переставляю модуль RTC часов с одной макетки на другую. На макетке с 4МГц кварцем при отсутствии модуля RTC срабатывает подпрограмма viv_not, а на макетке с кварцем 20Мгц – не срабатывает. Часы работают на той и на другой макетке корректно. На макетке с 20Мгц поставил светодиод для индикации ошибки “отсутствие связи”, но он не загорается при отсутствии модуля RTC и попдпрограмма viv_not конечно же не работает (они зависят от состояния флага Flag, 6). На 4 МГц всё работает, а на 20 МГц – нет.
Для 20 МГц надо увеличить паузу в подпрограмме pausi2c, для корректной работы i2c интерфейса, хотя часы поддерживают высокую скорость передачи данных до 400 кГц, все равно будет не лишним уменьшить скорость до 100 кГц, используйте следующую подпрограмму:
Значения счетчика для приема подтверждения надо увеличить до 100, вместо 20, но это не обязательно.
Если эти правки не помогут, значит в вашем коде есть ошибка, возможно что-то упустили.
Благодарю. Сделал так, но не помогло, видимо где то я ошибся. Буду разбираться.
Привет.
Разобрался с неработой попдпрограммы viv_not. У меня линия SDA, SCL выведена на PORT А, а на этом порте нет подтягивающих резисторов при работе на вход, и если модуль часов отключить (вместе с теми резисторами, что на нём распаяны), то и не робит прога.
Добры день. Отличный разбор китайского модуля часов. Схема и все функции в наличии. От себя хочу добавить, если планируете использовать данный модуль с батарейками 2032, то надо выпаять диод VD1, это цепочка заряда и рассчитана она на использование аккумулятора 2032. Если не убрать диод, батарейка вздуется и выйдет из строя довольно скоро.
Приветствую, да все верно, диод желательно убрать при совместном использовании батарейки и внешнего питания.
Добрый день.Заинтересовался Ардуино. Первые шаги. Модуль, что и на фото выше ZS-042(с DS3231), ардуино UNO и ардуино pro MINI. Заливаю модуль, через UNO. Устанавливаю батарейку CR2032(аккумулятор не нашел). собираю схему с Mini. Схема модуль и mini отрабатывает, пока не отключиться внешний источник. Перебрасываю модуль на UNO, смотрю по COMпорту – время застыло. При подаче внешнего питания продолжает дальше отсчитывать. На просторах интернета, говорят из-за цепи зарядки аккумулятора(убрать и всё), но дело в том что модуль в одном экземпляре и экспериментировать не хочется. Просто у меня подозрение, что это программно. если можно,то попроще объясните пожалуйста.
Здравствуйте, когда вы питаете модуль от батарейки (без внешнего источника питания), то линии SDA, SCL, INT/SQW, 32kHz не подтягиваются к положительному полюсу батарейки, так как на модуле стоит диод VD1, и соответственно передача данных не возможна.
Необходимо подтянуть эти линии через резисторы со стороны Arduino к положительному полюсу источника питания Arduino. Но при этом модуль будет подпитываться через эти резисторы и на линию питания от батарейки переключаться не будет, чтобы этого избежать надо удалить подтягивающие резисторы R1-R4 на модуле часов.
Спасибо. Возникает другой вопрос:получается ПРО МИНИ то же аккумулятор требуется? Извините может я не до конца рассказал. Схема ПРО МИНИ с модулем питаются от внешнего источника и отрабатывает по заданному ритму по часам. При исчезновении напряжения схема перестаёт работать, ничего страшного, но часы должны дальше отсчитывать. При появлении напряжения от внешнего источника схема должна отрабатывать программу на то время, которое модуль часов отсчитал(а у него время застывает). Может я ошибаюсь, для большей убедительности, не подскажите как посмотреть COM порт в реальном времени на ПРО МИНИ без USB переходника(заказал, жду, когда придёт не знаю), на UNO смотрю без проблем.
Время в модуле часов не должно останавливаться при переходе от внешнего источника на батарейку. Вы про какой COM порт говорите? Передача данных с модулем часов идет по шине I2C. Я arduino не программирую, ничего не могу сказать.
Извините что пропал. Всё это время обкатывал схему. Я нашёл ошибку в скетче, это меня и сбило с толку. Исправив ошибку, всё отрабатывает как надо. Отключается и включается в требуемое время по часам, даже если пропадало питание на неопределённый срок. Но казус с переключением DS3231 c MINI на UNO был, часы показывали время пропадания питания. В общем я сделал с самого начала. Перепрошил часики, потом MINI, собрал схему и всё работает. Спасибо за помощь.
DS3231 AT24C32 IIC модуле есть память с какой ячейки она начинается и какой номер ячейки заканчивается. в даташи написано начало 0x57
это по Шестнадцатиричная или Десятичная я не понял
если записывать в них только 8 байт Двоичным кодом сколько ячеек будет доступно для записи и считывания хочу сделать такие часы http://radiokot.ru/forum/viewtopic.php?f=57&t=21235 но поставить DS3231 AT24C32 IIC модуль
Здравствуйте, я не понял какую память вы имеете в виду? AT24C32 это микросхема памяти EEPROM с интерфейсом I2C, имеет объем 4096 байт, ячейки начинаются с нулевого адреса 0x00 и заканчивается 0x0FFF, адрес задается двумя байтами, кроме этого 7-ми битный адрес самой микросхемы равен 1010(A2)(A1)(A0), где A2, A1, A0 соответствующие входы микросхемы, от состояния которых (0 или 1) будет зависеть итоговый 7-ми битный адрес микросхемы. Более подробную информацию можно найти в сети.
если скажем я напишу так
записать в ячейку с номером 0х03 число 00010111
записать в ячейку с номером 0х09 число 00000111
ds1307
будет так число 23 запишется в как 23 часа
число 7 запишется в ОЗУ в 9 ячейку
а я число 23 и 7 куда записал в DS3231 или AT24C32
На шине I2C у каждого устройства есть свой 7-ми битный адрес, у часов DS3231 адрес равен 1101000, у микросхемы памяти EEPROM адрес равен 1010(A2)(A1)(A0), о чем я писал выше. Когда вы передаете данные , то сначала указываете адрес устройства (микросхемы) к которому идет обращение, почитайте более подробно про интерфейс I2C, у меня на сайте также имеется статья об этом Описание интерфейса I2C
Информация о значении времени в ячейках DS3231 хранится в двоично-десятичном формате (в данной статье все написано подробно, почему не читаете?), просто записать число 23 в ячейку часов будет неправильно. Почитайте что такое двоично-десятичный формат данных.
#define TWEN 2
#define TWIE 0
#define TWINT 7
#define TWEA 6
#define TWSTA 5
#define TWSTO 4
#define TWWC 3
rtc_write(9, 0x07);
void twi_start(void) {
TWCR = (1<<TWEA)|(1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
while (!(TWCR & (1<<TWINT))) {; }
}
void twi_stop(void) {
TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO);
}
void twi_write(unsigned char _data)
{
TWDR = _data;
TWCR = (1<<TWINT)|(1<<TWEN);
while (!(TWCR & (1<<TWINT))) {;}
}
unsigned char twi_read(unsigned char _ack) {
unsigned char _data;
if (_ack==1)
{
TWCR = (1<<TWEA)|(1<<TWINT) | (1<<TWEN);
}
else
{
TWCR = (1<<TWINT) | (1<<TWEN);
}
while (!(TWCR & (1<<TWINT)))
{
}
_data = TWDR;
return _data;
}
void rtc_write(unsigned char address, unsigned char data) {
twi_start();
twi_write(0x57);
twi_write(address);
twi_write(data);
twi_stop();
}
записать в ячейку с номером 0х09 число 00000111
теперь запишу в память?
Добрый день! Переменной какого типа можно описать время, которое выдает модуль? Интересует часы и минуты. Можно ли как-то преобразовать время к целочисленному типу?
Добрый день! Применил данный модуль для часов совместно с NODEMCU и матричного индикатора с драйвером MAX7219/. Синхронизация времени с сервером NTP.
clock.setDateTime(epoch);
При вычислении времени Time(epoch) в скетче в Serial выдает нормальное время, а при считывании с модуля dt = clock.getDateTime(); hour = (dt.hour) ;считывает на 1 час больше
например epoch =1548589614=Sun, 27 Jan 2019 11:46:54 GMT при считывании с часов выдаст 12:46 . В чем может быть причина ? Может ли быть в прошивке модуля забито переход на зимнее время например?
Добрый день! Можно-ли применить данный модуль для часов совместно с микросхемой к176ие12 вместо кварца, используя выход модуля 32кГц . Если можно то как это сделать.
а как можно сделать корректировку ошибки? Несколько секунд за несколько дней – это всё-таки слишком много
Корректировка частоты выполняется через регистр подстройки частоты, у этих часов заявленная точность 0,3-0,5 сек в день (может быть и больше), это нормально.
Здравствуйте!
у меня такой вопрос:
Для опроса таймера мы используем изменение логического уровня на ноге INT/SQW таймера.
А почему 1Гц на ножку INT/SQW нужно выводить именно с помощью будильника?
Почему нельзя просто включить ее установкой 0 в бит 2 в контрольном регистре регистре?
Ведь на выходе будет такой же меандр 1Гц.
Извините, уже нашел ответ в комментариях)))
Спасибо за статью. Надеюсь что смогу настроить часы. Я пытаюсь настроить с модулем индикации на tm1637.
Удалось вывести секунды и минуты на индикатор, но все мерцает и я подумал, что опрос чтения времени слишком часто проходит – каждый главный цикл Атмеги. У меня это около 2.8 мс. Попробовал включить прерывания по таймеру чтобы по прерыванию читать DS3231, но тут же получение данных по I2C сломалось. Я так понял что нельзя включать прерывания во время работы I2C.
Теперь попробую построить опрос временных регистров DS3231 по состоянию на ножке 1 Гц.
Вопрос:
А мерцание индикатора может быть действительно вызвано слишком частым опросом DS3231 ?
Приветствую, прерывания не влияют на передачу по протоколу I2C, у вас же контроллер в качестве ведущего работает, он выдает импульсы тактирования (CLK). На время прерываний импульсы не будут генерироваться (возникнет пауза), после прерывания все возобновится. У вас цикл 2,8 мс это 357 Гц, при такой частоте ничего не должно мерцать. Мерцание светодиодных индикаторов заметно при частоте 60Гц и ниже. У вас проблема в чем то другом.
Приветствую!
Смотрю ваши проекты и вижу, что вы досконально разобрались и с DS3231 и с gps модулями.
И возник у меня вопрос, модуль точного времени не такой и точный на самом деле, возможно ли сделать синхронизацию времени модуля от gps?
Этакий автономный модуль из мк, DS3231 и gps, для встраивания в другие конструкции.
Модули точного времени много где применяют, но его точность оставляет желать лучшего (
Получилась бы универсальная конструкция)