2017-04-04 6 views
3

Ich versuche, die RTC auf einer STM32F469I-DISCO-Platine zu initialisieren. Da ich noch lerne, habe ich versucht, mit der HAL-API zu spielen, die es mir ermöglicht, einige Projekte zu erreichen, bis ich genug Verständnis für diesen Mikrocontroller habe, um direkt mit Registern zu spielen.STM32 RTC-Timeout während der Initialisierung

Wie auch immer, mein Code verwendet die STM32F469I-DISCO-Vorlage von CubeF4, die es ermöglicht, direkt die HAL-Schicht und den Systemtakt (180 MHz über den 8 MHz HSE-Oszillator) zu laden.

Um die RTC zu initialisieren, befolgte ich die Anweisungen in der UM1725 : Description of STM32F4 HAL and LL drivers. Seite 715, Abschnitt 55.2.4 haben Sie Anweisungen zur Verwendung der HAL_RTC-API.

Und der erste Punkt besagt, dass es notwendig ist, den "RTC Domain Access" zu aktivieren. Dieser Punkt wird im obigen Abschnitt erklärt (55.2.3, gleiche Seite).

Und ich tat, worum es gebeten wurde. Hier ist mein Code (vereinfacht, ich lasse nur den RTC Init Teil und System Clock Konfiguration):

#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 

Und es funktioniert nicht. Nachdem ich in die unterste Schicht gegraben habe, habe ich herausgefunden, wo es nicht funktioniert. Ich weiß einfach nicht warum.

Der Aufruf HAL_RTC_Init() gibt einen HAL_ERROR-Status zurück. Dieser HAL_ERROR wird angezeigt, weil HAL_RTC_Init() RTC_EnterInitMode() aufruft und einen HAL_TIMEOUT-Status zurückgibt, weil eine Bedingung während der erwarteten Zeit nicht erreicht wird. Hier sind die Funktionen:

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; 
    } 
} 

und:

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; 
} 

Also, wenn ich gut untersucht, das Problem ist, dass die Bedingung: hrtc-> Instanz-> ISR & RTC_ISR_INITF == (uint32_t) RESET ist die ganze Zeit wahr ( ) (da die TIMEOUT-Bedingung ausgelöst wird). Das Ting, das ich nicht verstehe, ist laut der obigen Funktion (EnterInitMode), RTC_ISR_INITF und ISR Variablen eindeutig zu definieren und somit ist der bitweise Operation Wert nicht 0 (RESET).

Die "ISR" in der Funktion direkt definiert ist und RTC_INIT_MASK (#define mit 0xFFFFFFFF Wert in stm32f4xx_hal_rtc.h)

Die "RTC_ISR_INITF" ist ein Makro: (0x1U < < RTC_ISR_INITF_Pos) wobei RTC_ISR_INITF_Pos ist 6U (#define) definiert in stm32f469xx.h

Bin ich falsch, wenn ich sage, dass die "&" Operation ist nicht 0?

Haben Sie eine Idee, warum ich diese TIMEOUT-Bedingung ausgelöst habe?

Vielen Dank im Voraus!

Antwort

3

Ich löste mein Problem nach einer guten Nacht. Ich habe vergessen, die LSE Clock in meiner SystemClock_Config() Routine zu initialisieren ... Ich füge einfach den folgenden Code in SystemClock_Config() hinzu.

Ich testete danach mit STM Studio, um die Entwicklung meiner Variablen zu visualisieren. Und es hat gut funktioniert (vorher nicht).

Entschuldigung für die Unannehmlichkeiten.

Verwandte Themen