STM32F469I-DISCO 보드에서 RTC를 초기화하려고합니다. 내가 아직 배우기 때문에 HAL API로 게임을 시도했는데, 그 때까지 레지스터로 직접 플레이 할 수있는이 마이크로 컨트롤러에 대한 충분한 이해를 얻을 때까지 몇 가지 프로젝트를 수행 할 수있었습니다.STM32 RTC 초기화 중 타임 아웃
어쨌든 내 코드는 HAL 레이어와 시스템 클럭 (8 MHz HSE 발진기를 통해 180 MHz)을 직접로드 할 수있는 CubeF4의 STM32F469I-DISCO 템플릿을 사용합니다.
RTC를 초기화하기 위해 UM1725 : Description of STM32F4 HAL and LL drivers에 제공된 지침을 따랐습니다. 페이지 715, 섹션 55.2.4에는 HAL_RTC API를 사용하는 지침이 있습니다.
첫 번째 요점은 "RTC 도메인 액세스"를 활성화해야한다는 것입니다. 이 점은 위의 섹션에서 설명합니다 (55.2.3, 같은 페이지).
그리고 내가해야 할 일을했습니다. 여기에 내 코드 (단순화, 나는 단지 RTC Init 부분과 시스템 클럭 구성 만 남겼다.) :
#include "main.h"
RTC_HandleTypeDef rtcHandle;
RTC_InitTypeDef rtcInit;
RTC_TimeTypeDef rtcTime;
RTC_DateTypeDef rtcDate;
static void SystemClock_Config(void);
static void Error_Handler(void);
int main(void)
{
HAL_Init();
SystemClock_Config();
////////////////// RTC
HAL_PWR_EnableBkUpAccess();
__HAL_RCC_RTC_CONFIG(RCC_RTCCLKSOURCE_LSE);
__HAL_RCC_RTC_ENABLE();
rtcInit.HourFormat = RTC_HOURFORMAT_24;
rtcInit.AsynchPrediv = 0x7F;
rtcInit.SynchPrediv = 0xFF;
rtcInit.OutPut = RTC_OUTPUT_DISABLE;
rtcInit.OutPutPolarity = RTC_OUTPUT_POLARITY_HIGH;
rtcInit.OutPutType = RTC_OUTPUT_TYPE_OPENDRAIN;
rtcHandle.Instance = RTC;
rtcHandle.Init = rtcInit;
HAL_RTC_Init(&rtcHandle);
rtcTime.Hours = 12;
rtcTime.Minutes = 30;
rtcTime.Seconds = 40;
rtcDate.WeekDay = RTC_WEEKDAY_WEDNESDAY;
rtcDate.Month = RTC_MONTH_APRIL;
rtcDate.Date = 4;
rtcDate.Year= 17;
HAL_RTC_SetTime(&rtcHandle, &rtcTime, RTC_FORMAT_BCD);
while (1)
{
}
}
static void SystemClock_Config(void)
{
RCC_ClkInitTypeDef RCC_ClkInitStruct;
RCC_OscInitTypeDef RCC_OscInitStruct;
/* Enable Power Control clock */
__HAL_RCC_PWR_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
/* Enable HSE Oscillator and activate PLL with HSE as source */
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
#if defined(USE_STM32469I_DISCO_REVA)
RCC_OscInitStruct.PLL.PLLM = 25;
#else
RCC_OscInitStruct.PLL.PLLM = 8;
#endif /* USE_STM32469I_DISCO_REVA */
RCC_OscInitStruct.PLL.PLLN = 360;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLQ = 7;
RCC_OscInitStruct.PLL.PLLR = 6;
if(HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/* Enable the OverDrive to reach the 180 Mhz Frequency */
if(HAL_PWREx_EnableOverDrive() != HAL_OK)
{
Error_Handler();
}
RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
if(HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK)
{
Error_Handler();
}
}
/**
* @brief This function is executed in case of error occurrence.
* @param None
* @retval None
*/
static void Error_Handler(void)
{
/* User may add here some code to deal with this error */
while(1)
{
}
}
#ifdef USE_FULL_ASSERT
/**
* @brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* @param file: pointer to the source file name
* @param line: assert_param error line source number
* @retval None
*/
void assert_failed(uint8_t* file, uint32_t line)
{
/* User can add his own implementation to report the file name and line number,
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
/* Infinite loop */
while (1)
{
}
}
#endif
그리고 작동하지 않는다. 가장 낮은 레이어를 파고 들자 마자 작동하지 않는 부분을 찾아 낼 수있었습니다. 나는 이유를 모른다.
HAL_RTC_Init() 호출은 HAL_ERROR 상태를 반환합니다. 이 HAL_ERROR는 HAL_RTC_Init()이 RTC_EnterInitMode()를 호출하고 예상 된 시간 내에 조건이 달성되지 않기 때문에 HAL_TIMEOUT 상태를 반환하기 때문에 나타납니다.
HAL_StatusTypeDef HAL_RTC_Init(RTC_HandleTypeDef *hrtc)
{
/* Check the RTC peripheral state */
if(hrtc == NULL)
{
return HAL_ERROR;
}
/* Check the parameters */
assert_param(IS_RTC_HOUR_FORMAT(hrtc->Init.HourFormat));
assert_param(IS_RTC_ASYNCH_PREDIV(hrtc->Init.AsynchPrediv));
assert_param(IS_RTC_SYNCH_PREDIV(hrtc->Init.SynchPrediv));
assert_param (IS_RTC_OUTPUT(hrtc->Init.OutPut));
assert_param (IS_RTC_OUTPUT_POL(hrtc->Init.OutPutPolarity));
assert_param(IS_RTC_OUTPUT_TYPE(hrtc->Init.OutPutType));
if(hrtc->State == HAL_RTC_STATE_RESET)
{
/* Allocate lock resource and initialize it */
hrtc->Lock = HAL_UNLOCKED;
/* Initialize RTC MSP */
HAL_RTC_MspInit(hrtc);
}
/* Set RTC state */
hrtc->State = HAL_RTC_STATE_BUSY;
/* Disable the write protection for RTC registers */
__HAL_RTC_WRITEPROTECTION_DISABLE(hrtc);
/* Set Initialization mode */
if(RTC_EnterInitMode(hrtc) != HAL_OK)
{
/* Enable the write protection for RTC registers */
__HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
/* Set RTC state */
hrtc->State = HAL_RTC_STATE_ERROR;
return HAL_ERROR;
}
else
{
/* Clear RTC_CR FMT, OSEL and POL Bits */
hrtc->Instance->CR &= ((uint32_t)~(RTC_CR_FMT | RTC_CR_OSEL | RTC_CR_POL));
/* Set RTC_CR register */
hrtc->Instance->CR |= (uint32_t)(hrtc->Init.HourFormat | hrtc->Init.OutPut | hrtc->Init.OutPutPolarity);
/* Configure the RTC PRER */
hrtc->Instance->PRER = (uint32_t)(hrtc->Init.SynchPrediv);
hrtc->Instance->PRER |= (uint32_t)(hrtc->Init.AsynchPrediv << 16U);
/* Exit Initialization mode */
hrtc->Instance->ISR &= (uint32_t)~RTC_ISR_INIT;
hrtc->Instance->TAFCR &= (uint32_t)~RTC_TAFCR_ALARMOUTTYPE;
hrtc->Instance->TAFCR |= (uint32_t)(hrtc->Init.OutPutType);
/* Enable the write protection for RTC registers */
__HAL_RTC_WRITEPROTECTION_ENABLE(hrtc);
/* Set RTC state */
hrtc->State = HAL_RTC_STATE_READY;
return HAL_OK;
}
}
하고 : 여기서 함수되도록
HAL_StatusTypeDef RTC_EnterInitMode(RTC_HandleTypeDef* hrtc)
{
uint32_t tickstart = 0U;
/* Check if the Initialization mode is set */
if((hrtc->Instance->ISR & RTC_ISR_INITF) == (uint32_t)RESET)
{
/* Set the Initialization mode */
hrtc->Instance->ISR = (uint32_t)RTC_INIT_MASK;
/* Get tick */
tickstart = HAL_GetTick();
/* Wait till RTC is in INIT state and if Time out is reached exit */
while((hrtc->Instance->ISR & RTC_ISR_INITF) == (uint32_t)RESET)
{
if((HAL_GetTick() - tickstart) > RTC_TIMEOUT_VALUE)
{
return HAL_TIMEOUT;
}
}
}
return HAL_OK;
}
내가 좋게 조사하는 경우, 문제가되는 상태를 해당 : hrtc-> 인스턴스 -> ISR & RTC_ISR_INITF == (uint32_t) RESET은 항상 입니다 (TIMEOUT 조건이 발생했기 때문에). 내가 이해하지 못하는 것은 위의 함수 (EnterInitMode), RTC_ISR_INITF 및 ISR 변수에 따라 명확하게 정의 된 것으로 보이므로 비트 연산 값은 0 (RESET)이 아닙니다.
은 "ISR"직접 함수 정의 RTC_INIT_MASK
은 "RTC_ISR_INITF은"매크로이다 (stm32f4xx_hal_rtc.h에서 0xFFFFFFFF로 값 #DEFINE)이다 : (0x1U < < RTC_ISR_INITF_Pos) 여기서 RTC_ISR_INITF_Pos는 6U이며 (#define)
"&"작업이 0이 아니라고 말하는 것이 잘못 되었습니까?
이 TIMEOUT 조건이 발생하는 이유는 무엇입니까?
미리 감사드립니다.