Объявление

Внимание!
Данный форум предназначен только для радиолюбителей!
Никакие прочие объявления, реклама товаров либо услуг невозможны!


Любой спам на нашем форуме запрещён!
Разрешаются только ссылки по темам! 3а нарушения БАН.


Работа с часами реального времени DS3231

Правила форума
Внимание! Любой спам на нашем форуме запрещён!
Коммерческая реклама сайтов, ссылки, спам запрещены. Так же запрещены ссылки на сайты в профилях новичков.
Бан без предупреждений.

Работа с часами реального времени DS3231

Сообщение admin » 12 дек 2016, 20:57

Микросхема DS3231 является часами реального времени с температурной компенсацией TCXO. Погрешность составляет ±2 минуты за год при температуре окружающей среды от -40°С до +85°С. TCXO дает возможность получать на выходе микросхемы 32кГц во всем температурном диапазоне. Так же микросхема содержит два будильника которые могут генерить прерывания и выводить данное событие на один из выводов микросхемы.

Схема включения микросхемы.
Изображение

Для тех кто не хочет колупаться с пайкой, можно купить готовый модуль в магазине http://data-ru.ru/shopp/.

Давайте разбираться с выводами.

VCC, GND – это питание.
SDA, SCL – это шина I2C
RST – это сброс микросхемы (Reset)
N.C. – это неиспользуемые выводы. Судя по документации нужно прицепить к GND.
Vbat – это батарейка. Если батарейка не используется, та вывод нужно посадить на GND.
32kHz – это вывод с открытым стоком. При использовании требует подтягивающий резистор к питанию. На выходе генерится меандр с частотой 32 кГц. Вывод может быть включен или выключен. Если не используется, то можно его никуда не подключать.
INT/SQW - Пин на котором возможен либо меандр с частотой настроенной в RS1 RS0, либо выход прерывания при совпадении любого из будильников. Настройка производится установкой разряда INTCH в регистре контроля по адресу 0EН. При логическом уровне 0 вывод выдает меандр, при логическом уровне 1 прижимает вывод к нулю при совпадении хронометра и любого из будильников. При использовании этого вывода его необходимо подтянуть к питанию резистором, так как он реализован с открытым стоком и в неактивном состоянии будет висеть в воздухе. Если данный вывод не используется, то его можно никуда не подключать.

С ногами разобрались. Теперь давайте рассмотрим карту памяти.

Изображение

Как видно из таблицы в памяти расположены 19 регистров. Разберем их по очереди.

00Н – регистр содержит текущие секунды. Возможно чтение и запись. Структура данных в регистре следующая. В разрядах BIT0…BIT3 записываются единицы секунд от 0 до 9. В разрядах BIT4…BIT6 записываются десятки секунд от 0 до 6.

01Н – регистр минут содержит текущие минуты. Возможно чтение и запись. Структура данных в регистре следующая. В разрядах BIT0…BIT3 записываются единицы минут от 0 до 9. В разрядах BIT4…BIT6 записываются десятки минут от 0 до 6.

02Н – регистр часов. Возможно чтение и запись. Структура данных в регистре следующая. В разрядах BIT0…BIT3 записываются единицы часов от 0 до 9. В разряде BIT6 расположен вариант вывода часов. Если в этом разряде 0, то вывод будет в 24 часовом формате. При этом разряды BIT4 и BIT5 будут содержать десятки от 0 до 2. Если в разряде BIT6 записан лог 1, то вывод будет осуществляться в 12 часовом режиме. В этом режиме разряд BIT5 будет содержать значения суток, если присутствует лог 0, то это до полудня, а если лог 1, то после полудня. BIT4 выводит десятую часть часов, либо 0, либо 1.

03Н – регистр дня недели. Возможно чтение и запись. Три младших разряда принимают значения от 1 до 7. (с понедельника до воскресения).

04Н – регистр дней. Возможно чтение и запись. чтение и запись. Структура данных в регистре следующая. В разрядах BIT0…BIT3 записываются единицы дней от 0 до 9. В разрядах BIT4…BIT5 записываются десятки дней от 0 до 3.

05Н – регистр месяцев. Структура данных в регистре следующая. В разрядах BIT0…BIT3 записываются единицы месяцев от 0 до 9. В разряде BIT4 записываются десятки месяца, либо 0, либо 1. Также в данном регистре есть разряд Century BIT7. Данный разряд переключается при переполнении регистра годов. То есть данный разряд переключится когда регистр годов перейдет с 99 на 00. (например с 1999 на 2000) Указывает на изменения века.

06Н – регистр годов. Возможно чтение и запись. Структура данных в регистре следующая. В разрядах BIT0…BIT3 записываются единицы годов от 0 до 9. В разрядах BIT4…BIT7 записываются десятки годов от 0 до 9.

07Н – регистр секунд будильника 1. Возможно чтение и запись. Структура данных в регистре следующая. В разрядах BIT0…BIT3 записываются единицы секунд от 0 до 9. В разрядах BIT4…BIT6 записываются десятки секунд от 0 до 6.

08Н – регистр минут будильника 1. Возможно чтение и запись. Структура данных в регистре следующая. В разрядах BIT0…BIT3 записываются единицы минут от 0 до 9. В разрядах BIT4…BIT6 записываются десятки минут от 0 до 6.

09Н – регистр часов будильника 1. Возможно чтение и запись. Структура данных в регистре следующая. В разрядах BIT0…BIT3 записываются единицы часов от 0 до 9. В разряде BIT6 расположен вариант ввода часов. Если в этом разряде 0, то ввод должен быть в 24 часовом формате. При этом разряды BIT4 и BIT5 должны содержать десятки от 0 до 2. Если в разряде BIT6 записан лог 1, то ввод должен осуществляться в 12 часовом режиме. В этом режиме разряд BIT5 должен содержать значения суток, если записать лог 0, то это до полудня, а если лог 1, то после полудня. BIT4 должен содержать десятую часть часов, либо 0, либо 1.

0AН - регистр дней или дней недели будильника 1. Возможно чтение и запись. Структура данных в регистре следующая. В разряды BIT0…BIT3 записываются, либо единицы дней, либо единицы дней недели. Диапазон соответственно, либо от 0 до 9, либо от 1 до 7. В разряды BIT4 и BIT5 записываются только десятки дней от 0 до 3. Разряд BIT6 указывает на вариант данных. Если 0, то записаны дни, а если 1, то дни недели.

0BН – регистр минут будильника 2. Возможно чтение и запись. Структура данных в регистре следующая. В разрядах BIT0…BIT3 записываются единицы минут от 0 до 9. В разрядах BIT4…BIT6 записываются десятки минут от 0 до 6.

0CН – регистр часов будильника 2. Возможно чтение и запись. Структура данных в регистре следующая. В разрядах BIT0…BIT3 записываются единицы часов от 0 до 9. В разряде BIT6 расположен вариант ввода часов. Если в этом разряде 0, то ввод должен быть в 24 часовом формате. При этом разряды BIT4 и BIT5 должны содержать десятки от 0 до 2. Если в разряде BIT6 записан лог 1, то ввод должен осуществляться в 12 часовом режиме. В этом режиме разряд BIT5 должен содержать значения суток, если записать лог 0, то это до полудня, а если лог 1, то после полудня. BIT4 должен содержать десятую часть часов, либо 0, либо 1.

0DН - регистр дней или дней недели будильника 2. Возможно чтение и запись. Структура данных в регистре следующая. В разряды BIT0…BIT3 записываются, либо единицы дней, либо единицы дней недели. Диапазон соответственно, либо от 0 до 9, либо от 1 до 7. В разряды BIT4 и BIT5 записываются только десятки дней от 0 до 3. Разряд BIT6 указывает на вариант данных. Если 0, то записаны дни, а если 1, то дни недели.

0EН – регистр контроля. Возможно чтение и запись.

BIT0 A1IE - Разрешает/запрещает прерывания от будильника 1.
BIT1 A2IE - Разрешает/запрещает прерывания от будильника 2.
BIT2 INTCN - Разрешает/запрещает прерывания на выводе INT/SQW микросхемы.
BIT3, BIT4 RS1, RS2 - Задают частоту меандра выводимого на выводе INT/SQW микросхемы.
BIT5 CONV - Заставляем микросхему начать преобразование температуры. Запись в этот разряд возможно только тогда, когда бит занятости BSY сброшен.
BIT6 BBSQW - Если в этот разряд записать 1, то при работе от батарейки и отсутствующем питании на выводе INT/SQW будут продолжать выходить импульсы. При логическом 0 в данном разряде переведет вывод INT/SQW в высокоимпедансное состояние.
BIT7 EOSC - Разряд управления генератором. Если установлен логический 0, генератор включен. Если работа осуществляется только от батарейки, то логическая 1 отключает генератор. При подаче внешнего питания в этот разряд автоматически записывается логический 0 и генератор включается.

Немного о разрядах BIT7 в будильниках. Данные разряды дают возможность генерить сигнал раз в секунду, минуту, час, день или день недели. Это зависит от того что будет записано в эти разряды. Для наглядности вот таблички для обоих будильников. Я думаю посмотрев на них сразу станет все понятно.

Изображение

Так же вот таблица для задачи выходной частоты на выводе INT/SQW микросхемы.

Изображение

0FН – регистр контроля/статуса. Возможна запись и чтение.

BIT0 A1F - Флаг прерывания при совпадении значения будильника 1 и хронометра. Для сброса флага необходимо записать 0. Флаг принимает на запись только 0, при записи 1 ничего не происходит. Так же если установлен бит INTCN, то будет сгенерировано прерывание на выводе INT/SQW микросхемы.
BIT1 A2F - Флаг прерывания при совпадении значения будильника 2 и хронометра. Для сброса флага необходимо записать 0. Флаг принимает на запись только 0, при записи 1 ничего не происходит. Так же если установлен бит INTCN, то будет сгенерировано прерывание на выводе INT/SQW микросхемы.
BIT2 BSY – Флаг занятости. Взводится при преобразовании температуры. После преобразования сбрасывается и находится в покое в течение 1 минуты.
BIT3 EN32kHz – Бит разрешения вывода меандра с частотой 32кГц на выводе 32kHz микросхемы. При 1 разрешено, при 0 запрещено. По умолчанию при подаче питания установлена 1.
BIT7 OSF – Флаг контроля работы генератора. Логическая 1 указывает, что генератор остановлен. Условия возникновения 1 в этом флаге. 1. При первом включении питания (Тут я могу ошибиться, кто знает пусть поправит)
2. Напряжения на внешнем питание и на батарейке ниже нормы для тактирования схемы.
3. Сброшен бит EOSC при питании микросхемы от батарейки.
4. Внешние факторы влияющие на работу кристалла. Шумы, помехи и т. д.

10Н – Регистр хранит данные для правки частоты работы кристалла.

11Н – Регистр хранит данные температуры измеренной последний раз. (старший байт)

12Н – Регистр хранит данные температуры измеренной последний раз. (младший байт)

Так, с кишками микросхемы разобрались, теперь давайте все это запишем в виде библиотеки. Первая функция которая нам понадобится, будет называться DS_BYTE ds3231_byte(DS_BYTE data); Эта функция получает байт в десятиричном формате, а после преобразования возвращает в удобочитаемом виде для часов.

Код: выделить все
DS_BYTE ds3231_byte(DS_BYTE data)
{
   DS_BYTE temp = 0;
   
   while(data > 9)
      {
         data -= 10;
         temp++;
      }
   
   return (data | (temp << 4));
}


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

Код: выделить все
void ds3231_write_time(DS_BYTE hour, DS_BYTE min, DS_BYTE sec)
{   
   i2c_start();
   i2c_send_byte(0xD0);
   i2c_send_byte(0x00);
   i2c_send_byte(ds3231_byte(sec));
   i2c_send_byte(ds3231_byte(min));
   i2c_send_byte(ds3231_byte(hour));
   i2c_stop();
   
}


Как видно из названия переменных передаваемых функции, мы будем записывать время в виде часы, минуты и секунды. Сразу оговорюсь, я живу в России и у нас время имеет 24 часовой формат. Поэтому данная функция записывает время в этом формате. И так, как она работает. Сначала мы выдаем условие старта на шину. (Кто не в курсе откуда взялась эта функция, идут сюда и читают.) Затем передаем адрес микросхемы, за ним адрес первого регистра со временем, а у нас это секунды. За ним по очереди закидываем значения времени, предварительно преобразовав данные в часовой вид. После выдаем условие стопа и отпускаем шину.
Следующая функция будет записывать дату в память часов.

Код: выделить все
void ds3231_write_date(DS_BYTE year, DS_BYTE month, DS_BYTE date, DS_BYTE day)
{
   i2c_start();
   i2c_send_byte(0xD0);
   i2c_send_byte(0x03);
   i2c_send_byte(ds3231_byte(day));
   i2c_send_byte(ds3231_byte(date));
   i2c_send_byte(ds3231_byte(month));
   i2c_send_byte(ds3231_byte(year));
   i2c_stop();
}


Эта функция мало чем отличается от предыдущей, поэтому я надеюсь на вашу сообразительность и понимание как она работает)). А теперь самое интересное, читаем из микросхемы.
Функция чтения времени.

Код: выделить все
void ds3231_read_time(DS_BYTE *str)
{
   DS_BYTE temp[3];
   int i = 0;
   
   i2c_start();
   i2c_send_byte(0xD0);
   i2c_send_byte(0x00);
   i2c_restart();
   i2c_send_byte(0xD1);
   temp[0] = i2c_read_byte(ACK);
   temp[1] = i2c_read_byte(ACK);
   temp[2] = i2c_read_byte(NACK);
   i2c_stop();
   
   while(i < 3)
      {
         *str = ((temp[i] & 0x0F)+((temp[i] >> 4) * 10));
         str++;
         i++;
      }
}


Что здесь происходит. Сначала как всегда условие старта, затем передаем адрес микросхемы и адрес первого регистра. Затем даем повстарт и снова адрес микросхемы с одним но. Меняем последний бит записи на чтение. Это видно как адрес с 0xD0 поменялся на 0xD1. Затем в массив записываем три параметра, сначала секунды, затем минуты и в конце часы. Такой порядок выбран из-за адресации памяти часов. Если кто не понимает, смотрите карту памяти, таблица выше. Да, вот еще, обратите внимание на то, что первые два байта читаются, а в ответ посылается ACK, а в последнем NACK. Это говорит о том, что пока мы читаем, то отсылаем ACK, а когда мы читаем последний байт и больше читать не будем, то шлем NACK и кидаем условие стоп. Все, данные прочитаны. Теперь нам надо их как-то вернуть. Функция возвращает только одно переменные, а вот массивы возвращать не может. Как быть? Да очень просто. Создаем массив нужной длинны и передаем функции указатель на адрес первой ячейки. А так как мы знаем длину массива, то просто сдвигаемся по ячейкам увеличивая адрес на единицу, не забывая по этим адресам записывать данные. Вот этим и занимается цикл. Сначала мы по первому адресу записываем значение первой ячейки массива с секундами предварительно обнулив старшие четыре бита. Таким образом мы записали единицы, а потом прибавляем десятки. Для этого сдвигаем байт вправо на четыре бита. Таким образом мы получим десятки и умножаем их на десять. Вот и все. После вызова данной функции у нас в массиве окажутся значения времени.
Следующая функция чтения даты.

Код: выделить все
void ds3231_read_date(DS_BYTE *str)
{
   DS_BYTE temp[4];
   int i = 1;
   
   i2c_start();
   i2c_send_byte(0xD0);
   i2c_send_byte(0x03);
   i2c_restart();
   i2c_send_byte(0xD1);
   *str = i2c_read_byte(ACK);
   temp[1] = i2c_read_byte(ACK);
   temp[2] = i2c_read_byte(ACK);
   temp[3] = i2c_read_byte(NACK);
   i2c_stop();
   
   str++;
   while(i < 3)
   {
      *str = ((temp[i] & 0x0F)+(((temp[i] >> 4) & 0x07) * 10));
      str++;
      i++;
   }   
   *str = ((temp[3] & 0x0F)+((temp[3] >> 4) * 10));
}


Тут немного по замороченее с преобразованием. Первым байтом идет день недели, а так как он может принимать значение от 1 до 7, то его можно сразу записать в массив. Далее как и с временем, пишем год, месяц, число. В связи с тем что наше устройство врятли доживет до 2099 года, нам не нужен седьмой бит Century. Для этого чтобы он не мешался, мы накладываем маску 0x07 и обнуляем 7 бит. Все бы хорошо, но год все таки возможно дойдет до значения 99. А вдруг доживет до 99 года)) И наложение такой маски не приемлемо. Поэтому мы преобразования числа и месяца делаем в цикле, а год уже преобразуем отдельно. И последняя функция на сегодня, это чтение температуры. Микросхема, то с температурной компенсацией, значит имеет температуру. Расположена она в двух регистрах, но для наглядности я буду дергать только из первого, без десятых и не буду проверять на минус. Все таки часы висят чаще в помещении. Если все таки приспичит полный диапазон температур, то вычислять их можно по той же схеме что я описывал в статье по работе с датчиком DS18B20. Алгоритм такой же.

Код: выделить все
DS_BYTE ds3231_read_temp(void)
{
   DS_BYTE MSB = 0;
   
   i2c_start();
   i2c_send_byte(0xD0);
   i2c_send_byte(0x11);
   i2c_restart();
   i2c_send_byte(0xD1);
   MSB = i2c_read_byte(NACK);
   i2c_stop();
   
   return MSB;
}


Вот и все пока.
admin
Администратор
 
Сообщений: 63
Зарегистрирован: 27 ноя 2016, 18:21
ТегиРабота с часами реального времени DS3231

Вернуться в Для новичков. Азы.

Кто сейчас на форуме

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 2

/