{"id":4271,"date":"2020-02-05T20:00:59","date_gmt":"2020-02-05T19:00:59","guid":{"rendered":"https:\/\/msalamon.pl\/?p=4271"},"modified":"2025-12-27T17:36:46","modified_gmt":"2025-12-27T16:36:46","slug":"built-in-rtc-in-stm32f1","status":"publish","type":"post","link":"https:\/\/msalamon.pl\/en\/built-in-rtc-in-stm32f1\/","title":{"rendered":"Built-in RTC in STM32F1"},"content":{"rendered":"\n<p>STM32 microcontrollers undoubtedly have many killer features. Of course, compared to the ancient AVRs that are still used in the most popular Arduino Uno. One of those things is that <strong>STMs have a built-in real-time clock<\/strong>, RTC for short. Let me show you in detail what working with such a clock looks like using the HAL library generated by CubeMX.<\/p>\n\n\n\n<!--more-->\n\n\n\n<p>Some time ago I described external RTC chips (<a href=\"http:\/\/msalamon.pl\/piekielnie-dokladny-rtc-ds3231-na-stm32\/?utm_source=blog&amp;utm_medium=&amp;utm_campaign=rtcf1\">DS3231<\/a>, <a href=\"http:\/\/msalamon.pl\/dalsze-zmagania-z-rtc-ds1307-i-pcf8563-na-stm32\/?utm_source=blog&amp;utm_medium=&amp;utm_campaign=rtcf1\">DS1307 and PCF8563<\/a>). They were connected via the I\u00b2C interface and generated interrupts every second. Depending on the chip, they had either battery-backed SRAM memory or, for example, oscillator signal correction, making them extremely accurate. They also had hardware date handling inside.<\/p>\n\n\n\n<p>First of all, <strong>I will focus on the RTC built into the STM32F103C8T6 chip, i.e. the popular <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><\/strong>. More or less consciously, this is the first choice for beginners.<\/p>\n\n\n\n<p>You have to remember that <strong>this is one of the first RTC implementations used in STM32. It doesn\u2019t have many functions or extensive registers<\/strong>,&nbsp;as you\u2019ll see in a moment.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\"><figure><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\" src=\"http:\/\/msalamon.pl\/wp-content\/uploads\/2018\/09\/BluePill_baner-1024x341.jpg\" alt=\"\" width=\"750\" height=\"250\" class=\"aligncenter wp-image-953 size-large\" srcset=\"https:\/\/msalamon.pl\/wp-content\/uploads\/2018\/09\/BluePill_baner-1024x341.jpg 1024w, https:\/\/msalamon.pl\/wp-content\/uploads\/2018\/09\/BluePill_baner-300x100.jpg 300w, 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, https:\/\/msalamon.pl\/wp-content\/uploads\/2018\/09\/BluePill_baner.jpg 1200w\" sizes=\"auto, (max-width: 750px) 100vw, 750px\"><\/a><\/figure>RTC in the STM32F103<\/h1>\n\n\n\n<p>The clock circuit in its basic purpose is supposed to measure time, the human, watch-like one. <strong>In the F103, only one counter is used to count time\/date<\/strong>. <strong>It is a 32-bit register that counts only the number of seconds.<\/strong> I told you it\u2019s a simple RTC, right?<\/p>\n\n\n\n<p>Alright, but what do we need seconds alone for?! We want hours, minutes, and even the date like we had with dedicated external chips. What a piece of junk\u2026<\/p>\n\n\n\n<p>It\u2019s true that this single counter may look idiotic at first glance. However, it\u2019s not as stupid as it might seem. I don\u2019t know if you know, but in Linux-family systems time and date are also counted this way.<\/p>\n\n\n\n<p>Because it\u2019s implemented on a single counter, <strong>the programmer is free to decide what format they want to work with RTC in<\/strong>. You can use the <em>time.h<\/em> library and work with UNIX time or WinCE.<\/p>\n\n\n\n<p>Of course you can write your own RTC handling if you feel up to it. I highly recommend doing something like that. You can learn a lot along the way \ud83d\ude42<\/p>\n\n\n\n<p><strong>You can also use ST\u2019s library, which is included in the project generated by CubeMX.<\/strong> It works a bit differently than the UNIX standard. That\u2019s the library I\u2019ll focus on in the near future.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Battery backup<\/h3>\n\n\n\n<p>An interesting feature <strong>built into the RTC are the backup registers<\/strong>. In the F103 there are (as many as!) 10 of them. All are 16-bit, so you can store 20 bytes of data. Seems like little, right?<\/p>\n\n\n\n<p>These registers are battery-backed when the supply voltage disappears or the microcontroller enters low-power modes. Due to special battery backup, access to them is controlled by a special bit.<\/p>\n\n\n\n<p>In normal power mode, these registers operate from the voltage applied to VDD. <strong>The microcontroller reset circuit detects VDD loss and switches to VBAT power<\/strong> for the backup registers and also <strong>several special blocks. In total these are:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Backup Registers<\/li>\n\n\n\n<li>RTC \u2013 the clock can keep running<\/li>\n\n\n\n<li>LSI \u2013 internal oscillator for driving the RTC<\/li>\n\n\n\n<li>PC13 \u2013 Tamper detection<\/li>\n<\/ul>\n\n\n\n<p>Thanks to this, full RTC functionality is preserved after disconnecting the main power supply.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Tamper detection<\/h3>\n\n\n\n<p>There is also something called Tamper detection. Tamper in English means to meddle. It is detection of tampering with a device \ud83d\ude42<\/p>\n\n\n\n<p>How does it work in the STM32F103? <strong>The RTC has a special PC13 pin that is battery-backed<\/strong>, and can be configured as RTC_TAMPER. This pin can be connected to some kind of limit switch. <strong>After detecting the configured edge on this pin (for example, when someone opens the enclosure), an Event is triggered that clears the entire contents of the Backup Registers.<\/strong><\/p>\n\n\n\n<p>Importantly, the Tamper event also works from battery power.<\/p>\n\n\n\n<p>To be honest, I\u2019ve never used this mechanism. <strong>If you have any interesting application and a real example of use, describe it in the comments.<\/strong><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">RTC Alarm<\/h3>\n\n\n\n<p>Our RTC built into the <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\">STM32F103<\/a> has a simple alarm. There is a dedicated 32-bit register for this purpose. You write the alarm value there and if the value from the main RTC counter equals the alarm value, an interrupt will be generated.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Test platform<\/h2>\n\n\n\n<p>As I mentioned earlier, I will demonstrate RTC operation on the well-known and liked BluePill board with the STM32F103C8T6. This is currently my only STM32F1 platform that I own.<\/p>\n\n\n\n<p>The software I will use is:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>STM32CubeIDE v1.2.0<\/li>\n\n\n\n<li>STM32CubeMX v 5.5.0 built into the IDE<\/li>\n\n\n\n<li>HAL F1 v 1.8.0<\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">Configuration in CubeMX<\/h2>\n\n\n\n<p>For testing purposes, besides RTC I need a few other things.<\/p>\n\n\n\n<p>First, clocks:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>I set HCLK to the maximum value of 72 MHz<\/strong> using the external HSE oscillator.<\/li>\n\n\n\n<li><strong>As the RTC clock source, first choose LSI<\/strong> \u2013 later I\u2019ll show you how to switch to LSE<\/li>\n<\/ul>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><a href=\"http:\/\/msalamon.pl\/wp-content\/uploads\/2020\/02\/rtcf1_hse_lsi.jpg\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"451\" src=\"http:\/\/msalamon.pl\/wp-content\/uploads\/2020\/02\/rtcf1_hse_lsi-1024x451.jpg\" alt=\"\" class=\"wp-image-1393\" srcset=\"https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/02\/rtcf1_hse_lsi-1024x451.jpg 1024w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/02\/rtcf1_hse_lsi-300x132.jpg 300w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/02\/rtcf1_hse_lsi-768x338.jpg 768w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/02\/rtcf1_hse_lsi-1536x677.jpg 1536w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/02\/rtcf1_hse_lsi-24x11.jpg 24w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/02\/rtcf1_hse_lsi-36x16.jpg 36w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/02\/rtcf1_hse_lsi-160x70.jpg 160w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/02\/rtcf1_hse_lsi.jpg 1566w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n<\/div>\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><a href=\"http:\/\/msalamon.pl\/wp-content\/uploads\/2020\/02\/rtcf1_hse_lsi_clock_config.jpg\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"508\" src=\"http:\/\/msalamon.pl\/wp-content\/uploads\/2020\/02\/rtcf1_hse_lsi_clock_config-1024x508.jpg\" alt=\"\" class=\"wp-image-1394\" srcset=\"https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/02\/rtcf1_hse_lsi_clock_config-1024x508.jpg 1024w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/02\/rtcf1_hse_lsi_clock_config-300x149.jpg 300w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/02\/rtcf1_hse_lsi_clock_config-768x381.jpg 768w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/02\/rtcf1_hse_lsi_clock_config-1536x761.jpg 1536w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/02\/rtcf1_hse_lsi_clock_config-24x12.jpg 24w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/02\/rtcf1_hse_lsi_clock_config-36x18.jpg 36w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/02\/rtcf1_hse_lsi_clock_config-160x80.jpg 160w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/02\/rtcf1_hse_lsi_clock_config.jpg 1602w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n<\/div>\n\n\n<p><\/p>\n\n\n\n<p>For debugging purposes I used:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>UART2 in 115200 8n1 configuration<\/li>\n\n\n\n<li>Serial Wire in the System Core > SYS > Debug > Serial Wire tab<\/li>\n\n\n\n<li>GPIO input PA10 labeled as TEST<\/li>\n<\/ul>\n\n\n\n<p><strong>Now you can configure the RTC. It is located in the tree under Timers.<\/strong><\/p>\n\n\n\n<p>Check <strong>Activate Clock Source<\/strong> \u2013 to enable the RTC and provide the clock source. <strong>Also enable the calendar with the second checkbox.<\/strong> Wait, wait! I said there is no calendar here, right? What\u2019s going on?<\/p>\n\n\n\n<p>This will be a <strong>software calendar provided by ST\u2019s library<\/strong> \ud83d\ude42<\/p>\n\n\n\n<p>Below are the RTC settings. You can set the factory time and date. You enter the year in the 0\u201399 range, without hundreds and thousands.<\/p>\n\n\n\n<p>Also switch Data Format to binary. There will be no need to convert from BCD to \u201chuman\u201d numbers and back later.<\/p>\n\n\n\n<p>In the fields under General, leave everything at default: automatic prescaler calculation (convenience) and Alarm on the TAMPER pin (it doesn\u2019t matter for us at this moment).<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><a href=\"http:\/\/msalamon.pl\/wp-content\/uploads\/2020\/02\/rtcf1_rtc_config.jpg\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"546\" src=\"http:\/\/msalamon.pl\/wp-content\/uploads\/2020\/02\/rtcf1_rtc_config-1024x546.jpg\" alt=\"\" class=\"wp-image-1395\" srcset=\"https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/02\/rtcf1_rtc_config-1024x546.jpg 1024w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/02\/rtcf1_rtc_config-300x160.jpg 300w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/02\/rtcf1_rtc_config-768x409.jpg 768w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/02\/rtcf1_rtc_config-24x13.jpg 24w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/02\/rtcf1_rtc_config-36x19.jpg 36w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/02\/rtcf1_rtc_config-150x80.jpg 150w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/02\/rtcf1_rtc_config.jpg 1422w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n<\/div>\n\n\n<p><\/p>\n\n\n\n<p><strong>You can generate the project \ud83d\ude42<\/strong><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">RTC code<\/h2>\n\n\n\n<p>We got ST\u2019s library to work with, which also implements a software calendar. To operate on the RTC you need to create two instances of structures \u2013 time and date. Let me omit the additional elements related to sending data over UART.<\/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=\"\">RTC_TimeTypeDef RtcTime;\nRTC_DateTypeDef RtcDate;<\/pre>\n\n\n\n<p>Each of these structures has fields responsible for each element of date and time.<\/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=\"\">typedef struct\n{\n  uint8_t Hours;            \/*!&amp;lt; Specifies the RTC Time Hour.\n                                 This parameter must be a number between Min_Data = 0 and Max_Data = 23 *\/\n\n  uint8_t Minutes;          \/*!&amp;lt; Specifies the RTC Time Minutes.\n                                 This parameter must be a number between Min_Data = 0 and Max_Data = 59 *\/\n\n  uint8_t Seconds;          \/*!&amp;lt; Specifies the RTC Time Seconds.\n                                 This parameter must be a number between Min_Data = 0 and Max_Data = 59 *\/\n\n} RTC_TimeTypeDef;\n\ntypedef struct\n{\n  uint8_t WeekDay;  \/*!&amp;lt; Specifies the RTC Date WeekDay (not necessary for HAL_RTC_SetDate).\n                         This parameter can be a value of @ref RTC_WeekDay_Definitions *\/\n\n  uint8_t Month;    \/*!&amp;lt; Specifies the RTC Date Month (in BCD format).\n                         This parameter can be a value of @ref RTC_Month_Date_Definitions *\/\n\n  uint8_t Date;     \/*!&amp;lt; Specifies the RTC Date.\n                         This parameter must be a number between Min_Data = 1 and Max_Data = 31 *\/\n\n  uint8_t Year;     \/*!&amp;lt; Specifies the RTC Date Year.\n                         This parameter must be a number between Min_Data = 0 and Max_Data = 99 *\/\n\n} RTC_DateTypeDef;<\/pre>\n\n\n\n<p>So it\u2019s easy to reference them. <strong>Notice that the date also has the day-of-week number. You don\u2019t have to fill it in manually. When updating the date, it is calculated and written automatically.<\/strong><\/p>\n\n\n\n<p>Now in the main loop you can easily read the date and time.<\/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);\nHAL_RTC_GetDate(&amp;amp;hrtc, &amp;amp;RtcDate, RTC_FORMAT_BIN);<\/pre>\n\n\n\n<p>And that\u2019s it. Now it\u2019s enough to send it over UART. I added a small mechanism where I send to UART only when the second changes. We don\u2019t need an avalanche of data on the serial port.<\/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(RtcTime.Seconds != CompareSeconds)\n{\n\tMessageLen = sprintf((char*)Message, \"Date: %02d.%02d.20%02d Time: %02d:%02d:%02d\\n\\r\", RtcDate.Date, RtcDate.Month, RtcDate.Year, RtcTime.Hours, RtcTime.Minutes, RtcTime.Seconds);\n\tHAL_UART_Transmit(&amp;amp;huart2, Message, MessageLen, 100);\n\tCompareSeconds = RtcTime.Seconds;\n}<\/pre>\n\n\n\n<p>Here is the result.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><figure><a href=\"http:\/\/msalamon.pl\/wp-content\/uploads\/2020\/02\/rtcf1_time_on_terminal.jpg\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/msalamon.pl\/wp-content\/uploads\/2020\/02\/rtcf1_time_on_terminal.jpg\" alt=\"\" width=\"688\" height=\"440\" class=\"aligncenter wp-image-1396 size-full\" srcset=\"https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/02\/rtcf1_time_on_terminal.jpg 688w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/02\/rtcf1_time_on_terminal-300x192.jpg 300w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/02\/rtcf1_time_on_terminal-24x15.jpg 24w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/02\/rtcf1_time_on_terminal-36x23.jpg 36w, https:\/\/msalamon.pl\/wp-content\/uploads\/2020\/02\/rtcf1_time_on_terminal-125x80.jpg 125w\" sizes=\"auto, (max-width: 688px) 100vw, 688px\"><\/a><\/figure>Reloading date and time at MCU startup<\/h2>\n\n\n\n<p>When you reset the microcontroller, you\u2019ll notice that the date and time returned to those set from Cube. On the Internet you can find countless threads devoted to this terrible \u201cbug\u201d.<\/p>\n\n\n\n<p>I\u2019m not sure if it can be called a bug at all. It\u2019s normal library behavior. It\u2019s like if you wrote in main before the main loop that you want to set some date and expected it not to change between resets. It will be the same.<\/p>\n\n\n\n<p>How to fight it? After all, this is generated using Cube. Deleting the lines that set the time and date won\u2019t help when you regenerate the code in Cube. When you need to regenerate the code after some time, I guarantee you\u2019ll forget about it and you\u2019ll look for the problem from scratch. That\u2019s not how we do it!<\/p>\n\n\n\n<p>If you look into the RTC initialization code <strong>in the rtc.c file, you\u2019ll notice that right before setting the date and time there is a special user section. That\u2019s exactly what you will use.<\/strong><\/p>\n\n\n\n<p><strong>Insert a simple&nbsp;return here<\/strong>. It won\u2019t let the microcontroller reach the point where RTC is set, so time will run as it did before the reset. Beautiful!<\/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 MX_RTC_Init(void)\n{\n  RTC_TimeTypeDef sTime = {0};\n  RTC_DateTypeDef DateToUpdate = {0};\n\n  \/** Initialize RTC Only \n  *\/\n  hrtc.Instance = RTC;\n  hrtc.Init.AsynchPrediv = RTC_AUTO_1_SECOND;\n  hrtc.Init.OutPut = RTC_OUTPUTSOURCE_ALARM;\n  if (HAL_RTC_Init(&amp;amp;hrtc) != HAL_OK)\n  {\n    Error_Handler();\n  }\n\n  \/* USER CODE BEGIN Check_RTC_BKUP *\/\n  \/\/\n  \/\/\tYou have to do not let Init code to reinitialize Time and Date in RTC.\n  \/\/\tIt's \"a bug\" in HAL widely described and complain on forums.\n  \/\/\tThat causes every MCU restart the time and date will be same as you configured in CubeMX.\n  \/\/\tAll 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 *\/\n\n  \/** Initialize RTC and set the Time and Date \n  *\/\n  sTime.Hours = 23;\n  sTime.Minutes = 59;\n  sTime.Seconds = 55;\n\n  if (HAL_RTC_SetTime(&amp;amp;hrtc, &amp;amp;sTime, RTC_FORMAT_BIN) != HAL_OK)\n  {\n    Error_Handler();\n  }\n  DateToUpdate.WeekDay = RTC_WEEKDAY_SATURDAY;\n  DateToUpdate.Month = RTC_MONTH_FEBRUARY;\n  DateToUpdate.Date = 3;\n  DateToUpdate.Year = 20;\n\n  if (HAL_RTC_SetDate(&amp;amp;hrtc, &amp;amp;DateToUpdate, RTC_FORMAT_BIN) != HAL_OK)\n  {\n    Error_Handler();\n  }\n\n}<\/pre>\n\n\n\n<p>Now after reset the time is remembered, but the date isn\u2019t\u2026<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Problems with the date<\/h2>\n\n\n\n<p><strong>The date is not remembered because it is not a component of the hardware RTC!<\/strong> Additionally, ST\u2019s library does not treat the hardware RTC counter as date + time. It is used only for counting seconds, and when the counter rolls over \u2013 the day is reset.<\/p>\n\n\n\n<p>The date structure is just a variable in SRAM that the library stores. So it\u2019s normal that after a microcontroller reset it will be cleared!<\/p>\n\n\n\n<p><strong>You can fight it. Remember the Backup Registers? Exactly with them.<\/strong><\/p>\n\n\n\n<p>However, I\u2019ll deal with that next time, because this post has already become quite large.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter\"><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=nucleo\"><img loading=\"lazy\" decoding=\"async\" width=\"1200\" height=\"400\" src=\"http:\/\/msalamon.pl\/wp-content\/uploads\/2020\/07\/Nucleo-64-baner.jpg\" alt=\"\" class=\"wp-image-1593\" 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>\n<\/div>\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Summary<\/h2>\n\n\n\n<p>As you can see, you won\u2019t use the RTC right away the same way you would with those in dedicated ICs. Even though configuration in Cube and usage are quite easy, a problem appeared with the disappearing date and the lack of keeping it when power is removed.<\/p>\n\n\n\n<p>But don\u2019t worry! In the next article I\u2019ll show you how to deal with it. I\u2019ll also cover switching to work with an external crystal, because that will also bring a certain surprise \ud83d\ude09<\/p>\n\n\n\n<p>You can find the full project along with the library, as usual, on my GitHub:<a href=\"https:\/\/github.com\/lamik\/RTC_F103\" target=\"_blank\" rel=\"noopener\"><span> LINK<\/span><\/a><\/p>\n\n\n\n<p><span>If you noticed an error, disagree with something, would like to add something important, or simply feel like 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;4271&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;1&quot;,&quot;legendonly&quot;:&quot;&quot;,&quot;readonly&quot;:&quot;&quot;,&quot;score&quot;:&quot;5&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;5\\\/5 - (1 vote)&quot;,&quot;size&quot;:&quot;24&quot;,&quot;title&quot;:&quot;Built-in RTC in STM32F1&quot;,&quot;width&quot;:&quot;120&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: 120px;\">\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            5\/5 - (1 vote)    <\/div>\n    <\/div>\n","protected":false},"excerpt":{"rendered":"<p>STM32 microcontrollers undoubtedly have many killer features. Of course, compared to the ancient AVRs that are still used in the most popular Arduino Uno. One of those things is that STMs have a built-in real-time clock, RTC for short. Let me show you in detail what working with such a [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":3387,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_links_to":"","_links_to_target":""},"categories":[160],"tags":[175,176,174,177],"class_list":["post-4271","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-stm32","tag-electronics","tag-programming","tag-stm32","tag-stm32cubemx"],"_links":{"self":[{"href":"https:\/\/msalamon.pl\/en\/wp-json\/wp\/v2\/posts\/4271","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=4271"}],"version-history":[{"count":3,"href":"https:\/\/msalamon.pl\/en\/wp-json\/wp\/v2\/posts\/4271\/revisions"}],"predecessor-version":[{"id":4380,"href":"https:\/\/msalamon.pl\/en\/wp-json\/wp\/v2\/posts\/4271\/revisions\/4380"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/msalamon.pl\/en\/wp-json\/wp\/v2\/media\/3387"}],"wp:attachment":[{"href":"https:\/\/msalamon.pl\/en\/wp-json\/wp\/v2\/media?parent=4271"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/msalamon.pl\/en\/wp-json\/wp\/v2\/categories?post=4271"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/msalamon.pl\/en\/wp-json\/wp\/v2\/tags?post=4271"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}