В данном уроке мы подключим микросхему времени DS3231 к нашей плате Arduino Nano.
Данный модуль выглядит следующим образом:
Работает данная микросхема по I2C шине.
Подключение данной микросхемы:
Данная микросхема может работать как в режиме чтения так и в режиме записи. Вначале необходимо отправить адрес микросхемы DS3231 — 0x68, после чего бит чтения/записи. Для чтения это логическая единица, для записи логический ноль. Так как мы будем использовать готовую библиотеку, нам надо будет только указать адрес микросхемы и правильную функцию:
Wire.beginTransmission(адрес) — начала работы с устройством которое имеет указанный адрес.
Wire.write(значение) — чтение данных
Wire.read (значение) -запись данных
Так как мы будем считывать сразу массив данных, мы используем команду:
Wire.requestFrom(адрес устройства, количество запрашиваемых байт) — чтение массива данных
Регистр хранения данных:
В данном уроке мы только подключимся к микросхеме DS3231, запишем в нее время и считаем его. Работу с будильником и проверкой температуры микросхемы (которая влияет на точность времени) мы займемся в следующих уроках.
Программный код:
#include «Wire.h»
#define DS3231_I2C_ADDRESS 0x68
// конвертируем обычные десятичные значения в двоично-десятичный код:
byte decToBcd(byte val){
return( (val/10*16) + (val%10) );
}
// конвертируем двоично-десятичный код в обычные десятичные значения:
byte bcdToDec(byte val){
return( (val/16*10) + (val%16) );
}
void setup(){
Wire.begin();
Serial.begin(9600);
// задаем текущее время;
// секунды, минуты, часы, день недели, дата, месяц, год:
// setDS3231time(30,42,16,5,13,10,16);
}
void setDS3231time(byte second, byte minute, byte hour, byte dayOfWeek, byte
dayOfMonth, byte month, byte year){
// передаем данные о времени и дате на DS3231:
Wire.beginTransmission(DS3231_I2C_ADDRESS);
// выставляем регистр указателей DS3231 на регистр «00h»,
// т.е. на регистр, в котором хранятся данные о секундах:
Wire.write(0);
Wire.write(decToBcd(second)); // задаем секунды
Wire.write(decToBcd(minute)); // задаем минуты
Wire.write(decToBcd(hour)); // задаем часы
Wire.write(decToBcd(dayOfWeek));// задаем день недели (1 – это воскресенье, 7 – это суббота)
Wire.write(decToBcd(dayOfMonth)); // задаем дату (от 1 до 31)
Wire.write(decToBcd(month)); // задаем месяц
Wire.write(decToBcd(year)); // задаем год (от 0 до 99)
Wire.endTransmission();
}
void readDS3231time( byte *second,
byte *minute,
byte *hour,
byte *dayOfWeek,
byte *dayOfMonth,
byte *month,
byte *year){
Wire.beginTransmission(DS3231_I2C_ADDRESS);
Wire.write(0); // выставляем регистр указателей DS3231 на регистр «00h»:
Wire.endTransmission();
Wire.requestFrom(DS3231_I2C_ADDRESS, 7); // запрашиваем у DS3231 семь байтов начиная с регистра «00h»:
*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());
}
void displayTime(){
byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
readDS3231time(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year); // извлекаем данные из DS3231:
Serial.print(hour, DEC); // отправляем их на монитор порта:
// при показе конвертируем байтовую переменную в десятичное число:
Serial.print(«:»);
if (minute<10){
Serial.print(«0»);
}
Serial.print(minute, DEC);
Serial.print(«:»);
if (second<10){
Serial.print(«0»);
}
Serial.print(second, DEC);
Serial.print(» «);
Serial.print(dayOfMonth, DEC);
Serial.print(«/»);
Serial.print(month, DEC);
Serial.print(«/»);
Serial.print(year, DEC);
Serial.print(» Day of week: «); // » День недели: «
switch(dayOfWeek){
case 1:
Serial.println(«Sunday»); // «Воскресенье»
break;
case 2:
Serial.println(«Monday»); // «Понедельник»
break;
case 3:
Serial.println(«Tuesday»); // «Вторник»
break;
case 4:
Serial.println(«Wednesday»); // «Среда»
break;
case 5:
Serial.println(«Thursday»); // «Четверг»
break;
case 6:
Serial.println(«Friday»); // «Пятница»
break;
case 7:
Serial.println(«Saturday»); // «Суббота»
break;
}
}
void loop(){
displayTime(); // показываем на мониторе порта текущие данные RTC-модуля
delay(1000); // секундная задержка
}