cancel
Showing results for 
Search instead for 
Did you mean: 

How to properly configure a RTC clock?

BBart.16
Associate II

Have some problem with my code. CLock works too fast(about 20%). no difference between built-in oscillator, or crystal. And counts wrong(1, 2, 3...9, 16, then again 9 normal, and jump 6 up).

Heres my code:

#include "main.h"

#include "an_disp.h"

#include "an_disp.c"

#include <string.h>

RTC_HandleTypeDef hrtc;

TIM_HandleTypeDef htim14;

uint8_t hr;

uint8_t mn;

uint8_t sc;

char buffer[10];

void SystemClock_Config(void);

static void MX_GPIO_Init(void);

static void MX_TIM14_Init(void);

static void MX_RTC_Init(void);

void sec(void) {

   if (sc % 2 == 0) {

      HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_SET);

   }

   else if (sc % 2== 1) {

      HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1, GPIO_PIN_RESET);

   }

}

int main(void)

{

 HAL_Init();

 SystemClock_Config();

 MX_GPIO_Init();

 MX_TIM14_Init();

 MX_RTC_Init();

   HAL_Delay(50);

   lcd_init();

   RTC_TimeTypeDef RTC_Time;

   HAL_RTC_GetTime(&hrtc, &RTC_Time, RTC_FORMAT_BCD);

   hr = RTC_Time.Hours;

   mn = RTC_Time.Minutes;

   sc = RTC_Time.Seconds;

   HAL_Delay(4000);

   HAL_RTC_SetTime(&hrtc, &RTC_Time, RTC_FORMAT_BCD);

   while (1) {

      lcd_locate(0, 0);

      lcd_str("czesc2");

      HAL_RTC_GetTime(&hrtc, &RTC_Time, RTC_FORMAT_BCD);

      hr = RTC_Time.Hours;

      mn = RTC_Time.Minutes;

      sc = RTC_Time.Seconds;

      sec();

      sprintf(buffer, "%d:%d:%d", hr, mn, sc);

      lcd_locate(0, 1);

      lcd_str(buffer);

   }

}

void SystemClock_Config(void)

{

 RCC_OscInitTypeDef RCC_OscInitStruct = {0};

 RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

 RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};

 RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI|RCC_OSCILLATORTYPE_HSE;

 RCC_OscInitStruct.HSEState = RCC_HSE_ON;

 RCC_OscInitStruct.LSIState = RCC_LSI_ON;

 RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;

 if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)

 {

   Error_Handler();

 }

 RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK

                             |RCC_CLOCKTYPE_PCLK1;

 RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSE;

 RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV2;

 RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;

 if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)

 {

   Error_Handler();

 }

 PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_RTC;

 PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_LSI;

 if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)

 {

   Error_Handler();

 }

}

static void MX_RTC_Init(void)

{

 RTC_TimeTypeDef sTime = {0};

 RTC_DateTypeDef sDate = {0};

 RTC_AlarmTypeDef sAlarm = {0};

 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;

 if (HAL_RTC_Init(&hrtc) != HAL_OK)

 {

   Error_Handler();

 }

 sTime.Hours = 0x11;

 sTime.Minutes = 0x10;

 sTime.Seconds = 0x30;

 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();

 }

 sAlarm.AlarmTime.Hours = 0x0;

 sAlarm.AlarmTime.Minutes = 0x0;

 sAlarm.AlarmTime.Seconds = 0x0;

 sAlarm.AlarmTime.SubSeconds = 0x0;

 sAlarm.AlarmTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE;

 sAlarm.AlarmTime.StoreOperation = RTC_STOREOPERATION_RESET;

 sAlarm.AlarmMask = RTC_ALARMMASK_NONE;

 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();

 }

}

static void MX_TIM14_Init(void)

{

 htim14.Instance = TIM14;

 htim14.Init.Prescaler = 7999;

 htim14.Init.CounterMode = TIM_COUNTERMODE_UP;

 htim14.Init.Period = 999;

 htim14.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;

 htim14.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;

 if (HAL_TIM_Base_Init(&htim14) != HAL_OK)

 {

   Error_Handler();

 }

}

static void MX_GPIO_Init(void)

{

 GPIO_InitTypeDef GPIO_InitStruct = {0};

 __HAL_RCC_GPIOF_CLK_ENABLE();

 __HAL_RCC_GPIOA_CLK_ENABLE();

 __HAL_RCC_GPIOB_CLK_ENABLE();

 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_1|GPIO_PIN_7|GPIO_PIN_9|GPIO_PIN_10

                         |GPIO_PIN_13|GPIO_PIN_14, GPIO_PIN_RESET);

 HAL_GPIO_WritePin(GPIOB, GPIO_PIN_1, GPIO_PIN_RESET);

 GPIO_InitStruct.Pin = GPIO_PIN_1|GPIO_PIN_7|GPIO_PIN_9|GPIO_PIN_10

                         |GPIO_PIN_13|GPIO_PIN_14;

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

 GPIO_InitStruct.Pin = GPIO_PIN_1;

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

}

void Error_Handler(void)

{

}

#ifdef USE_FULL_ASSERT

void assert_failed(char *file, uint32_t line)

{

}

#endif

3 REPLIES 3

> CLock works too fast(about 20%). no difference between built-in oscillator,

You mean LSI? That's supposed to be very imprecise. Read datasheet

> or crystal.

That would mean a terribly wrong crystal, or, more properly, LSE is not running and RTC fell back to LSI, if you have clock security switched on on LSE (you did not care to tell us the STM32 model you are using). Are you sure LSE is connected properly, set up properly and working? Is this a known good board (such as a Disco or a Nucleo)?

> And counts wrong(1, 2, 3...9, 16, then again 9 normal, and jump 6 up).

Maybe you misinterpret what BCD format is. I don't use Cube.

JW

turboscrew
Senior III

At least the system_clock() selects LSI.

turboscrew
Senior III

BTW, from stm32f4xx_hal_rtc.c:

" * @note You must call HAL_RTC_GetDate() after HAL_RTC_GetTime() to unlock the values 

 *       in the higher-order calendar shadow registers to ensure consistency between the time and date values.

 *       Reading RTC current time locks the values in calendar shadow registers until current date is read. "