2024-06-18 03:01 AM - edited 2024-06-18 07:57 AM
I am experiencing issues with the VBAT pin on the STM32H563ZIT6 microcontroller. Specifically, the VBAT pin is not responding properly. I am using a CR2032 CMOS battery for RTC backup, but it is not maintaining the date and time as expected. When the power supply is off, the RTC does not hold and run correctly, but it resumes running once the power supply is restored.
I have attached the circuit diagram for your reference. Could you please provide a clear explanation of the potential issues and offer guidance on how to resolve them? Expert advice on this matter would be greatly appreciated.
VBAT & CMOS :
Solved! Go to Solution.
2024-06-21 11:43 PM
Ok, but C14 should be there. (I use 10u cer.cap here.)
+
Set in Cube the LSE drive high !
Then it should work.
2024-06-22 12:46 AM - edited 2024-06-22 12:59 AM
As I suspected LSE is disabled. So your crystal will never oscillate.
And you don't use LSE as clock source either.
Drive strength depends on the MCU family and used crystal. Higher drive strength consumes more current. Too low and it may not oscillate.
Check Table 7. "Recommended crystal / MEMS resonators for the LSE oscillator in STM32"
from an2867-guidelines-for-oscillator-design-on-stm8afals-and-stm32-mcusmpus-stmicroelectronics.pdf for what your MCU supports.I've had issues with using a not supported crystal with too high capacitance. It resulted in some boards not booting sometimes since the LSE init function time out. The trick was using a different crystal with correctly calculated capacitors and set the right drive strength (in our case second highest level was good).
Check the datasheet of your MCU to see what drive strength levels are supported for LSEDRV.
"Table 43. Low-speed external user clock characteristic" in stm32h563zi.pdf
2024-06-27 12:18 AM
As per your instructions, the problem was solved. We checked it a few times, each for a duration of 5 to 10 minutes, over the last few days. If any issues occur in the future, I will call you back. Thank you for your support and guidance.
2024-06-27 12:56 AM
I'm glad you got it to work. Please kudo the posts that helped you.
2024-07-29 11:49 PM
Hi Bharath Kumar
In my project i was also working on the RTC.
We are also got the issue which you got, which the rtc does not getting updated during the power OFF. Please help me to solve the issue
2024-07-30 12:11 AM
Hi Ajay
Please follow the given STM instructions from the beginning to the end of our conversation.
Also, please provide your circuit for correction.
Ensure you use the internal oscillator
2024-07-30 12:36 AM
Please read this topic and other topics on RTC issues. If those don't help you, please open a new topic.
2024-07-30 12:45 AM
2024-07-30 01:02 AM
OK @unsigned_char_array we will go through it. but we get 1.2V on oscillator this means it is working properly??
2024-08-02 12:50 AM
Meanwhile we verify the hardware can you please let us know whether the code used for RTC Initialization and backup method is correct and sufficient. Please help me with this. Thankyou
/* USER CODE BEGIN Header */ #include "stdio.h" /* USER CODE END Header */ /* Includes ------------------------------------------------------------------*/ #include "main.h" /* Private includes ----------------------------------------------------------*/ /* USER CODE BEGIN Includes */ /* USER CODE END Includes */ /* Private typedef -----------------------------------------------------------*/ /* USER CODE BEGIN PTD */ /* USER CODE END PTD */ /* Private define ------------------------------------------------------------*/ /* USER CODE BEGIN PD */ /* USER CODE END PD */ /* Private macro -------------------------------------------------------------*/ /* USER CODE BEGIN PM */ /* USER CODE END PM */ /* Private variables ---------------------------------------------------------*/ RTC_HandleTypeDef hrtc; UART_HandleTypeDef huart3; /* USER CODE BEGIN PV */ char time[10]; char date[10]; RTC_TimeTypeDef RtcTime; RTC_DateTypeDef RtcDate; uint8_t CompareSeconds; uint8_t CompareDate; uint8_t Message[64]; uint8_t MessageLen; uint8_t Messagexyz[64]; uint8_t MessageLenxyz; /* USER CODE END PV */ /* Private function prototypes -----------------------------------------------*/ void SystemClock_Config(void); static void MX_GPIO_Init(void); static void MX_RTC_Init(void); static void MX_USART3_UART_Init(void); void BackupDateToBR(void); extern uint32_t CalculateDayNumber(uint8_t , uint8_t , uint8_t ); // DD.MM.YY extern void CalculateDateFromDayNumber(uint32_t , uint8_t *, uint8_t *, uint8_t *); /* USER CODE BEGIN PFP */ /* USER CODE END PFP */ /* Private user code ---------------------------------------------------------*/ /* USER CODE BEGIN 0 */ uint32_t CalculateDayNumber(uint8_t Date, uint8_t Month, uint8_t Year) { // Format: // DD.MM.YY uint32_t _Year = Year + 20; Month = (Month + 9) % 12; _Year = _Year - (Month / 10); return ((365 * _Year) + (_Year / 4) - (_Year / 100) + (_Year / 400) + (((Month * 306) + 5) / 10) + (Date - 1)); } void CalculateDateFromDayNumber(uint32_t DayNumber, uint8_t *Date, uint8_t *Month, uint8_t *Year) { uint32_t _Date, _Month, _Year; _Year = ((10000 * DayNumber) + 14780) / 3652425; int32_t ddd = DayNumber - ((365 * _Year) + (_Year / 4) - (_Year / 100) + (_Year / 400)); if (ddd < 0) { _Year -= 1; ddd = DayNumber - ((365 * _Year) + (_Year / 4) - (_Year / 100) + (_Year / 400)); } int32_t mi = ((100 * ddd) + 52) / 3060; _Month = (mi + 2) % 12 + 1; _Year = _Year + (mi + 2)/12; _Date = ddd - ((mi * 306) + 5)/10 + 1; *Date = _Date; *Month = _Month; *Year = _Year - 20; } /* USER CODE END 0 */ /** * @brief The application entry point. * @retval int */ int main(void) { /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ /* MCU Configuration--------------------------------------------------------*/ /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ HAL_Init(); /* USER CODE BEGIN Init */ /* USER CODE END Init */ /* Configure the system clock */ SystemClock_Config(); /* USER CODE BEGIN SysInit */ /* USER CODE END SysInit */ /* Initialize all configured peripherals */ MX_GPIO_Init(); MX_RTC_Init(); MX_USART3_UART_Init(); /* USER CODE BEGIN 2 */ /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ HAL_GPIO_WritePin(GPIOA, GPIO_PIN_15, GPIO_PIN_SET); HAL_Delay(200); HAL_GPIO_WritePin(GPIOB, GPIO_PIN_13, GPIO_PIN_SET); HAL_Delay(200); HAL_GPIO_WritePin(GPIOA, GPIO_PIN_15, GPIO_PIN_RESET); HAL_Delay(2000); while(1) { HAL_RTC_GetTime(&hrtc, &RtcTime, RTC_FORMAT_BIN); HAL_RTC_GetDate(&hrtc, &RtcDate, RTC_FORMAT_BIN); if(RtcTime.Seconds != CompareSeconds) { MessageLen = 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); HAL_UART_Transmit(&huart3, Message, MessageLen, 100); CompareSeconds = RtcTime.Seconds; } if(RtcDate.Date != CompareDate) { BackupDateToBR(); CompareDate = RtcDate.Date; } } /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ /* USER CODE END 3 */ } /** * @brief System Clock Configuration * @retval None */ void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; RCC_PeriphCLKInitTypeDef PeriphClkInit = {0}; /** Initializes the RCC Oscillators according to the specified parameters * in the RCC_OscInitTypeDef structure. */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI|RCC_OSCILLATORTYPE_LSE; RCC_OscInitStruct.LSEState = RCC_LSE_ON; RCC_OscInitStruct.HSIState = RCC_HSI_ON; RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI_DIV2; RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9; if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { Error_Handler(); } /** Initializes the CPU, AHB and APB buses clocks */ RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK) { Error_Handler(); } PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_RTC; PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_LSE; if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) { Error_Handler(); } } /** * @brief RTC Initialization Function * None * @retval None */ static void MX_RTC_Init(void) { /* USER CODE BEGIN RTC_Init 0 */ /* USER CODE END RTC_Init 0 */ RTC_TimeTypeDef sTime = {0}; RTC_DateTypeDef DateToUpdate = {0}; /* USER CODE BEGIN RTC_Init 1 */ /* USER CODE END RTC_Init 1 */ /** Initialize RTC Only */ hrtc.Instance = RTC; hrtc.Init.AsynchPrediv = RTC_AUTO_1_SECOND; hrtc.Init.OutPut = RTC_OUTPUTSOURCE_ALARM; if (HAL_RTC_Init(&hrtc) != HAL_OK) { Error_Handler(); } /* USER CODE BEGIN Check_RTC_BKUP */ RTC_DateTypeDef BackupDate; RtcDate.Date = (HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR2) >> 8); RtcDate.Month = HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR2); RtcDate.Year = (HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR3) >> 8); RtcDate.WeekDay = HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR3); MessageLenxyz = sprintf((char*)Messagexyz, "Backup Date Value: %d, Month: %d, Year: %d, Weekday: %d\n\r", RtcDate.Date, RtcDate.Month, RtcDate.Year, RtcDate.WeekDay); HAL_RTC_GetTime(&hrtc, &RtcTime, RTC_FORMAT_BIN); // There is also an internal date update based on HW RTC time elapsed!! HAL_RTC_GetDate(&hrtc, &BackupDate, RTC_FORMAT_BIN); // Days elapsed since MCU power down uint32_t BackupDateDays = CalculateDayNumber(BackupDate.Date, BackupDate.Month, BackupDate.Year); uint32_t RtcDateDays = CalculateDayNumber(RtcDate.Date, RtcDate.Month, RtcDate.Year); // MessageLenxyz = sprintf((char*)Messagexyz, "BackupDateDays : %d RtcDateDays: %d\n\r", BackupDateDays,RtcDateDays); RtcDateDays += (BackupDateDays - CalculateDayNumber(1, 1, 0)); CalculateDateFromDayNumber(RtcDateDays, &RtcDate.Date, &RtcDate.Month, &RtcDate.Year); HAL_RTC_SetDate(&hrtc, &RtcDate, RTC_FORMAT_BIN); return; /* USER CODE END Check_RTC_BKUP */ /** Initialize RTC and set the Time and Date */ sTime.Hours = 0x10; sTime.Minutes = 0x10; sTime.Seconds = 0x30; if (HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BCD) != HAL_OK) { Error_Handler(); } DateToUpdate.WeekDay = RTC_WEEKDAY_SATURDAY; DateToUpdate.Month = RTC_MONTH_JULY; DateToUpdate.Date = 0x27; DateToUpdate.Year = 0x24; if (HAL_RTC_SetDate(&hrtc, &DateToUpdate, RTC_FORMAT_BCD) != HAL_OK) { Error_Handler(); } /* USER CODE BEGIN RTC_Init 2 */ /* USER CODE END RTC_Init 2 */ } /** * @brief USART3 Initialization Function * None * @retval None */ static void MX_USART3_UART_Init(void) { /* USER CODE BEGIN USART3_Init 0 */ /* USER CODE END USART3_Init 0 */ /* USER CODE BEGIN USART3_Init 1 */ /* USER CODE END USART3_Init 1 */ huart3.Instance = USART3; huart3.Init.BaudRate = 115200; huart3.Init.WordLength = UART_WORDLENGTH_8B; huart3.Init.StopBits = UART_STOPBITS_1; huart3.Init.Parity = UART_PARITY_NONE; huart3.Init.Mode = UART_MODE_TX_RX; huart3.Init.HwFlowCtl = UART_HWCONTROL_NONE; huart3.Init.OverSampling = UART_OVERSAMPLING_16; if (HAL_UART_Init(&huart3) != HAL_OK) { Error_Handler(); } /* USER CODE BEGIN USART3_Init 2 */ /* USER CODE END USART3_Init 2 */ } /** * @brief GPIO Initialization Function * None * @retval None */ static void MX_GPIO_Init(void) { GPIO_InitTypeDef GPIO_InitStruct = {0}; /* USER CODE BEGIN MX_GPIO_Init_1 */ /* USER CODE END MX_GPIO_Init_1 */ /* GPIO Ports Clock Enable */ __HAL_RCC_GPIOC_CLK_ENABLE(); __HAL_RCC_GPIOD_CLK_ENABLE(); __HAL_RCC_GPIOB_CLK_ENABLE(); __HAL_RCC_GPIOA_CLK_ENABLE(); /*Configure GPIO pin Output Level */ HAL_GPIO_WritePin(GPIOB, GPIO_PIN_13, GPIO_PIN_RESET); /*Configure GPIO pin Output Level */ HAL_GPIO_WritePin(GPIOA, GPIO_PIN_15, GPIO_PIN_RESET); /*Configure GPIO pin : PB13 */ GPIO_InitStruct.Pin = GPIO_PIN_13; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); /*Configure GPIO pin : PA15 */ GPIO_InitStruct.Pin = GPIO_PIN_15; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); /* USER CODE BEGIN MX_GPIO_Init_2 */ /* USER CODE END MX_GPIO_Init_2 */ } /* USER CODE BEGIN 4 */ void BackupDateToBR(void) { HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_DR2, ((RtcDate.Date << | (RtcDate.Month))); HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_DR3, ((RtcDate.Year << | (RtcDate.WeekDay))); } /* USER CODE END 4 */ /** * @brief This function is executed in case of error occurrence. * @retval None */ void Error_Handler(void) { /* USER CODE BEGIN Error_Handler_Debug */ /* USER CODE END Error_Handler_Debug */ } #ifdef USE_FULL_ASSERT /** * @brief Reports the name of the source file and the source line number * where the assert_param error has occurred. * file: pointer to the source file name * line: assert_param error line source number * @retval None */ void assert_failed(uint8_t *file, uint32_t line) { /* USER CODE BEGIN 6 */ /* USER CODE END 6 */ } #endif /* USE_FULL_ASSERT */