STM32H7RTC在电源降低后重置(连接VBAT)

问题描述 投票:0回答:4

I正在使用STM32H753和STM32Cubemx,并尝试在VBAT上运行RTC模块。为此,我将电池连接到MCU。 RTC连接到LSE。接下来,我将RTC设置在代码中,然后将MCU与电源源断开连接,然后再次重新连接。基于文档,这应该自动将RTC电源从VDD切换到VBAT。 我已经在启动中评论了MX_RTC_INIT(),因此当MCU重新启动时,RTC不会重置。 below是系统时钟配置,RTC Init和用于读取RTC寄存器的代码。

void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0}; /** Supply configuration update enable */ HAL_PWREx_ConfigSupply(PWR_LDO_SUPPLY); /** Configure the main internal regulator output voltage */ __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); while(!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {} /** Configure LSE Drive Capability */ HAL_PWR_EnableBkUpAccess(); __HAL_RCC_LSEDRIVE_CONFIG(RCC_LSEDRIVE_LOW); /** Macro to configure the PLL clock source */ __HAL_RCC_PLL_PLLSOURCE_CONFIG(RCC_PLLSOURCE_HSE); /** Initializes the CPU, AHB and APB busses clocks */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE|RCC_OSCILLATORTYPE_LSE; RCC_OscInitStruct.HSEState = RCC_HSE_ON; RCC_OscInitStruct.LSEState = RCC_LSE_ON; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLM = 1; RCC_OscInitStruct.PLL.PLLN = 84; RCC_OscInitStruct.PLL.PLLP = 2; RCC_OscInitStruct.PLL.PLLQ = 4; RCC_OscInitStruct.PLL.PLLR = 2; RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_3; RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE; RCC_OscInitStruct.PLL.PLLFRACN = 0; if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { Error_Handler(); } /** Initializes the CPU, AHB and APB busses clocks */ RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2 |RCC_CLOCKTYPE_D3PCLK1|RCC_CLOCKTYPE_D1PCLK1; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV2; RCC_ClkInitStruct.APB3CLKDivider = RCC_APB3_DIV2; RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV4; RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV4; RCC_ClkInitStruct.APB4CLKDivider = RCC_APB4_DIV2; if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK) { Error_Handler(); } PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_RTC|RCC_PERIPHCLK_USART3 |RCC_PERIPHCLK_SPI1|RCC_PERIPHCLK_SDMMC |RCC_PERIPHCLK_ADC; PeriphClkInitStruct.PLL2.PLL2M = 1; PeriphClkInitStruct.PLL2.PLL2N = 25; PeriphClkInitStruct.PLL2.PLL2P = 4; PeriphClkInitStruct.PLL2.PLL2Q = 2; PeriphClkInitStruct.PLL2.PLL2R = 2; PeriphClkInitStruct.PLL2.PLL2RGE = RCC_PLL2VCIRANGE_3; PeriphClkInitStruct.PLL2.PLL2VCOSEL = RCC_PLL2VCOMEDIUM; PeriphClkInitStruct.PLL2.PLL2FRACN = 0; PeriphClkInitStruct.SdmmcClockSelection = RCC_SDMMCCLKSOURCE_PLL; PeriphClkInitStruct.Spi123ClockSelection = RCC_SPI123CLKSOURCE_PLL; PeriphClkInitStruct.Usart234578ClockSelection = RCC_USART234578CLKSOURCE_D2PCLK1; PeriphClkInitStruct.AdcClockSelection = RCC_ADCCLKSOURCE_PLL2; PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSE; if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) { Error_Handler(); } }

这是RTC InitCode

static void MX_RTC_Init(void) { /* USER CODE BEGIN RTC_Init 0 */ /* USER CODE END RTC_Init 0 */ RTC_TimeTypeDef sTime = {0}; RTC_DateTypeDef sDate = {0}; RTC_AlarmTypeDef sAlarm = {0}; /* USER CODE BEGIN RTC_Init 1 */ /* USER CODE END RTC_Init 1 */ /** Initialize RTC Only */ hrtc.Instance = RTC; hrtc.Init.HourFormat = RTC_HOURFORMAT_24; hrtc.Init.AsynchPrediv = 127; hrtc.Init.SynchPrediv = 255; hrtc.Init.OutPut = RTC_OUTPUT_DISABLE; hrtc.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH; hrtc.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN; hrtc.Init.OutPutRemap = RTC_OUTPUT_REMAP_NONE; if (HAL_RTC_Init(&hrtc) != HAL_OK) { Error_Handler(); } /* USER CODE BEGIN Check_RTC_BKUP */ /* USER CODE END Check_RTC_BKUP */ /** Initialize RTC and set the Time and Date */ sTime.Hours = 0x0; sTime.Minutes = 0x0; sTime.Seconds = 0x0; sTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE; sTime.StoreOperation = RTC_STOREOPERATION_RESET; if (HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BCD) != HAL_OK) { Error_Handler(); } sDate.WeekDay = RTC_WEEKDAY_MONDAY; sDate.Month = RTC_MONTH_JANUARY; sDate.Date = 0x1; sDate.Year = 0x0; if (HAL_RTC_SetDate(&hrtc, &sDate, RTC_FORMAT_BCD) != HAL_OK) { Error_Handler(); } /** Enable the Alarm A */ sAlarm.AlarmTime.Hours = 0x0; sAlarm.AlarmTime.Minutes = 0x20; sAlarm.AlarmTime.Seconds = 0x0; sAlarm.AlarmTime.SubSeconds = 0x0; sAlarm.AlarmTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE; sAlarm.AlarmTime.StoreOperation = RTC_STOREOPERATION_RESET; sAlarm.AlarmMask = RTC_ALARMMASK_DATEWEEKDAY|RTC_ALARMMASK_HOURS; sAlarm.AlarmSubSecondMask = RTC_ALARMSUBSECONDMASK_ALL; sAlarm.AlarmDateWeekDaySel = RTC_ALARMDATEWEEKDAYSEL_DATE; sAlarm.AlarmDateWeekDay = 0x1; sAlarm.Alarm = RTC_ALARM_A; if (HAL_RTC_SetAlarm_IT(&hrtc, &sAlarm, RTC_FORMAT_BCD) != HAL_OK) { Error_Handler(); } /** Enable the Alarm B */ sAlarm.AlarmTime.Minutes = 0x40; sAlarm.Alarm = RTC_ALARM_B; if (HAL_RTC_SetAlarm_IT(&hrtc, &sAlarm, RTC_FORMAT_BCD) != HAL_OK) { Error_Handler(); } /* USER CODE BEGIN RTC_Init 2 */ /* USER CODE END RTC_Init 2 */ }
这是我在启动后使用的代码来读取RTC寄存器vallues:

HAL_RTC_GetTime(&hrtc, &sTime, RTC_FORMAT_BIN); HAL_RTC_GetDate(&hrtc, &sDate, RTC_FORMAT_BIN); float subSecondsFloat = ( 255 - sTime.SubSeconds ); subSecondsFloat = (subSecondsFloat /255); subSecondsFloat = (subSecondsFloat * 1000); year = (uint32_t) (sDate.Year); month = (uint32_t) (sDate.Month); day = (uint32_t) (sDate.Date); hours = (uint32_t) (sTime.Hours); minutes = (uint32_t) (sTime.Minutes); seconds = (uint32_t) (sTime.Seconds); subseconds = (uint32_t) (subSecondsFloat); sprintf(usartSendBuffer,"\n%lu,%lu,%lu,%lu,%lu,%lu,%lu\n", year,month,day,hours, minutes,seconds,subseconds); printf(usartSendBuffer);
当我将MCU与电源断开并将其重新连接到电源源时,以上代码在电源重置后给出以下结果(RTC寄存器值):

159,10,9,32,51,51,4294967295
因此,RTC在MCU重置的某个地方重置。考虑到我已禁用MX_RTC_INIT(),我不知道RTC在哪里重置。

对不起,如果问题是基本的,我真的是这个领域的新手。

我非常感谢任何帮助,谢谢。 tovs vouria

您需要检查备份状态。

转到以下代码。 这是使用STM32系列日历的示例。

/** * @brief RTC Initialization Function * @param 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 sDate = {0}; /* USER CODE BEGIN RTC_Init 1 */ /* USER CODE END RTC_Init 1 */ /** Initialize RTC Only */ hrtc.Instance = RTC; hrtc.Init.HourFormat = RTC_HOURFORMAT_24; hrtc.Init.AsynchPrediv = 127; ///?// 127; hrtc.Init.SynchPrediv = 255; hrtc.Init.OutPut = RTC_OUTPUT_DISABLE; hrtc.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH; hrtc.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN; hrtc.Init.OutPutRemap = RTC_OUTPUT_REMAP_NONE; if (HAL_RTC_Init(&hrtc) != HAL_OK) { Error_Handler(); } /* USER CODE BEGIN Check_RTC_BKUP */ /*##-1- Check if Data stored in BackUp register1: No Need to reconfigure RTC#*/ /* Read the Back Up Register 1 Data */ if (HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR0) != RTC_BKUP_DEFINE_CODE) { // Clear Backup registor : recover to current RTC information // Set to Time/Date from current Time/Date // Write a data in ad RTC Backup data register HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_DR0, RTC_BKUP_DEFINE_CODE); } else { // Only read time and date HAL_RTC_GetTime(&hrtc, Time, Format); HAL_RTC_GetDate(&hrtc, Date, Format); } /* USER CODE END Check_RTC_BKUP */ /* USER CODE BEGIN RTC_Init 2 */ /* USER CODE END RTC_Init 2 */ }

stm32 real-time-clock stm32h743
4个回答
2
投票

要确认:我找不到使用VBAT维护RTC时钟的示例;

提示:HAL RTC时钟Intialisation将时钟设置为零,而日历寄存器则有点古怪。您必须从初始化代码中删除它,否则每次启动时,都会将时钟设置为零:
/** * @brief RTC Initialization Function * @param None * @retval None */ static void MX_RTC_Init(void) { /* USER CODE BEGIN RTC_Init 0 */ /* USER CODE END RTC_Init 0 */ #if TIME_DATE_SET_ON_BOOT == 1 RTC_TimeTypeDef sTime = {0}; RTC_DateTypeDef sDate = {0}; #endif /* USER CODE BEGIN RTC_Init 1 */ /* USER CODE END RTC_Init 1 */ /** Initialize RTC Only */ hrtc.Instance = RTC; hrtc.Init.HourFormat = RTC_HOURFORMAT_24; hrtc.Init.AsynchPrediv = 127; hrtc.Init.SynchPrediv = 255; hrtc.Init.OutPut = RTC_OUTPUT_DISABLE; hrtc.Init.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH; hrtc.Init.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN; hrtc.Init.OutPutRemap = RTC_OUTPUT_REMAP_NONE; if (HAL_RTC_Init(&hrtc) != HAL_OK) { Error_Handler(); } /* USER CODE BEGIN Check_RTC_BKUP */ /* USER CODE END Check_RTC_BKUP */ /** Initialize RTC and set the Time and Date */ #if TIME_DATE_SET_ON_BOOT == 1 sTime.Hours = 0x0; sTime.Minutes = 0x0; sTime.Seconds = 0x0; sTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE; sTime.StoreOperation = RTC_STOREOPERATION_RESET; if (HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BCD) != HAL_OK) { Error_Handler(); } sDate.WeekDay = RTC_WEEKDAY_MONDAY; sDate.Month = RTC_MONTH_JANUARY; sDate.Date = 0x1; sDate.Year = 0x0; if (HAL_RTC_SetDate(&hrtc, &sDate, RTC_FORMAT_BCD) != HAL_OK) { Error_Handler(); } #endif /* USER CODE BEGIN RTC_Init 2 */ /* USER CODE END RTC_Init 2 */ }
    
REASH是我的STM32H7B3LIHXQ处理器的启动代码:

int main(void) { /* USER CODE BEGIN 1 */ /* USER CODE END 1 */ /* MPU Configuration--------------------------------------------------------*/ MPU_Config(); /* Enable I-Cache---------------------------------------------------------*/ SCB_EnableICache(); /* Enable D-Cache---------------------------------------------------------*/ SCB_EnableDCache(); /* MCU Configuration--------------------------------------------------------*/ /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ HAL_Init(); /* Configure the system clock */ SystemClock_Config(); /* USER CODE BEGIN SysInit */ #if BACKEND_PERIPERHALS == 1 #if (TRAP_DIV_BY_ZERO_HARD_FAULT == 1 && DEBUG_NMI_FAULTS == 1) SCB->CCR |= 0x10; // enable div-by-0 trap #endif /* Enable the Backup System and VBat parameters */ __HAL_RCC_BKPRAM_CLK_ENABLE(); HAL_PWREx_DisableBatteryCharging(); HAL_PWREx_EnableBkUpReg(); HAL_PWR_EnableBkUpAccess(); /* Enable Back up SRAM */ /* Enable write access to Backup domain */ PWR->CR1 |= PWR_CR1_DBP; while((PWR->CR1 & PWR_CR1_DBP) == RESET) { } #endif /* USER CODE END SysInit */ /* Initialize all configured peripherals */ MX_CRC_Init(); MX_GPIO_Init(); MX_DMA2D_Init(); MX_LTDC_Init(); MX_I2C4_Init(); MX_OCTOSPI1_Init(); MX_TouchGFX_Init(); /* USER CODE BEGIN 2 */ #if BACKEND_PERIPERHALS == 1 MX_DMA_Init(); MX_TIM5_Init(); #if ADC2_ENABLED == 1 MX_ADC2_Init(); MX_TIM3_Init(); #endif MX_CRC_Init(); MX_I2C1_Init(); #if OP_AMPS_ENABLED == 1 MX_OPAMP1_Init(); MX_OPAMP2_Init(); #endif MX_RNG_Init(); MX_RTC_Init(); ... /** * @brief System Clock Configuration * @retval None */ void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0}; /** Supply configuration update enable */ HAL_PWREx_ConfigSupply(PWR_DIRECT_SMPS_SUPPLY); /** Configure the main internal regulator output voltage */ __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE0); while(!__HAL_PWR_GET_FLAG(PWR_FLAG_VOSRDY)) {} /** Configure LSE Drive Capability */ // __HAL_RCC_BKPRAM_CLK_ENABLE(); // // HAL_PWREx_DisableBatteryCharging(); // HAL_PWREx_EnableBkUpReg(); // HAL_PWR_EnableBkUpAccess(); // // __HAL_RCC_LSEDRIVE_CONFIG(RCC_LSEDRIVE_LOW); /** Macro to configure the PLL clock source */ __HAL_RCC_PLL_PLLSOURCE_CONFIG(RCC_PLLSOURCE_HSE); /** Initializes the RCC Oscillators according to the specified parameters * in the RCC_OscInitTypeDef structure. */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI48|RCC_OSCILLATORTYPE_HSI |RCC_OSCILLATORTYPE_LSI|RCC_OSCILLATORTYPE_HSE |RCC_OSCILLATORTYPE_LSE; RCC_OscInitStruct.HSEState = RCC_HSE_ON; RCC_OscInitStruct.LSEState = RCC_LSE_ON; RCC_OscInitStruct.HSIState = RCC_HSI_DIV2; RCC_OscInitStruct.HSICalibrationValue = 0; RCC_OscInitStruct.LSIState = RCC_LSI_ON; RCC_OscInitStruct.HSI48State = RCC_HSI48_ON; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLM = 12; RCC_OscInitStruct.PLL.PLLN = 280; RCC_OscInitStruct.PLL.PLLP = 2; RCC_OscInitStruct.PLL.PLLQ = 2; RCC_OscInitStruct.PLL.PLLR = 2; RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_1; RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE; RCC_OscInitStruct.PLL.PLLFRACN = 0; 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_CLOCKTYPE_D3PCLK1|RCC_CLOCKTYPE_D1PCLK1; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV2; RCC_ClkInitStruct.APB3CLKDivider = RCC_APB3_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV1; RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV1; RCC_ClkInitStruct.APB4CLKDivider = RCC_APB4_DIV1; if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_3) != HAL_OK) { Error_Handler(); } PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_RTC|RCC_PERIPHCLK_LTDC |RCC_PERIPHCLK_RNG|RCC_PERIPHCLK_ADC |RCC_PERIPHCLK_I2C1|RCC_PERIPHCLK_I2C4 |RCC_PERIPHCLK_OSPI; PeriphClkInitStruct.PLL2.PLL2M = 24; PeriphClkInitStruct.PLL2.PLL2N = 266; PeriphClkInitStruct.PLL2.PLL2P = 2; PeriphClkInitStruct.PLL2.PLL2Q = 2; PeriphClkInitStruct.PLL2.PLL2R = 2; PeriphClkInitStruct.PLL2.PLL2RGE = RCC_PLL2VCIRANGE_0; PeriphClkInitStruct.PLL2.PLL2VCOSEL = RCC_PLL2VCOMEDIUM; PeriphClkInitStruct.PLL2.PLL2FRACN = 0; PeriphClkInitStruct.PLL3.PLL3M = 24; PeriphClkInitStruct.PLL3.PLL3N = 201; PeriphClkInitStruct.PLL3.PLL3P = 2; PeriphClkInitStruct.PLL3.PLL3Q = 2; PeriphClkInitStruct.PLL3.PLL3R = 41; PeriphClkInitStruct.PLL3.PLL3RGE = RCC_PLL3VCIRANGE_0; PeriphClkInitStruct.PLL3.PLL3VCOSEL = RCC_PLL3VCOMEDIUM; PeriphClkInitStruct.PLL3.PLL3FRACN = 5462; PeriphClkInitStruct.OspiClockSelection = RCC_OSPICLKSOURCE_PLL2; PeriphClkInitStruct.RngClockSelection = RCC_RNGCLKSOURCE_HSI48; PeriphClkInitStruct.I2c123ClockSelection = RCC_I2C123CLKSOURCE_D2PCLK1; PeriphClkInitStruct.I2c4ClockSelection = RCC_I2C4CLKSOURCE_D3PCLK1; PeriphClkInitStruct.AdcClockSelection = RCC_ADCCLKSOURCE_PLL2; PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSE; if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) { Error_Handler(); } HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_HSI, RCC_MCODIV_1); }

1
投票
该代码工作正常。 ICAN删除主电源,时钟和备用RAM不断滴答。

仅通过您的代码,我也遇到了类似的问题。 在您的代码中是问题。

sAlarm.AlarmTime.StoreOperation = RTC_STOREOPERATION_RESET;
应该遵循

1
投票

在IOC文件中,请在RTC中进行更改存储操作设置以设置。 然后输入mx_rtc_init函数。

@

jongokbaek

的答案是正确的。您可以将随机代码存储在RTC备份寄存器中,并在重置后检查其是否仍然有效。但是我无法打电话给我无法打断警报的工作。

0
投票

HAL_RTC_SetAlarm_IT()

	

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.