{"id":1326,"date":"2022-11-13T05:36:07","date_gmt":"2022-11-13T05:36:07","guid":{"rendered":"https:\/\/blog.embeddedexpert.io\/?p=1326"},"modified":"2022-11-13T05:36:11","modified_gmt":"2022-11-13T05:36:11","slug":"working-with-stm32-and-ds3231-rtc-set-and-get-the-time-and-date","status":"publish","type":"post","link":"https:\/\/blog.embeddedexpert.io\/?p=1326","title":{"rendered":"Working with STM32 and DS3231 RTC: Set and Get the Time and Date"},"content":{"rendered":"\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"798\" height=\"800\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/11\/DS3231-Precise-Real-Time-Clock-Module-I2C-RTC-AT24C32-2.webp\" alt=\"\" class=\"wp-image-1327\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/11\/DS3231-Precise-Real-Time-Clock-Module-I2C-RTC-AT24C32-2.webp 798w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/11\/DS3231-Precise-Real-Time-Clock-Module-I2C-RTC-AT24C32-2-300x300.webp 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/11\/DS3231-Precise-Real-Time-Clock-Module-I2C-RTC-AT24C32-2-150x150.webp 150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/11\/DS3231-Precise-Real-Time-Clock-Module-I2C-RTC-AT24C32-2-768x770.webp 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/11\/DS3231-Precise-Real-Time-Clock-Module-I2C-RTC-AT24C32-2-750x752.webp 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/11\/DS3231-Precise-Real-Time-Clock-Module-I2C-RTC-AT24C32-2-400x400.webp 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/11\/DS3231-Precise-Real-Time-Clock-Module-I2C-RTC-AT24C32-2-250x250.webp 250w\" sizes=\"(max-width: 798px) 100vw, 798px\" \/><\/figure>\n\n\n\n<p>In this guide, we shall use STM32 to develop a driver to set and get the time store in the DS3231. <\/p>\n\n\n\n<p>In this guide, we shall cover the following:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>DS3231 Module.<\/li><li>Connection with STM32F411 Nucleo-64.<\/li><li>Developing the header file.<\/li><li>Developing the source file.<\/li><li>Code.<\/li><li>Results.<\/li><\/ul>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">1. DS3231 Module<\/h2>\n\n\n\n<p><\/p>\n\n\n\n<p>The DS3231 is a low-cost, extremely accurate I 2 C real-time clock (RTC) with an integrated temperature compensated crystal oscillator (TCXO) and crystal. The device incorporates a battery input, and maintains accurate timekeeping when main power to the device is interrupted. The integration of the crystal resonator enhances the long-term accuracy of the device as well as reduces the piece-part count in a manufacturing line.<\/p>\n\n\n\n<p>The RTC maintains seconds, minutes, hours, day, date, month, and year information. The date at the end of the month is automatically adjusted for months with fewer than 31 days, including corrections for leap year. The clock operates in either the 24-hour or 12-hour format with an AM\/PM indicator. Two programmable time-of-day alarms and a programmable square-wave output are provided. Address and data are transferred serially through an I 2 C bidirectional bus.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"450\" height=\"313\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/10\/DS3231-Real-Time-Clock-Specifications.jpg\" alt=\"\" class=\"wp-image-506\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/10\/DS3231-Real-Time-Clock-Specifications.jpg 450w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/10\/DS3231-Real-Time-Clock-Specifications-300x209.jpg 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/10\/DS3231-Real-Time-Clock-Specifications-400x278.jpg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/10\/DS3231-Real-Time-Clock-Specifications-250x174.jpg 250w\" sizes=\"(max-width: 450px) 100vw, 450px\" \/><\/figure><\/div>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"300\" height=\"300\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/10\/pctdetail.772-290.1-300x300.jpg\" alt=\"\" class=\"wp-image-505\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/10\/pctdetail.772-290.1-300x300.jpg 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/10\/pctdetail.772-290.1-150x150.jpg 150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/10\/pctdetail.772-290.1-768x768.jpg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/10\/pctdetail.772-290.1-750x750.jpg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/10\/pctdetail.772-290.1-400x400.jpg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/10\/pctdetail.772-290.1-250x250.jpg 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/10\/pctdetail.772-290.1.jpg 1000w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><figcaption>DS3231<\/figcaption><\/figure><\/div>\n\n\n\n<p>The module can work on either 3.3 or 5 V which makes it suitable for many development platforms or microcontrollers. The battery input is 3V and a typical CR2032 3V battery can power the module and maintain the information for more than a year.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">2. Connection with STM32F411 Nucleo-64:<\/h2>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"715\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/10\/Screen-Shot-2021-10-19-at-8.03.15-AM-1024x715.png\" alt=\"\" class=\"wp-image-510\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/10\/Screen-Shot-2021-10-19-at-8.03.15-AM-1024x715.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/10\/Screen-Shot-2021-10-19-at-8.03.15-AM-300x209.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/10\/Screen-Shot-2021-10-19-at-8.03.15-AM-768x536.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/10\/Screen-Shot-2021-10-19-at-8.03.15-AM-1536x1072.png 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/10\/Screen-Shot-2021-10-19-at-8.03.15-AM-2048x1430.png 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/10\/Screen-Shot-2021-10-19-at-8.03.15-AM-1150x803.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/10\/Screen-Shot-2021-10-19-at-8.03.15-AM-750x524.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/10\/Screen-Shot-2021-10-19-at-8.03.15-AM-400x279.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2021\/10\/Screen-Shot-2021-10-19-at-8.03.15-AM-250x175.png 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure><\/div>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">3. Developing the header file:<\/h2>\n\n\n\n<p><\/p>\n\n\n\n<p>Before starting the driver development, I2C multiread and multiwrite is needed in order to get the DS3231 to work.<\/p>\n\n\n\n<p>You can get those two functions from here:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Multibyte read (<a rel=\"noreferrer noopener\" href=\"https:\/\/blog.embeddedexpert.io\/?p=549\" data-type=\"URL\" data-id=\"https:\/\/blog.embeddedexpert.io\/?p=549\" target=\"_blank\">here<\/a>).<\/li><li>Multibyte write (<a rel=\"noreferrer noopener\" href=\"https:\/\/blog.embeddedexpert.io\/?p=576\" data-type=\"URL\" data-id=\"https:\/\/blog.embeddedexpert.io\/?p=576\" target=\"_blank\">here<\/a>).<\/li><\/ul>\n\n\n\n<p>We start off by creating new header file with name of ds3231.h.<\/p>\n\n\n\n<p>Within the header file, we shall declare a structure as following :<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">\n\ntypedef struct ts {\n    uint8_t sec;         \/* seconds *\/\n    uint8_t min;         \/* minutes *\/\n    uint8_t hour;        \/* hours *\/\n    uint8_t mday;        \/* day of the month *\/\n    uint8_t mon;         \/* month *\/\n    int16_t year;        \/* year *\/\n    uint8_t wday;        \/* day of the week *\/\n    uint8_t yday;        \/* day in the year *\/\n    uint8_t isdst;       \/* daylight saving time *\/\n    uint8_t year_s;      \/* year in short notation*\/\n\n}ts;<\/pre><\/div>\n\n\n\n<p>The structure will hold the following:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Seconds.<\/li><li>Minutes.<\/li><li>Hours.<\/li><li>Day of the month.<\/li><li>Month.<\/li><li>Year.<\/li><li>Other data needed for the calculation.<\/li><\/ul>\n\n\n\n<p><\/p>\n\n\n\n<p>Also, declare the following three functions:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">void DS3231_set(ts t);\nvoid DS3231_get(ts *t);\nvoid print_time(ts *t);<\/pre><\/div>\n\n\n\n<p>First one is to set the time and data and take the structure as argument.<\/p>\n\n\n\n<p>Second one is to read the time from DS3231 and takes a pointer to the structure.<\/p>\n\n\n\n<p>Third function which will print the time.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>Hence, the entire header file as following:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">\n#ifndef DS3231_H_\n#define DS3231_H_\n\n#include &quot;stdint.h&quot;\n\n\ntypedef struct ts {\n    uint8_t sec;         \/* seconds *\/\n    uint8_t min;         \/* minutes *\/\n    uint8_t hour;        \/* hours *\/\n    uint8_t mday;        \/* day of the month *\/\n    uint8_t mon;         \/* month *\/\n    int16_t year;        \/* year *\/\n    uint8_t wday;        \/* day of the week *\/\n    uint8_t yday;        \/* day in the year *\/\n    uint8_t isdst;       \/* daylight saving time *\/\n    uint8_t year_s;      \/* year in short notation*\/\n\n}ts;\n\n\nvoid DS3231_set(ts t);\nvoid DS3231_get(ts *t);\nvoid print_time(ts *t);\n\n\n#endif \/* DS3231_H_ *\/<\/pre><\/div>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">4. Developing the source code.<\/h2>\n\n\n\n<p>Create a new source code with name of ds3231.c. <\/p>\n\n\n\n<p>Within this declare the following macro:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">#define DS3231_I2C_ADDR             0x68\n\n\n\/\/ time keeping registers\n#define DS3231_TIME_CAL_ADDR        0x00\n#define DS3231_ALARM1_ADDR          0x07\n#define DS3231_ALARM2_ADDR          0x0B\n#define DS3231_CONTROL_ADDR         0x0E\n#define DS3231_STATUS_ADDR          0x0F\n#define DS3231_AGING_OFFSET_ADDR    0x10\n#define DS3231_TEMPERATURE_ADDR     0x11\n\n\/\/ control register bits\n#define DS3231_CONTROL_A1IE     \t0x1\t\t\/* Alarm 2 Interrupt Enable *\/\n#define DS3231_CONTROL_A2IE     \t0x2\t\t\/* Alarm 2 Interrupt Enable *\/\n#define DS3231_CONTROL_INTCN    \t0x4\t\t\/* Interrupt Control *\/\n#define DS3231_CONTROL_RS1\t    \t0x8\t\t\/* square-wave rate select 2 *\/\n#define DS3231_CONTROL_RS2    \t\t0x10\t\/* square-wave rate select 2 *\/\n#define DS3231_CONTROL_CONV    \t\t0x20\t\/* Convert Temperature *\/\n#define DS3231_CONTROL_BBSQW    \t0x40\t\/* Battery-Backed Square-Wave Enable *\/\n#define DS3231_CONTROL_EOSC\t    \t0x80\t\/* not Enable Oscillator, 0 equal on *\/\n\n\n\/\/ status register bits\n#define DS3231_STATUS_A1F      \t\t0x01\t\t\/* Alarm 1 Flag *\/\n#define DS3231_STATUS_A2F      \t\t0x02\t\t\/* Alarm 2 Flag *\/\n#define DS3231_STATUS_BUSY     \t\t0x04\t\t\/* device is busy executing TCXO *\/\n#define DS3231_STATUS_EN32KHZ  \t\t0x08\t\t\/* Enable 32KHz Output  *\/\n#define DS3231_STATUS_OSF      \t\t0x80\t\t\/* Oscillator Stop Flag *\/<\/pre><\/div>\n\n\n\n<p>Also, two functions:<\/p>\n\n\n\n<p>First one that converts the dec to BCD:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">static uint8_t dectobcd(const uint8_t val)\n{\n    return ((val \/ 10 * 16) + (val % 10));\n}<\/pre><\/div>\n\n\n\n<p>The second one is to convert BCD to dec:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">static uint8_t bcdtodec(const uint8_t val)\n{\n    return ((val \/ 16 * 10) + (val % 16));\n}\n<\/pre><\/div>\n\n\n\n<p>In order to set the time and date:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">void DS3231_set(ts t)\n{\n    uint8_t i, century;\n    century = 0x80;\n    t.year_s = t.year - 2000;\n    uint8_t TimeDate[7] = { t.sec, t.min, t.hour, t.wday, t.mday, t.mon, t.year_s };\n\n    for (i=0;i&lt;=6;i++)\n    \t{\n    \tTimeDate[i] = dectobcd(TimeDate[i]);\n    \tif(i == 5){TimeDate[5] |= century;}\n    \t}\n\n    i2c_WriteMulti(DS3231_I2C_ADDR,DS3231_TIME_CAL_ADDR,(char*)TimeDate,7);\n}\n<\/pre><\/div>\n\n\n\n<p>Since we are already beyond 2000, hence we shall set the century bit to 1:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"725\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/11\/Screenshot-2022-11-13-at-8.22.29-AM-1024x725.png\" alt=\"\" class=\"wp-image-1328\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/11\/Screenshot-2022-11-13-at-8.22.29-AM-1024x725.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/11\/Screenshot-2022-11-13-at-8.22.29-AM-300x212.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/11\/Screenshot-2022-11-13-at-8.22.29-AM-768x544.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/11\/Screenshot-2022-11-13-at-8.22.29-AM-1536x1088.png 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/11\/Screenshot-2022-11-13-at-8.22.29-AM-2048x1450.png 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/11\/Screenshot-2022-11-13-at-8.22.29-AM-1150x814.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/11\/Screenshot-2022-11-13-at-8.22.29-AM-750x531.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/11\/Screenshot-2022-11-13-at-8.22.29-AM-400x283.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/11\/Screenshot-2022-11-13-at-8.22.29-AM-250x177.png 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>and subtract 2000 from the given year.<\/p>\n\n\n\n<p>Then convert the variables to BCD and send the variables to DS3231 in order to set the time and date.<\/p>\n\n\n\n<p>In order to get the time:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">void DS3231_get(ts *t)\n{\n\tuint8_t TimeDate[7];        \/\/second,minute,hour,dow,day,month,year\n\tuint8_t i;\n\tuint16_t year_full;\n\n\ti2c_ReadMulti(DS3231_I2C_ADDR,DS3231_TIME_CAL_ADDR,7,(char*)TimeDate);\n\n\tfor (i = 0; i &lt;= 6; i++) {\n\t\tif (i == 5) {\n\t\t\tTimeDate[5] = bcdtodec(TimeDate[i] &amp; 0x1F);\n\n\t\t} else\n\t\t\tTimeDate[i] = bcdtodec(TimeDate[i]);\n\t}\n\n\n\tyear_full = 2000 + TimeDate[6];\n\n\tt-&gt;sec = TimeDate[0];\n\tt-&gt;min = TimeDate[1];\n\tt-&gt;hour = TimeDate[2];\n\tt-&gt;mday = TimeDate[4];\n\tt-&gt;mon = TimeDate[5];\n\tt-&gt;year = year_full;\n\tt-&gt;wday = TimeDate[3];\n\tt-&gt;year_s = TimeDate[6];\n\n}<\/pre><\/div>\n\n\n\n<p>For getting the time, it is similar to setting the time but using BCD to dec and adding 2000 to the year.<\/p>\n\n\n\n<p>To print the time:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">void print_time(ts *t)\n{\n\tprintf(&quot;Current DS3231 Time: %d:%d:%d\\r\\n&quot;,t-&gt;hour,t-&gt;min,t-&gt;sec);\n\tprintf(&quot;Current DS3231 Date: %d\/%d\/%d\\r\\n&quot;,t-&gt;year,t-&gt;mon,t-&gt;mday);\n\n}<\/pre><\/div>\n\n\n\n<p><\/p>\n\n\n\n<p>Hence, the source code as following:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">\n\n#include &quot;ds3231.h&quot;\n#include &quot;i2c.h&quot;\n\n\n#define DS3231_I2C_ADDR             0x68\n\n\n\/\/ time keeping registers\n#define DS3231_TIME_CAL_ADDR        0x00\n#define DS3231_ALARM1_ADDR          0x07\n#define DS3231_ALARM2_ADDR          0x0B\n#define DS3231_CONTROL_ADDR         0x0E\n#define DS3231_STATUS_ADDR          0x0F\n#define DS3231_AGING_OFFSET_ADDR    0x10\n#define DS3231_TEMPERATURE_ADDR     0x11\n\n\/\/ control register bits\n#define DS3231_CONTROL_A1IE     \t0x1\t\t\/* Alarm 2 Interrupt Enable *\/\n#define DS3231_CONTROL_A2IE     \t0x2\t\t\/* Alarm 2 Interrupt Enable *\/\n#define DS3231_CONTROL_INTCN    \t0x4\t\t\/* Interrupt Control *\/\n#define DS3231_CONTROL_RS1\t    \t0x8\t\t\/* square-wave rate select 2 *\/\n#define DS3231_CONTROL_RS2    \t\t0x10\t\/* square-wave rate select 2 *\/\n#define DS3231_CONTROL_CONV    \t\t0x20\t\/* Convert Temperature *\/\n#define DS3231_CONTROL_BBSQW    \t0x40\t\/* Battery-Backed Square-Wave Enable *\/\n#define DS3231_CONTROL_EOSC\t    \t0x80\t\/* not Enable Oscillator, 0 equal on *\/\n\n\n\/\/ status register bits\n#define DS3231_STATUS_A1F      \t\t0x01\t\t\/* Alarm 1 Flag *\/\n#define DS3231_STATUS_A2F      \t\t0x02\t\t\/* Alarm 2 Flag *\/\n#define DS3231_STATUS_BUSY     \t\t0x04\t\t\/* device is busy executing TCXO *\/\n#define DS3231_STATUS_EN32KHZ  \t\t0x08\t\t\/* Enable 32KHz Output  *\/\n#define DS3231_STATUS_OSF      \t\t0x80\t\t\/* Oscillator Stop Flag *\/\n\n\nstatic uint8_t dectobcd(const uint8_t val)\n{\n    return ((val \/ 10 * 16) + (val % 10));\n}\n\nstatic uint8_t bcdtodec(const uint8_t val)\n{\n    return ((val \/ 16 * 10) + (val % 16));\n}\n\n\nvoid DS3231_set(ts t)\n{\n    uint8_t i, century;\n    century = 0x80;\n    t.year_s = t.year - 2000;\n    uint8_t TimeDate[7] = { t.sec, t.min, t.hour, t.wday, t.mday, t.mon, t.year_s };\n\n    for (i=0;i&lt;=6;i++)\n    \t{\n    \tTimeDate[i] = dectobcd(TimeDate[i]);\n    \tif(i == 5){TimeDate[5] |= century;}\n    \t}\n\n    i2c_WriteMulti(DS3231_I2C_ADDR,DS3231_TIME_CAL_ADDR,(char*)TimeDate,7);\n}\n\nvoid DS3231_get(ts *t)\n{\n\tuint8_t TimeDate[7];        \/\/second,minute,hour,dow,day,month,year\n\tuint8_t i;\n\tuint16_t year_full;\n\n\ti2c_ReadMulti(DS3231_I2C_ADDR,DS3231_TIME_CAL_ADDR,7,(char*)TimeDate);\n\n\tfor (i = 0; i &lt;= 6; i++) {\n\t\tif (i == 5) {\n\t\t\tTimeDate[5] = bcdtodec(TimeDate[i] &amp; 0x1F);\n\n\t\t} else\n\t\t\tTimeDate[i] = bcdtodec(TimeDate[i]);\n\t}\n\n\n\tyear_full = 2000 + TimeDate[6];\n\n\tt-&gt;sec = TimeDate[0];\n\tt-&gt;min = TimeDate[1];\n\tt-&gt;hour = TimeDate[2];\n\tt-&gt;mday = TimeDate[4];\n\tt-&gt;mon = TimeDate[5];\n\tt-&gt;year = year_full;\n\tt-&gt;wday = TimeDate[3];\n\tt-&gt;year_s = TimeDate[6];\n\n}\n\nvoid print_time(ts *t)\n{\n\tprintf(&quot;Current DS3231 Time: %d:%d:%d\\r\\n&quot;,t-&gt;hour,t-&gt;min,t-&gt;sec);\n\tprintf(&quot;Current DS3231 Date: %d\/%d\/%d\\r\\n&quot;,t-&gt;year,t-&gt;mon,t-&gt;mday);\n\n}\n<\/pre><\/div>\n\n\n\n<p>Within main.c file:<\/p>\n\n\n\n<p>include the header file as following:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">#include &quot;ds3231.h&quot;<\/pre><\/div>\n\n\n\n<p>Declare the sturcture:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">ts ds3231_data;<\/pre><\/div>\n\n\n\n<p><\/p>\n\n\n\n<p>Then set the time and date within the structure:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">\tds3231_data.sec=0;\n\tds3231_data.min=55;\n\tds3231_data.hour=7;\n\tds3231_data.mday=7;\n\tds3231_data.mon=11;\n\tds3231_data.year=2022;<\/pre><\/div>\n\n\n\n<p>Call DS3231_set function:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">DS3231_set(ds3231_data);<\/pre><\/div>\n\n\n\n<p>In while 1 loop  :<\/p>\n\n\n\n<p>call get time function, then call print time function and wait for a half of second:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">\t\t\tDS3231_get(&amp;ds3231_data);\n\t\t\tprint_time(&amp;ds3231_data);\n\t\t\tdelay(500);<\/pre><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">5. Code:<\/h2>\n\n\n\n<p>You many download the code from here:<\/p>\n\n\n\n<div class=\"wp-block-file\"><a href=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/11\/DS3231.zip\">DS3231<\/a><a href=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/11\/DS3231.zip\" class=\"wp-block-file__button\" download>Download<\/a><\/div>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">6. Results:<\/h2>\n\n\n\n<p>After compile and load the code to STM32F411 and open serial terminal application,  you should get something similar to what you set:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"706\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/11\/Screenshot-2022-11-13-at-8.29.08-AM-1024x706.png\" alt=\"\" class=\"wp-image-1330\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/11\/Screenshot-2022-11-13-at-8.29.08-AM-1024x706.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/11\/Screenshot-2022-11-13-at-8.29.08-AM-300x207.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/11\/Screenshot-2022-11-13-at-8.29.08-AM-768x529.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/11\/Screenshot-2022-11-13-at-8.29.08-AM-1150x793.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/11\/Screenshot-2022-11-13-at-8.29.08-AM-750x517.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/11\/Screenshot-2022-11-13-at-8.29.08-AM-400x276.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/11\/Screenshot-2022-11-13-at-8.29.08-AM-250x172.png 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2022\/11\/Screenshot-2022-11-13-at-8.29.08-AM.png 1172w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Happy coding \ud83d\ude42<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this guide, we shall use STM32 to develop a driver to set and get the time store in the DS3231. In this guide, we shall cover the following: DS3231 Module. Connection with STM32F411 Nucleo-64. Developing the header file. Developing the source file. Code. Results. 1. DS3231 Module The DS3231 is a low-cost, extremely accurate [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3,2,11,12],"tags":[],"class_list":["post-1326","post","type-post","status-publish","format-standard","hentry","category-data-structures","category-embedded-systems","category-peripheral-drivers","category-stm32"],"_links":{"self":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/1326"}],"collection":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1326"}],"version-history":[{"count":1,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/1326\/revisions"}],"predecessor-version":[{"id":1331,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/1326\/revisions\/1331"}],"wp:attachment":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1326"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1326"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1326"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}