DS3231.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557
  1. /*
  2. DS3231.cpp - Arduino/chipKit library support for the DS3231 I2C Real-Time Clock
  3. Copyright (C)2015 Rinky-Dink Electronics, Henning Karlsen. All right reserved
  4. This library has been made to easily interface and use the DS3231 RTC with
  5. an Arduino or chipKit.
  6. You can find the latest version of the library at
  7. http://www.RinkyDinkElectronics.com/
  8. This library is free software; you can redistribute it and/or
  9. modify it under the terms of the CC BY-NC-SA 3.0 license.
  10. Please see the included documents for further information.
  11. Commercial use of this library requires you to buy a license that
  12. will allow commercial use. This includes using the library,
  13. modified or not, as a tool to sell products.
  14. The license applies to all part of the library including the
  15. examples and tools supplied with the library.
  16. */
  17. #include "DS3231.h"
  18. // Include hardware-specific functions for the correct MCU
  19. #if defined(__AVR__)
  20. #include "hardware/avr/HW_AVR.h"
  21. #elif defined(__PIC32MX__)
  22. #include "hardware/pic32/HW_PIC32.h"
  23. #elif defined(__arm__)
  24. #include "hardware/arm/HW_ARM.h"
  25. #endif
  26. #define REG_SEC 0x00
  27. #define REG_MIN 0x01
  28. #define REG_HOUR 0x02
  29. #define REG_DOW 0x03
  30. #define REG_DATE 0x04
  31. #define REG_MON 0x05
  32. #define REG_YEAR 0x06
  33. #define REG_ALARM1_SEC 0x07
  34. #define REG_ALARM1_MIN 0x08
  35. #define REG_ALARM1_HOUR 0x09
  36. #define REG_ALARM1_DATE 0x0a
  37. #define REG_ALARM2_MIN 0x0b
  38. #define REG_ALARM2_HOUR 0x0c
  39. #define REG_ALARM2_DATE 0x0d
  40. #define REG_CON 0x0e
  41. #define REG_STATUS 0x0f
  42. #define REG_AGING 0x10
  43. #define REG_TEMPM 0x11
  44. #define REG_TEMPL 0x12
  45. #define SEC_1970_TO_2000 946684800
  46. static const uint8_t dim[] = { 31,28,31,30,31,30,31,31,30,31,30,31 };
  47. /* Public */
  48. Time::Time()
  49. {
  50. this->year = 2014;
  51. this->mon = 1;
  52. this->date = 1;
  53. this->hour = 0;
  54. this->min = 0;
  55. this->sec = 0;
  56. this->dow = 3;
  57. }
  58. DS3231::DS3231(uint8_t data_pin, uint8_t sclk_pin)
  59. {
  60. _sda_pin = data_pin;
  61. _scl_pin = sclk_pin;
  62. }
  63. Time DS3231::getTime()
  64. {
  65. Time t;
  66. _burstRead();
  67. t.sec = _decode(_burstArray[0]);
  68. t.min = _decode(_burstArray[1]);
  69. t.hour = _decodeH(_burstArray[2]);
  70. t.dow = _burstArray[3];
  71. t.date = _decode(_burstArray[4]);
  72. t.mon = _decode(_burstArray[5]);
  73. t.year = _decodeY(_burstArray[6])+2000;
  74. return t;
  75. }
  76. void DS3231::setTime(uint8_t hour, uint8_t min, uint8_t sec)
  77. {
  78. if (((hour>=0) && (hour<24)) && ((min>=0) && (min<60)) && ((sec>=0) && (sec<60)))
  79. {
  80. _writeRegister(REG_HOUR, _encode(hour));
  81. _writeRegister(REG_MIN, _encode(min));
  82. _writeRegister(REG_SEC, _encode(sec));
  83. }
  84. }
  85. void DS3231::setDate(uint8_t date, uint8_t mon, uint16_t year)
  86. {
  87. if (((date>0) && (date<=31)) && ((mon>0) && (mon<=12)) && ((year>=2000) && (year<3000)))
  88. {
  89. year -= 2000;
  90. _writeRegister(REG_YEAR, _encode(year));
  91. _writeRegister(REG_MON, _encode(mon));
  92. _writeRegister(REG_DATE, _encode(date));
  93. }
  94. }
  95. void DS3231::setDOW()
  96. {
  97. int dow;
  98. byte mArr[12] = {6,2,2,5,0,3,5,1,4,6,2,4};
  99. Time _t = getTime();
  100. dow = (_t.year % 100);
  101. dow = dow*1.25;
  102. dow += _t.date;
  103. dow += mArr[_t.mon-1];
  104. if (((_t.year % 4)==0) && (_t.mon<3))
  105. dow -= 1;
  106. while (dow>7)
  107. dow -= 7;
  108. _writeRegister(REG_DOW, dow);
  109. }
  110. void DS3231::setDOW(uint8_t dow)
  111. {
  112. if ((dow>0) && (dow<8))
  113. _writeRegister(REG_DOW, dow);
  114. }
  115. char *DS3231::getTimeStr(uint8_t format)
  116. {
  117. static char output[] = "xxxxxxxx";
  118. Time t;
  119. t=getTime();
  120. if (t.hour<10)
  121. output[0]=48;
  122. else
  123. output[0]=char((t.hour / 10)+48);
  124. output[1]=char((t.hour % 10)+48);
  125. output[2]=58;
  126. if (t.min<10)
  127. output[3]=48;
  128. else
  129. output[3]=char((t.min / 10)+48);
  130. output[4]=char((t.min % 10)+48);
  131. output[5]=58;
  132. if (format==FORMAT_SHORT)
  133. output[5]=0;
  134. else
  135. {
  136. if (t.sec<10)
  137. output[6]=48;
  138. else
  139. output[6]=char((t.sec / 10)+48);
  140. output[7]=char((t.sec % 10)+48);
  141. output[8]=0;
  142. }
  143. return (char*)&output;
  144. }
  145. char *DS3231::getDateStr(uint8_t slformat, uint8_t eformat, char divider)
  146. {
  147. static char output[] = "xxxxxxxxxx";
  148. int yr, offset;
  149. Time t;
  150. t=getTime();
  151. switch (eformat)
  152. {
  153. case FORMAT_LITTLEENDIAN:
  154. if (t.date<10)
  155. output[0]=48;
  156. else
  157. output[0]=char((t.date / 10)+48);
  158. output[1]=char((t.date % 10)+48);
  159. output[2]=divider;
  160. if (t.mon<10)
  161. output[3]=48;
  162. else
  163. output[3]=char((t.mon / 10)+48);
  164. output[4]=char((t.mon % 10)+48);
  165. output[5]=divider;
  166. if (slformat==FORMAT_SHORT)
  167. {
  168. yr=t.year-2000;
  169. if (yr<10)
  170. output[6]=48;
  171. else
  172. output[6]=char((yr / 10)+48);
  173. output[7]=char((yr % 10)+48);
  174. output[8]=0;
  175. }
  176. else
  177. {
  178. yr=t.year;
  179. output[6]=char((yr / 1000)+48);
  180. output[7]=char(((yr % 1000) / 100)+48);
  181. output[8]=char(((yr % 100) / 10)+48);
  182. output[9]=char((yr % 10)+48);
  183. output[10]=0;
  184. }
  185. break;
  186. case FORMAT_BIGENDIAN:
  187. if (slformat==FORMAT_SHORT)
  188. offset=0;
  189. else
  190. offset=2;
  191. if (slformat==FORMAT_SHORT)
  192. {
  193. yr=t.year-2000;
  194. if (yr<10)
  195. output[0]=48;
  196. else
  197. output[0]=char((yr / 10)+48);
  198. output[1]=char((yr % 10)+48);
  199. output[2]=divider;
  200. }
  201. else
  202. {
  203. yr=t.year;
  204. output[0]=char((yr / 1000)+48);
  205. output[1]=char(((yr % 1000) / 100)+48);
  206. output[2]=char(((yr % 100) / 10)+48);
  207. output[3]=char((yr % 10)+48);
  208. output[4]=divider;
  209. }
  210. if (t.mon<10)
  211. output[3+offset]=48;
  212. else
  213. output[3+offset]=char((t.mon / 10)+48);
  214. output[4+offset]=char((t.mon % 10)+48);
  215. output[5+offset]=divider;
  216. if (t.date<10)
  217. output[6+offset]=48;
  218. else
  219. output[6+offset]=char((t.date / 10)+48);
  220. output[7+offset]=char((t.date % 10)+48);
  221. output[8+offset]=0;
  222. break;
  223. case FORMAT_MIDDLEENDIAN:
  224. if (t.mon<10)
  225. output[0]=48;
  226. else
  227. output[0]=char((t.mon / 10)+48);
  228. output[1]=char((t.mon % 10)+48);
  229. output[2]=divider;
  230. if (t.date<10)
  231. output[3]=48;
  232. else
  233. output[3]=char((t.date / 10)+48);
  234. output[4]=char((t.date % 10)+48);
  235. output[5]=divider;
  236. if (slformat==FORMAT_SHORT)
  237. {
  238. yr=t.year-2000;
  239. if (yr<10)
  240. output[6]=48;
  241. else
  242. output[6]=char((yr / 10)+48);
  243. output[7]=char((yr % 10)+48);
  244. output[8]=0;
  245. }
  246. else
  247. {
  248. yr=t.year;
  249. output[6]=char((yr / 1000)+48);
  250. output[7]=char(((yr % 1000) / 100)+48);
  251. output[8]=char(((yr % 100) / 10)+48);
  252. output[9]=char((yr % 10)+48);
  253. output[10]=0;
  254. }
  255. break;
  256. }
  257. return (char*)&output;
  258. }
  259. char *DS3231::getDOWStr(uint8_t format)
  260. {
  261. char *output = "xxxxxxxxxx";
  262. char *daysLong[] = {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"};
  263. char *daysShort[] = {"Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"};
  264. Time t;
  265. t=getTime();
  266. if (format == FORMAT_SHORT)
  267. output = daysShort[t.dow-1];
  268. else
  269. output = daysLong[t.dow-1];
  270. return output;
  271. }
  272. char *DS3231::getMonthStr(uint8_t format)
  273. {
  274. char *output= "xxxxxxxxx";
  275. char *monthLong[] = {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"};
  276. char *monthShort[] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
  277. Time t;
  278. t=getTime();
  279. if (format == FORMAT_SHORT)
  280. output = monthShort[t.mon-1];
  281. else
  282. output = monthLong[t.mon-1];
  283. return output;
  284. }
  285. long DS3231::getUnixTime(Time t)
  286. {
  287. uint16_t dc;
  288. dc = t.date;
  289. for (uint8_t i = 0; i<(t.mon-1); i++)
  290. dc += dim[i];
  291. if ((t.mon > 2) && (((t.year-2000) % 4) == 0))
  292. ++dc;
  293. dc = dc + (365 * (t.year-2000)) + (((t.year-2000) + 3) / 4) - 1;
  294. return ((((((dc * 24L) + t.hour) * 60) + t.min) * 60) + t.sec) + SEC_1970_TO_2000;
  295. }
  296. void DS3231::enable32KHz(bool enable)
  297. {
  298. uint8_t _reg = _readRegister(REG_STATUS);
  299. _reg &= ~(1 << 3);
  300. _reg |= (enable << 3);
  301. _writeRegister(REG_STATUS, _reg);
  302. }
  303. void DS3231::setOutput(byte enable)
  304. {
  305. uint8_t _reg = _readRegister(REG_CON);
  306. _reg &= ~(1 << 2);
  307. _reg |= (enable << 2);
  308. _writeRegister(REG_CON, _reg);
  309. }
  310. void DS3231::setSQWRate(int rate)
  311. {
  312. uint8_t _reg = _readRegister(REG_CON);
  313. _reg &= ~(3 << 3);
  314. _reg |= (rate << 3);
  315. _writeRegister(REG_CON, _reg);
  316. }
  317. float DS3231::getTemp()
  318. {
  319. uint8_t _msb = _readRegister(REG_TEMPM);
  320. uint8_t _lsb = _readRegister(REG_TEMPL);
  321. return (float)_msb + ((_lsb >> 6) * 0.25f);
  322. }
  323. /* Private */
  324. void DS3231::_sendStart(byte addr)
  325. {
  326. pinMode(_sda_pin, OUTPUT);
  327. digitalWrite(_sda_pin, HIGH);
  328. digitalWrite(_scl_pin, HIGH);
  329. digitalWrite(_sda_pin, LOW);
  330. digitalWrite(_scl_pin, LOW);
  331. shiftOut(_sda_pin, _scl_pin, MSBFIRST, addr);
  332. }
  333. void DS3231::_sendStop()
  334. {
  335. pinMode(_sda_pin, OUTPUT);
  336. digitalWrite(_sda_pin, LOW);
  337. digitalWrite(_scl_pin, HIGH);
  338. digitalWrite(_sda_pin, HIGH);
  339. pinMode(_sda_pin, INPUT);
  340. }
  341. void DS3231::_sendNack()
  342. {
  343. pinMode(_sda_pin, OUTPUT);
  344. digitalWrite(_scl_pin, LOW);
  345. digitalWrite(_sda_pin, HIGH);
  346. digitalWrite(_scl_pin, HIGH);
  347. digitalWrite(_scl_pin, LOW);
  348. pinMode(_sda_pin, INPUT);
  349. }
  350. void DS3231::_sendAck()
  351. {
  352. pinMode(_sda_pin, OUTPUT);
  353. digitalWrite(_scl_pin, LOW);
  354. digitalWrite(_sda_pin, LOW);
  355. digitalWrite(_scl_pin, HIGH);
  356. digitalWrite(_scl_pin, LOW);
  357. pinMode(_sda_pin, INPUT);
  358. }
  359. void DS3231::_waitForAck()
  360. {
  361. pinMode(_sda_pin, INPUT);
  362. digitalWrite(_scl_pin, HIGH);
  363. while (digitalRead(_sda_pin)==HIGH) {}
  364. digitalWrite(_scl_pin, LOW);
  365. }
  366. uint8_t DS3231::_readByte()
  367. {
  368. pinMode(_sda_pin, INPUT);
  369. uint8_t value = 0;
  370. uint8_t currentBit = 0;
  371. for (int i = 0; i < 8; ++i)
  372. {
  373. digitalWrite(_scl_pin, HIGH);
  374. currentBit = digitalRead(_sda_pin);
  375. value |= (currentBit << 7-i);
  376. delayMicroseconds(1);
  377. digitalWrite(_scl_pin, LOW);
  378. }
  379. return value;
  380. }
  381. void DS3231::_writeByte(uint8_t value)
  382. {
  383. pinMode(_sda_pin, OUTPUT);
  384. shiftOut(_sda_pin, _scl_pin, MSBFIRST, value);
  385. }
  386. uint8_t DS3231::_decode(uint8_t value)
  387. {
  388. uint8_t decoded = value & 127;
  389. decoded = (decoded & 15) + 10 * ((decoded & (15 << 4)) >> 4);
  390. return decoded;
  391. }
  392. uint8_t DS3231::_decodeH(uint8_t value)
  393. {
  394. if (value & 128)
  395. value = (value & 15) + (12 * ((value & 32) >> 5));
  396. else
  397. value = (value & 15) + (10 * ((value & 48) >> 4));
  398. return value;
  399. }
  400. uint8_t DS3231::_decodeY(uint8_t value)
  401. {
  402. uint8_t decoded = (value & 15) + 10 * ((value & (15 << 4)) >> 4);
  403. return decoded;
  404. }
  405. uint8_t DS3231::_encode(uint8_t value)
  406. {
  407. uint8_t encoded = ((value / 10) << 4) + (value % 10);
  408. return encoded;
  409. }
  410. void DS3231::setAlarm1Time(uint8_t hour, uint8_t min)
  411. {
  412. if (((hour>=0) && (hour<24)) && ((min>=0) && (min<60)))
  413. {
  414. min = _encode(min);
  415. hour = _encode(hour);
  416. uint8_t sec = 0x00;
  417. min = min &~ (1<<7);
  418. hour = hour &~ (1<<7);
  419. hour = hour &~ (1<<6);
  420. uint8_t date = 0x81;
  421. _writeRegister(REG_ALARM1_SEC, sec);
  422. _writeRegister(REG_ALARM1_MIN, min);
  423. _writeRegister(REG_ALARM1_HOUR, hour);
  424. _writeRegister(REG_ALARM1_DATE, date);
  425. }
  426. }
  427. char *DS3231::getAlarm1Str(uint8_t format)
  428. {
  429. static char output[] = "xx:xx:xx-xxxxxx";
  430. uint8_t sec = _readRegister(REG_ALARM1_SEC);
  431. uint8_t min = _readRegister(REG_ALARM1_MIN);
  432. uint8_t hour = _readRegister(REG_ALARM1_HOUR);
  433. uint8_t date = _readRegister(REG_ALARM1_DATE);
  434. // Formatage des bits de controle
  435. if((sec&(1<<7)) == 0)
  436. output[14] = 48;
  437. else
  438. output[14] = 49;
  439. if((min&(1<<7)) == 0)
  440. output[13] = 48;
  441. else
  442. output[13] = 49;
  443. if((hour&(1<<7)) == 0)
  444. output[12] = 48;
  445. else
  446. output[12] = 49;
  447. if((hour&(1<<6)) == 0)
  448. output[10] = 50;
  449. else
  450. output[10] = 49;
  451. if((date&(1<<7)) == 0)
  452. output[11] = 48;
  453. else
  454. output[11] = 49;
  455. if((date&(1<<6)) == 0)
  456. output[9] = 77;
  457. else
  458. output[9] = 87;
  459. //Fin formatage des bits de controle
  460. sec = _decode(sec);
  461. min = _decode(min);
  462. hour = _decode(hour);
  463. if (hour<10)
  464. output[0]=48; // "0" en ASCII
  465. else
  466. output[0]=char((hour / 10)+48);
  467. output[1]=char((hour % 10)+48);
  468. if (min<10)
  469. output[3]=48; // "0" en ASCII
  470. else
  471. output[3]=char((min / 10)+48);
  472. output[4]=char((min % 10)+48);
  473. output[6]=char((sec / 10)+48);
  474. output[7]=char((sec % 10)+48);
  475. output[16]=0;
  476. return (char*)&output;
  477. }
  478. void DS3231::setControl()
  479. {
  480. _writeRegister(REG_CON, 0x07);
  481. // Serial.print("set de la conf");
  482. }
  483. void DS3231::resetAlarm()
  484. {
  485. _writeRegister(REG_STATUS, 0x00);
  486. // Serial.print("reset de l'alarme");
  487. }