Модуль часов реального времени DS3231 (ZS-042)

Модуль часов реального времени на микросхеме DS3231,




Особенности модуля ZS-042:

  • Часы реального времени с температурной компенсацией хода, календарь до 2100 года, учетом високосного года.
  • 32 байта внешней EEPROM памяти.
  • Держатель для Li-Ion аккумулятора LIR2032 с возможностью зарядки. Модуль не поддреживает батареи типа CR2032 без доработки.
  • Интерфейс: I2C
  • Напряжение питания: 2,3 В — 5,5 В.
  • Габариты: 40 х 22 мм.

DS3231:

В основе модуля лежит микросхема RTC (Real Time Clock) DS3231 от Maxim. Это полноценные часы и календарь до 2100 года. Точность хода ±2ppm при температуре 0°C — +40°C. Часы могут работать в 24 или 12 часовом формате с отображением AM/PM. Также в наличи два будильника и датчик температуры.

EEPROM 24C32:

На модуле установлена микросхема EEPROM 24C32 объемом 32 байт, ее можно быть использован по своему усмотрению, например для сохранения настроек. 24C32 использует I2C интерфейс.

I2C адрес EEPROM можно изменить с помощью трех перемычек на плате, A0, A1 и A2.

тут картинка

Согласно спецификации, это 3 бита в конце 7-битного адреса

A0, A1 и A2 подтянуты к питанию, а значит адрес с не запаянными перемычками, 0b1010111 или 0x57.

Аккумулятор или батарея?

LIR2032 на модуле служит в качестве резервного источника питания для часов. Проще, чтобы часы не сбрасывались при отключении питания. Если посмотреть на схему модуля (она ниже) увидим схему зарядки аккумулятора, если диод (D2) с резистором (R5) можно так называть, т.е. при внешнем питании, через эту цепочку подается напряжение заряда на аккумулятор.

В случаи использования не перезаряжаемой батареии CR2032 от этой цепочки желательно избавится.


Распиновка модуля:

  • 32K — Выход с открытым стоком (требует подтягивающего резистора) на выходе генерируется миандр с частотой 32КГц.
  • SQW — На самом деле называется INT/SQW. Программируемый выход с открытым стоком, обычно служит как выход прерывания для микроконтроллера, назначение зависит от конфигурации в одном из регистров DS3231, можно дернуть ногой по срабатыванию будильника, на выходе можно генерировать миандр с частотой 1Гц, 4кГц, 8kHz или 32кГц.
  • SCL и SDA — Выходы интерфейса I2C, уже подтянутые к питанию резисторами на 4,7К
  • VCC и GND — Питание 2,3 В — 5,5 В и масса.

Принципиальная схема модуля:


Подключение к Arduino


Код из видео:

#include <Wire.h>
#include <OLED_I2C.h>

OLED  myOLED(SDA, SCL, 8);

extern uint8_t SmallFont[];
extern uint8_t MediumNumbers[];
extern uint8_t BigNumbers[];
 
   
 ///// часы ..
byte decToBcd(byte val){
  return ( (val/10*16) + (val%10) );
}

byte bcdToDec(byte val){
  return ( (val/16*10) + (val%16) );
}

void setDateDs1307(byte second,        // 0-59
                   byte minute,        // 0-59
                   byte hour,          // 1-23
                   byte dayOfWeek,     // 1-7
                   byte dayOfMonth,    // 1-28/29/30/31
                   byte month,         // 1-12
                   byte year)          // 0-99
{
   Wire.beginTransmission(0x68);
   Wire.write(0);
   Wire.write(decToBcd(second));    
   Wire.write(decToBcd(minute));
   Wire.write(decToBcd(hour));     
   Wire.write(decToBcd(dayOfWeek));
   Wire.write(decToBcd(dayOfMonth));
   Wire.write(decToBcd(month));
   Wire.write(decToBcd(year));
   Wire.endTransmission();
}

void getDateDs1307(byte *second,
          byte *minute,
          byte *hour,
          byte *dayOfWeek,
          byte *dayOfMonth,
          byte *month,
          byte *year)
{

  Wire.beginTransmission(0x68);
  Wire.write(0);
  Wire.endTransmission();

  Wire.requestFrom(0x68, 7);

  *second     = bcdToDec(Wire.read() & 0x7f);
  *minute     = bcdToDec(Wire.read());
  *hour       = bcdToDec(Wire.read() & 0x3f); 
  *dayOfWeek  = bcdToDec(Wire.read());
  *dayOfMonth = bcdToDec(Wire.read());
  *month      = bcdToDec(Wire.read());
  *year       = bcdToDec(Wire.read());
}
  
///// температура ..
float get3231Temp(){
  byte tMSB, tLSB; 
  float temp3231;

  Wire.beginTransmission(0x68);
  Wire.write(0x11);
  Wire.endTransmission();
  Wire.requestFrom(0x68, 2);

  if(Wire.available()) {
    tMSB = Wire.read(); //2's complement int portion
    tLSB = Wire.read(); //fraction portion

    temp3231 = (tMSB & B01111111); //do 2's math on Tmsb
    temp3231 += ( (tLSB >> 6) * 0.25 ); //only care about bits 7 & 8
  }
  else {
    //oh noes, no data!
  }

  return temp3231;
}


void setup()
{
  Serial.begin(9600);
  myOLED.begin();
  Wire.begin();
 

 /*  // установка часов
  byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
  second = 30;
  minute = 0;
  hour = 14;
  dayOfWeek = 3; // день недели
  dayOfMonth = 1; // день
  month = 4;
  year = 14;

  setDateDs1307(second, minute, hour, dayOfWeek, dayOfMonth, month, year);
 */
}

void loop(){
  byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
  char week[8][10] = {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"};
 
  getDateDs1307(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);
  
  char time[10];
  char data[11];
  
  snprintf(time, sizeof(time),"%02d:%02d:%02d",           
           hour, minute, second);
           
  snprintf(data, sizeof(data), "%02d/%02d/%02d",            
            dayOfMonth, month, year);
  
  myOLED.setFont(SmallFont);
 
  myOLED.print(time, LEFT, 0);
  myOLED.print(data, LEFT, 15);
  myOLED.printNumF(get3231Temp(), 2, LEFT, 30);
  myOLED.print("C", 32, 30);
  myOLED.update();

 delay(1000);
}

////// конец