{"id":4269,"date":"2020-02-19T20:00:20","date_gmt":"2020-02-19T19:00:20","guid":{"rendered":"https:\/\/msalamon.pl\/?p=4269"},"modified":"2025-12-27T17:35:26","modified_gmt":"2025-12-27T16:35:26","slug":"what-is-this-date-in-the-stm32f1-rct","status":"publish","type":"post","link":"https:\/\/msalamon.pl\/en\/what-is-this-date-in-the-stm32f1-rct\/","title":{"rendered":"What is this date in the STM32F1 RCT?"},"content":{"rendered":"\n<p>In the previous post I started a mini-series dedicated to the built-in RTC in STM32 chips. I began with probably the most popular microcontroller <a href=\"https:\/\/sklep.msalamon.pl\/produkt\/stm32f103c8t6-dev-board-2\/?utm_source=blog&amp;utm_medium=article&amp;utm_campaign=rtcf1&amp;utm_content=Text\">SMT32F103<\/a> found among others in the cheap <a href=\"https:\/\/sklep.msalamon.pl\/produkt\/stm32f103c8t6-dev-board-2\/?utm_source=blog&amp;utm_medium=article&amp;utm_campaign=rtcf1&amp;utm_content=Text\">BluePill<\/a> board. I got to the point where after resetting the microcontroller the time was still correct, but the date started from zero.<\/p>\n\n\n\n<!--more-->\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><a href=\"https:\/\/sklep.msalamon.pl\/produkt\/stm32f103c8t6-dev-board-2\/?utm_source=blog&amp;utm_medium=banner&amp;utm_campaign=rtcf1&amp;utm_content=bluepill\"><img loading=\"lazy\" decoding=\"async\" width=\"1200\" height=\"400\" src=\"http:\/\/msalamon.pl\/wp-content\/uploads\/2018\/09\/BluePill_baner.jpg\" alt=\"\" class=\"wp-image-953\" srcset=\"https:\/\/msalamon.pl\/wp-content\/uploads\/2018\/09\/BluePill_baner.jpg 1200w, https:\/\/msalamon.pl\/wp-content\/uploads\/2018\/09\/BluePill_baner-300x100.jpg 300w, https:\/\/msalamon.pl\/wp-content\/uploads\/2018\/09\/BluePill_baner-1024x341.jpg 1024w, https:\/\/msalamon.pl\/wp-content\/uploads\/2018\/09\/BluePill_baner-768x256.jpg 768w, https:\/\/msalamon.pl\/wp-content\/uploads\/2018\/09\/BluePill_baner-24x8.jpg 24w, https:\/\/msalamon.pl\/wp-content\/uploads\/2018\/09\/BluePill_baner-36x12.jpg 36w, https:\/\/msalamon.pl\/wp-content\/uploads\/2018\/09\/BluePill_baner-160x53.jpg 160w\" sizes=\"auto, (max-width: 1200px) 100vw, 1200px\" \/><\/a><\/figure>\n<\/div>\n\n\n<p><\/p>\n\n\n\n<h1 class=\"wp-block-heading\">Why is the date being reset?<\/h1>\n\n\n\n<p>Alright, I\u2019m only resetting the MCU, so the RTC counter keeps running. So why does the time match after reset, but the date does not?<\/p>\n\n\n\n<p>It comes from the way ST uses the built-in RTC counter. Let me remind you that it\u2019s used in such a way that when a day rolls over, the counter is reset. It simply does not hold a complete date like it does in Linux.<\/p>\n\n\n\n<p>That\u2019s why the time is preserved after reset. The date is stored in an ordinary variable in RAM, which is reset when the microcontroller starts. And that is the cause of the \u201cproblem\u201d. How do we fight it?<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Let\u2019s finally use the Backup Registers!<\/h2>\n\n\n\n<p>I\u2019ve mentioned backup registers a few times already. Let me remind you that these are a dozen\/several dozen battery-backed registers. Additionally, clearing these registers requires a special procedure, which is not included in a normal MCU reset.<\/p>\n\n\n\n<p>Writing to these registers also requires unlocking. In HAL, this lock is removed by default. This is done in the <em>HAL_RTC_MspInit<\/em> function<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">HAL_PWR_EnableBkUpAccess();\n<\/pre>\n\n\n\n<p>Since the lock is removed, we can write to these registers. It\u2019s very simple. Just use the HAL function from the extended RTC function set.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">void HAL_RTCEx_BKUPWrite(RTC_HandleTypeDef *hrtc, uint32_t BackupRegister, uint32_t Data);<\/pre>\n\n\n\n<p>You pass the RTC handle, the backup register number, and the data. Unfortunately, the argument is misleading, because it points to a 32-bit variable that you can put into the register. <strong>BKP holds ONLY 16 bits.<\/strong><\/p>\n\n\n\n<p>By the way, these ubiquitous 32-bit arguments are a plague of HAL, which opponents use to start flame wars on electronics forums. I partly agree with them, but come on\u2014it doesn\u2019t completely eliminate HAL \ud83d\ude42<\/p>\n\n\n\n<p>Ok, so how do you write the current date into these registers? Since they fit 2 bytes each, and each date variable fits in one byte, two backup registers are enough to store the complete date. I made this simple function in main.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">void BackupDateToBR(void)\n{\n    HAL_RTCEx_BKUPWrite(&amp;amp;hrtc, RTC_BKP_DR2, ((RtcDate.Date &amp;lt;&amp;lt; 8) | (RtcDate.Month)));\n    HAL_RTCEx_BKUPWrite(&amp;amp;hrtc, RTC_BKP_DR3, ((RtcDate.Year &amp;lt;&amp;lt; 8) | (RtcDate.WeekDay)));\n}<\/pre>\n\n\n\n<p>I write day and month to BKP_DR2, and year and weekday to BKP_DR3. Weekday is not mandatory \u2013 it is always recalculated in ST\u2019s library.<\/p>\n\n\n\n<p>When should you back up the date? There\u2019s no point doing it every second. Only when the date changes.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">if(RtcDate.Date != CompareDate)\n{\n    BackupDateToBR();\n    CompareDate = RtcDate.Date;\n}<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Restoring the date at startup<\/h2>\n\n\n\n<p>Now it\u2019s enough to read this data at startup and set it using the function we already know, <em>HAL_RTC_SetDate<\/em>. Let\u2019s try it!<\/p>\n\n\n\n<p>In the \/* USER CODE BEGIN Check_RTC_BKUP *\/ section in the RTC initialization\u2014where last time I inserted a return so as not to set the clock with the data entered in Cube\u2014I\u2019ll add some code. I\u2019ll read the saved date from the BKP regs and set the calendar.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/* USER CODE BEGIN Check_RTC_BKUP *\/\nRtcDate.Date = (HAL_RTCEx_BKUPRead(&amp;amp;hrtc, RTC_BKP_DR2) &amp;gt;&amp;gt; 8);\nRtcDate.Month = HAL_RTCEx_BKUPRead(&amp;amp;hrtc, RTC_BKP_DR2);\nRtcDate.Year = (HAL_RTCEx_BKUPRead(&amp;amp;hrtc, RTC_BKP_DR3) &amp;gt;&amp;gt; 8);\nRtcDate.WeekDay = HAL_RTCEx_BKUPRead(&amp;amp;hrtc, RTC_BKP_DR3);\n\nHAL_RTC_SetDate(&amp;amp;hrtc, &amp;amp;RtcDate, RTC_FORMAT_BIN);\n\n\/\/\n\/\/  You have to do not let Init code to reinitialize Time and Date in RTC.\n\/\/  It's \"a bug\" in HAL widely described and complain on forums.\n\/\/  That causes every MCU restart the time and date will be same as you configured in CubeMX.\n\/\/  All you have to do is just return before init time\/date in this user section.\n\/\/\n  return;\n\/* USER CODE END Check_RTC_BKUP *\/<\/pre>\n\n\n\n<p>This code will cause the date to be remembered after a microcontroller reset. Success! \u2026until\u2026<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Date rollover vs. backup<\/h2>\n\n\n\n<p>What happens if, during battery backup power, the date rolls over? By one, two, or 20 days? Before we move on to battery backup power, let\u2019s test this by simulating such a situation in the debugger. How? By changing the values in the RTC counter, simulating a date rollover \u201cin the absence\u201d of the core.<\/p>\n\n\n\n<p>To change the register, start debugging and pause code execution. Now in the upper-right corner you have several sections. Go into <strong>SFRs<\/strong>. These are Special Function Registers, i.e., simplified, you can say these are peripheral registers. Expand the tree for RTC.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><a href=\"http:\/\/msalamon.pl\/wp-content\/uploads\/2020\/02\/rtcf1_SFRs.jpg\"><img loading=\"lazy\" decoding=\"async\" width=\"283\" height=\"300\" src=\"http:\/\/msalamon.pl\/wp-content\/uploads\/2020\/02\/rtcf1_SFRs-283x300.jpg\" alt=\"\" class=\"wp-image-1402\" srcset=\"https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/02\/rtcf1_SFRs-283x300.jpg 283w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/02\/rtcf1_SFRs-24x24.jpg 24w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/02\/rtcf1_SFRs-34x36.jpg 34w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/02\/rtcf1_SFRs-75x80.jpg 75w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/02\/rtcf1_SFRs.jpg 652w\" sizes=\"auto, (max-width: 283px) 100vw, 283px\" \/><\/a><\/figure>\n<\/div>\n\n\n<p>The three registers we care about are \u2013 CRL, CNTH and CNTL.<\/p>\n\n\n\n<p>CRL \u2013 this is the control register for RTC. We\u2019ll need it so that RTC allows us to write our value into the counter. This is done with bit 4, i.e., CNF.<\/p>\n\n\n\n<p>CNTH and CNTL \u2013 the upper and lower RTC counters. Both 16-bit. This is where RTC counts seconds.<\/p>\n\n\n\n<p>Now, to change the counter value you need to:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Set the CNF bit of the CRL register to 0x1<\/li>\n\n\n\n<li>Modify the CNTH and CNTL values \u2013 in Eclipse they will \u201creturn\u201d to their values after you enter them<\/li>\n\n\n\n<li>Clear the CNF bit of the CRL register (0x0) to latch the introduced changes in the counter.<\/li>\n<\/ol>\n\n\n\n<p>By how much should we increase the RTC counter? We want to check changes by a day or a few. One day is 86400 seconds, so that\u2019s how much you need to add to the counter for each day to simulate a day change.<\/p>\n\n\n\n<p>I\u2019ll add 2 days and a few seconds \u2013 I\u2019ll set the counter to 180000. CNTH = 0x2, CNTL = 0xBF20.&nbsp;<\/p>\n\n\n\n<p>Before the change, during pause I have the date set to 17.05.2020 and the time 16:58:17 (I jumped into the future). Now I\u2019ll change the counter and reset the MCU. This is exactly the MCU power coming back while the RTC is on battery backup power.<\/p>\n\n\n\n<p>What happened?<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><a href=\"http:\/\/msalamon.pl\/wp-content\/uploads\/2020\/02\/rtcf1_before_change.jpg\"><img loading=\"lazy\" decoding=\"async\" width=\"688\" height=\"441\" src=\"http:\/\/msalamon.pl\/wp-content\/uploads\/2020\/02\/rtcf1_before_change.jpg\" alt=\"\" class=\"wp-image-1403\" srcset=\"https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/02\/rtcf1_before_change.jpg 688w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/02\/rtcf1_before_change-300x192.jpg 300w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/02\/rtcf1_before_change-24x15.jpg 24w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/02\/rtcf1_before_change-36x23.jpg 36w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/02\/rtcf1_before_change-125x80.jpg 125w\" sizes=\"auto, (max-width: 688px) 100vw, 688px\" \/><\/a><\/figure>\n<\/div>\n\n\n<p>Damn, something is wrong! The time changed, but the day was not updated. How is that possible? We remembered the date in the backup register.<\/p>\n\n\n\n<p>This is where the weakness of ST\u2019s solution shows up\u2026 The problem is in the <em>HAL_RTC_SetDate<\/em> function. Inside this function, the RTC counter is corrected, which in short consists of <strong>CUTTING OFF THE ELAPSED DAYS<\/strong>. This causes the number of elapsed days to disappear from the RTC counter and it is not transferred to the date in any way. SCANDAL!<\/p>\n\n\n\n<p>This is a terrible problem, because even using backup registers we are still not able to easily control the date. There are two solutions:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Write your own RTC handling, which will be better thought out.<\/li>\n\n\n\n<li>Do a bit of code gymnastics and recover the date without modifying ST\u2019s code (HAL and the RTC lib).<\/li>\n<\/ol>\n\n\n\n<p>Let me do the second option. Just for practice and to show that you can still use the library generated by Cube.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Full date recovery<\/h2>\n\n\n\n<p>Oh, HAL opponents will hate me, because I\u2019m going to make a workaround now involving adding many clock cycles. But maybe they\u2019ll praise me for ingenuity \ud83d\ude42 Feel free to discuss.<\/p>\n\n\n\n<p>I will need two <em>RTC_DateTypeDef<\/em> variables:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>RtcDate, which I use everywhere in the later code. This is the target variable that should contain the date.<\/li>\n\n\n\n<li>BackupDate \u2013 a temporary variable for calculations.<\/li>\n<\/ol>\n\n\n\n<p>Everything will happen in RTC initialization. After MCU startup, I collect the backup registers into the target variable.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/* USER CODE BEGIN Check_RTC_BKUP *\/\n\nRTC_DateTypeDef BackupDate;\n\nRtcDate.Date = (HAL_RTCEx_BKUPRead(&amp;amp;hrtc, RTC_BKP_DR2) &amp;gt;&amp;gt; 8);\nRtcDate.Month = HAL_RTCEx_BKUPRead(&amp;amp;hrtc, RTC_BKP_DR2);\nRtcDate.Year = (HAL_RTCEx_BKUPRead(&amp;amp;hrtc, RTC_BKP_DR3) &amp;gt;&amp;gt; 8);\nRtcDate.WeekDay = HAL_RTCEx_BKUPRead(&amp;amp;hrtc, RTC_BKP_DR3);<\/pre>\n\n\n\n<p>In the next step I collect the time, which is correct, into the target time variable. At this moment a new date is also calculated based on the RTC counter. By adding 2 days, it will be January 3rd of year 00, because ST\u2019s software calendar counts from January 1st of year 00.<\/p>\n\n\n\n<p>Now I collect that date into the temporary backup variable.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">HAL_RTC_GetTime(&amp;amp;hrtc, &amp;amp;RtcTime, RTC_FORMAT_BIN); \/\/ There is also an internal date update based on HW RTC time elapsed!!\nHAL_RTC_GetDate(&amp;amp;hrtc, &amp;amp;BackupDate, RTC_FORMAT_BIN); \/\/ Days elapsed since MCU power down<\/pre>\n\n\n\n<p>Now it\u2019s enough to add these 2 days to our target calendar variable and everything is great? Yes! Only\u2026 what if it\u2019s so many days that in the new date the month or year rolls over. The calculations become complicated\u2026<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Operations on the number of elapsed days<\/h2>\n\n\n\n<p>I found <a href=\"https:\/\/web.archive.org\/web\/20170507133619\/https:\/alcor.concordia.ca\/~gpkatch\/gdate-algorithm.html\" target=\"_blank\" rel=\"noopener\">two useful algorithms<\/a> operating on integers. They do have some issues with year zero, but that can be worked around.<\/p>\n\n\n\n<p>The first function, <em>CalculateDayNumber&nbsp;<\/em>, is supposed to return the day number from the beginning of the calendar based on the date.<\/p>\n\n\n\n<p>The second returns the date based on the day number.<\/p>\n\n\n\n<p>To avoid strange errors around year zero, I added and subtracted 20 years in both functions. 20 because, like year zero, it is a leap year. So there won\u2019t be errors because of that.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\/* USER CODE BEGIN 1 *\/\nuint32_t CalculateDayNumber(uint8_t Date, uint8_t Month, uint8_t Year)\n{\n\t\/\/ Format:\n\t\/\/ DD.MM.YY\n\tuint32_t _Year = Year + 20;\n\tMonth = (Month + 9) % 12;\n\t_Year = _Year - (Month \/ 10);\n\treturn ((365 * _Year) + (_Year \/ 4) - (_Year \/ 100) + (_Year \/ 400) + (((Month * 306) + 5) \/ 10) + (Date - 1));\n}\n\nvoid CalculateDateFromDayNumber(uint32_t DayNumber, uint8_t *Date, uint8_t *Month, uint8_t *Year)\n{\n\tuint32_t _Date, _Month, _Year;\n\t_Year = ((10000 * DayNumber) + 14780) \/ 3652425;\n\tint32_t ddd = DayNumber - ((365 * _Year) + (_Year \/ 4) - (_Year \/ 100) + (_Year \/ 400));\n\tif (ddd &amp;lt; 0)\n\t{\n\t\t_Year -= 1;\n\t\tddd = DayNumber - ((365 * _Year) + (_Year \/ 4) - (_Year \/ 100) + (_Year \/ 400));\n\t}\n\tint32_t mi = ((100 * ddd) + 52) \/ 3060;\n\t_Month = (mi + 2) % 12 + 1;\n\t_Year = _Year + (mi + 2)\/12;\n\t_Date = ddd - ((mi * 306) + 5)\/10 + 1;\n\t*Date = _Date;\n\t*Month = _Month;\n\t*Year = _Year - 20;\n}\n\/* USER CODE END 1 *\/<\/pre>\n\n\n\n<p>Now, having the backup date and the date that elapsed while power was absent, I can calculate their corresponding day numbers.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">  uint32_t BackupDateDays = CalculateDayNumber(BackupDate.Date, BackupDate.Month, BackupDate.Year);\n  uint32_t RtcDateDays = CalculateDayNumber(RtcDate.Date, RtcDate.Month, RtcDate.Year);<\/pre>\n\n\n\n<p>To the target date, it\u2019s enough to add the days that elapsed. However, you need to subtract January 1st due to the fact that inside the algorithm we are actually counting the day 20 years ahead (due to errors for year 0000).<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">RtcDateDays += (BackupDateDays - CalculateDayNumber(1, 1, 0));<\/pre>\n\n\n\n<p>Now the only thing left is to transform the day number into a date using the second algorithm.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">CalculateDateFromDayNumber(RtcDateDays, &amp;amp;RtcDate.Date, &amp;amp;RtcDate.Month, &amp;amp;RtcDate.Year);<\/pre>\n\n\n\n<p>Finally, write this date into the software calendar.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">HAL_RTC_SetDate(&amp;amp;hrtc, &amp;amp;RtcDate, RTC_FORMAT_BIN);<\/pre>\n\n\n\n<p>That\u2019s it \ud83d\ude42<\/p>\n\n\n\n<p>Now the date will always (in 99%) be correct. I\u2019ll test again by entering 180000 into RTC.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><a href=\"http:\/\/msalamon.pl\/wp-content\/uploads\/2020\/02\/rtcf1_after_change.jpg\"><img loading=\"lazy\" decoding=\"async\" width=\"688\" height=\"441\" src=\"http:\/\/msalamon.pl\/wp-content\/uploads\/2020\/02\/rtcf1_after_change.jpg\" alt=\"\" class=\"wp-image-1404\" srcset=\"https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/02\/rtcf1_after_change.jpg 688w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/02\/rtcf1_after_change-300x192.jpg 300w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/02\/rtcf1_after_change-24x15.jpg 24w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/02\/rtcf1_after_change-36x23.jpg 36w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/02\/rtcf1_after_change-125x80.jpg 125w\" sizes=\"auto, (max-width: 688px) 100vw, 688px\" \/><\/a><\/figure>\n<\/div>\n\n\n<p>Does it always work? I won\u2019t bet my hand on it. Buuuut let\u2019s try adding\u2026 700 days, shall we?<\/p>\n\n\n\n<p>19.05.20 + 700 days = 19.04.22 according to the <a href=\"https:\/\/www.timeanddate.com\/date\/dateadded.html?d1=19&amp;m1=05&amp;y1=20&amp;type=add&amp;ay=&amp;am=&amp;aw=&amp;ad=700&amp;rec=\" target=\"_blank\" rel=\"noopener\">calculator<\/a>.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><a href=\"http:\/\/msalamon.pl\/wp-content\/uploads\/2020\/02\/rtcf1_add_700_days_web.jpg\"><img loading=\"lazy\" decoding=\"async\" width=\"999\" height=\"493\" src=\"http:\/\/msalamon.pl\/wp-content\/uploads\/2020\/02\/rtcf1_add_700_days_web.jpg\" alt=\"\" class=\"wp-image-1405\" srcset=\"https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/02\/rtcf1_add_700_days_web.jpg 999w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/02\/rtcf1_add_700_days_web-300x148.jpg 300w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/02\/rtcf1_add_700_days_web-768x379.jpg 768w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/02\/rtcf1_add_700_days_web-24x12.jpg 24w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/02\/rtcf1_add_700_days_web-36x18.jpg 36w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/02\/rtcf1_add_700_days_web-160x80.jpg 160w\" sizes=\"auto, (max-width: 999px) 100vw, 999px\" \/><\/a><\/figure>\n<\/div>\n\n\n<p>700 days * 86400 seconds = 60480000 seconds (0x39ADA00). Plus 2 hours gives 60847200 (0x39AF629) and I\u2019ll enter that value into RTC.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><figure><a href=\"http:\/\/msalamon.pl\/wp-content\/uploads\/2020\/02\/rtcf1_700d_plus.jpg\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/msalamon.pl\/wp-content\/uploads\/2020\/02\/rtcf1_700d_plus.jpg\" alt=\"\" width=\"491\" height=\"289\" class=\"aligncenter size-full wp-image-1406\" srcset=\"https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/02\/rtcf1_700d_plus.jpg 491w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/02\/rtcf1_700d_plus-300x177.jpg 300w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/02\/rtcf1_700d_plus-24x14.jpg 24w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/02\/rtcf1_700d_plus-36x21.jpg 36w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/02\/rtcf1_700d_plus-136x80.jpg 136w\" sizes=\"auto, (max-width: 491px) 100vw, 491px\"><\/a><\/figure>So what? It works!<figure><a href=\"http:\/\/msalamon.pl\/wp-content\/uploads\/2020\/02\/rtcf1_700d_plus_result.jpg\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/msalamon.pl\/wp-content\/uploads\/2020\/02\/rtcf1_700d_plus_result.jpg\" alt=\"\" width=\"688\" height=\"441\" class=\"aligncenter size-full wp-image-1407\" srcset=\"https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/02\/rtcf1_700d_plus_result.jpg 688w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/02\/rtcf1_700d_plus_result-300x192.jpg 300w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/02\/rtcf1_700d_plus_result-24x15.jpg 24w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/02\/rtcf1_700d_plus_result-36x23.jpg 36w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/02\/rtcf1_700d_plus_result-125x80.jpg 125w\" sizes=\"auto, (max-width: 688px) 100vw, 688px\"><\/a><\/figure><figure><a href=\"https:\/\/sklep.msalamon.pl\/kategoria-produktu\/dev-boardy\/stm32-nucleo\/?utm_source=blog&amp;utm_medium=banner&amp;utm_campaign=rtcf1&amp;utm_content=Text\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/msalamon.pl\/wp-content\/uploads\/2020\/07\/Nucleo-64-baner.jpg\" alt=\"\" width=\"1200\" height=\"400\" class=\"aligncenter wp-image-1593 size-full\" srcset=\"https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/07\/Nucleo-64-baner.jpg 1200w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/07\/Nucleo-64-baner-300x100.jpg 300w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/07\/Nucleo-64-baner-1024x341.jpg 1024w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/07\/Nucleo-64-baner-768x256.jpg 768w\" sizes=\"auto, (max-width: 1200px) 100vw, 1200px\"><\/a><\/figure><a href=\"http:\/\/msalamon.pl\/wp-content\/uploads\/2020\/02\/rtcf1_700d_plus_result.jpg\"><\/a><\/h2>\n\n\n\n<h2 class=\"wp-block-heading\">Summary<\/h2>\n\n\n\n<p>Using ST\u2019s library is quite a challenge. The creators of our favorite STMs pulled a nasty trick on us by delivering such a hard-to-use library. However, contrary to what the smartest guys say \u2013 it can be used.<\/p>\n\n\n\n<p>Also remember that this is the case for the poorest RTC, where there is only a seconds counter. In STM32F4 there is already a hardware calendar. I will definitely test it in the next posts.<\/p>\n\n\n\n<p>The article grew again. There are still two issues left. Battery backup, which is not as trivial as one might expect, and driving RTC with an external crystal, which on BluePill will also cause a few problems. That\u2019s for the next post!<\/p>\n\n\n\n<p><strong>In the meantime, I invite you to the comments section. Let me know if you liked this post and whether it makes sense to create articles like this. Every comment is valuable to me.<\/strong><\/p>\n\n\n\n<p>The full project along with the library can be found as usual on my GitHub:<a href=\"https:\/\/github.com\/lamik\/RTC_F103\/tree\/article_2\" target=\"_blank\" rel=\"noopener\"><span> LINK<\/span><\/a><\/p>\n\n\n\n<p><span>If you noticed any mistake, disagree with something, would like to add something important, or simply feel you\u2019d like to discuss this topic, write a comment. Remember that the discussion should be polite and in accordance with the rules of the Polish language.<\/span><\/p>\n\n\n<div class=\"kk-star-ratings kksr-auto kksr-align-left kksr-valign-bottom\"\n    data-payload='{&quot;align&quot;:&quot;left&quot;,&quot;id&quot;:&quot;4269&quot;,&quot;slug&quot;:&quot;default&quot;,&quot;valign&quot;:&quot;bottom&quot;,&quot;ignore&quot;:&quot;&quot;,&quot;reference&quot;:&quot;auto&quot;,&quot;class&quot;:&quot;&quot;,&quot;count&quot;:&quot;0&quot;,&quot;legendonly&quot;:&quot;&quot;,&quot;readonly&quot;:&quot;&quot;,&quot;score&quot;:&quot;0&quot;,&quot;starsonly&quot;:&quot;&quot;,&quot;best&quot;:&quot;5&quot;,&quot;gap&quot;:&quot;0&quot;,&quot;greet&quot;:&quot;&quot;,&quot;legend&quot;:&quot;0\\\/5 - (0 votes)&quot;,&quot;size&quot;:&quot;24&quot;,&quot;title&quot;:&quot;What is this date in the STM32F1 RCT?&quot;,&quot;width&quot;:&quot;0&quot;,&quot;_legend&quot;:&quot;{score}\\\/{best} - ({count} {votes})&quot;,&quot;font_factor&quot;:&quot;1.25&quot;}'>\n            \n<div class=\"kksr-stars\">\n    \n<div class=\"kksr-stars-inactive\">\n            <div class=\"kksr-star\" data-star=\"1\" style=\"padding-right: 0px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 24px; height: 24px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"2\" style=\"padding-right: 0px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 24px; height: 24px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"3\" style=\"padding-right: 0px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 24px; height: 24px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"4\" style=\"padding-right: 0px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 24px; height: 24px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" data-star=\"5\" style=\"padding-right: 0px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 24px; height: 24px;\"><\/div>\n        <\/div>\n    <\/div>\n    \n<div class=\"kksr-stars-active\" style=\"width: 0px;\">\n            <div class=\"kksr-star\" style=\"padding-right: 0px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 24px; height: 24px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 0px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 24px; height: 24px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 0px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 24px; height: 24px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 0px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 24px; height: 24px;\"><\/div>\n        <\/div>\n            <div class=\"kksr-star\" style=\"padding-right: 0px\">\n            \n\n<div class=\"kksr-icon\" style=\"width: 24px; height: 24px;\"><\/div>\n        <\/div>\n    <\/div>\n<\/div>\n                \n\n<div class=\"kksr-legend\" style=\"font-size: 19.2px;\">\n            <span class=\"kksr-muted\"><\/span>\n    <\/div>\n    <\/div>\n","protected":false},"excerpt":{"rendered":"<p>In the previous post I started a mini-series dedicated to the built-in RTC in STM32 chips. I began with probably the most popular microcontroller SMT32F103 found among others in the cheap BluePill board. I got to the point where after resetting the microcontroller the time was still correct, but the [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":3395,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_links_to":"","_links_to_target":""},"categories":[160],"tags":[176,174,177],"class_list":["post-4269","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-stm32","tag-programming","tag-stm32","tag-stm32cubemx"],"_links":{"self":[{"href":"https:\/\/msalamon.pl\/en\/wp-json\/wp\/v2\/posts\/4269","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/msalamon.pl\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/msalamon.pl\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/msalamon.pl\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/msalamon.pl\/en\/wp-json\/wp\/v2\/comments?post=4269"}],"version-history":[{"count":3,"href":"https:\/\/msalamon.pl\/en\/wp-json\/wp\/v2\/posts\/4269\/revisions"}],"predecessor-version":[{"id":4378,"href":"https:\/\/msalamon.pl\/en\/wp-json\/wp\/v2\/posts\/4269\/revisions\/4378"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/msalamon.pl\/en\/wp-json\/wp\/v2\/media\/3395"}],"wp:attachment":[{"href":"https:\/\/msalamon.pl\/en\/wp-json\/wp\/v2\/media?parent=4269"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/msalamon.pl\/en\/wp-json\/wp\/v2\/categories?post=4269"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/msalamon.pl\/en\/wp-json\/wp\/v2\/tags?post=4269"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}