Объявление

США начнут предпринимать меры экономического и военного характера, если Россия не прекратит нарушать Договор о ракетах средней и меньшей дальности (ДРСМД)

Решение главы Национального Объединения "Новая Россия - Великая Россия" Rommstaina: http://russianew.ru/viewtopic.php?f=120&t=4039

Работа с часами реального времени 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
Администратор
 
Сообщений: 77
Зарегистрирован: 27 ноя 2016, 18:21
ТегиРабота с часами реального времени DS3231

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

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

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

cron
/