Skip to main content
Visitor II
March 31, 2025
Question

RTC Alarm Minutes and Seconds on STM32U575VI

  • March 31, 2025
  • 1 reply
  • 353 views

Hi,

I'm currently working on an application for a STM32U575VI6. It's supposed to generate an interruption every 4 minutes and 9 seconds. However, it works only when I mask the seconds, and only work with minutes. The moment I try configure both and enable them, it doesn't activates. Do you know why ? The function that configures the alarm is at line 527.

/* USER CODE BEGIN Header */
/**
 ******************************************************************************
 * @file : main.c
 * @brief : Main program body
 ******************************************************************************
 * @attention
 *
 * Copyright (c) 2024 STMicroelectronics.
 * All rights reserved.
 *
 * This software is licensed under terms that can be found in the LICENSE file
 * in the root directory of this software component.
 * If no LICENSE file comes with this software, it is provided AS-IS.
 *
 ******************************************************************************
 */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "adc.h"
#include "i2c.h"
#include "icache.h"
#include "memorymap.h"
#include "rtc.h"
#include "usart.h"
#include "gpio.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "fm24cl64.h"
#include "RA08.h"
#include <stdio.h>
#include <stdlib.h>

/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
#define AN_INTERVAL		2
#define DIG_INTERVAL	10
#define ANA_WAIT		5000
/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/

/* USER CODE BEGIN PV */
uint8_t alarmFlag = 0;
uint8_t flagAlarmA = 0;
uint8_t flagAlarmB = 0;

/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */

void adjustAlarm(RTC_HandleTypeDef *hrtc, RTC_AlarmTypeDef *sAlarm, uint8_t interval);
void saveAnalogAvg(I2C_HandleTypeDef *hi2c2, uint32_t avgAna, uint16_t eepromAddress);

uint32_t ADC_ConvertRank3(ADC_HandleTypeDef *hadc);
uint32_t ADC_ConvertRank4(ADC_HandleTypeDef *hadc);

HAL_StatusTypeDef transmitAllData(RA08_Handle *ra08h, I2C_HandleTypeDef *hi2c2, uint8_t counterAdd);
/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */


/* USER CODE END 0 */

/**
 * @brief The application entry point.
 * @retval int
 */
int main(void)
{
 /* USER CODE BEGIN 1 */

																																																																												uint8_t error101[11] = "ERROR101\r\n";
 uint8_t error201[11] = "ERROR201\r\n";
 uint8_t error202[11] = "ERROR202\r\n";

 uint32_t avgAna3 = 0;
 uint32_t avgAna4 = 0;
 uint32_t analog_ch3 = 0;
 uint32_t analog_ch4 = 0;
 uint32_t anValue3[25] = {0};
 uint32_t anTimer;
 //uint32_t digValue[25] = {0};
 uint16_t eepromAddressAn3 = 0;
 uint8_t joinFlag = 0;
 //uint8_t anInterval = 1; HOW MANY MINUTES WITHIN THE INTERVAL BETWEEN LECTURES
 //uint8_t digInterval = 1;
 uint8_t anCounter = 0;
 uint8_t anCounterAdd = 0;
 //uint8_t digCounter = 0;


 char cal_end[15] = "CONFIG. MODE\r\n";
 char uart_buffer[50];
 char packetToSend[13] = "43770";
 char hora_char[3] = {0};
 char minutos_char[3] = {0};

 RA08_Handle ra08h;

 RTC_AlarmTypeDef alarmA;
 RTC_AlarmTypeDef alarmB;


 /* 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_MEMORYMAP_Init();
 MX_ICACHE_Init();
 MX_USART1_UART_Init();
 MX_USART2_UART_Init();
 MX_I2C2_Init();
 MX_RTC_Init();
 MX_ADC1_Init();
 /* USER CODE BEGIN 2 */

 /*
 * LED1_PIN = VERDE
 * LED2_PIN = ROJO
 */

 HAL_Delay(5000);

 /*- PARA OBTENER LA HORA DEBEMOS CREAR UN OBJETO DE TIPO RTC_TIMETYPEDEF PARA ALMACENARLO. LUEGO SE PUEDE PASAR A CHAR MEDIANTE ITOA, PARA SU VISUALIZACION -*/

 /*
	HAL_RTC_GetTime(&hrtc, &currentTime, FORMAT_BIN);
	HAL_RTC_GetDate(&hrtc, &currentDate, FORMAT_BIN);

	itoa(currentTime.Hours, hora_char, 10);
	itoa(currentTime.Minutes, minutos_char, 10);
	*/

 // ENTER MANUALLY LORAWAN PARAMETERS
 if(HAL_GPIO_ReadPin(GPIOB, PROG_PIN_Pin) == GPIO_PIN_RESET)
 {

	 RA08_Restore(&ra08h, &huart1, &huart2);


	 HAL_UART_Transmit(&huart2, (uint8_t*)cal_end, strlen(cal_end), 500);
	 RA08_Config(&ra08h, &huart2, &hi2c2);

	 while(1)
	 {
		 // WHEN FINISHED, THE RED LED WILL START TO BLINK
		 HAL_GPIO_TogglePin(GPIOC, LED2_Pin);
		 HAL_Delay(500);
	 }
 }

 /* MODULE CONFIG.--------------------------*/

 if(RA08_Init(&ra08h, &huart1, &hi2c2) == HAL_ERROR)
 {
	 // IT BLOCKS IF WAS NOT PREVIOUSLY CONFIGURED
	 HAL_UART_Transmit(&huart2, error101, sizeof(error101), UART_TIMEOUT);

	 while(1)
	 {
		 HAL_GPIO_TogglePin(GPIOC, LED1_Pin);
		 HAL_Delay(500);
	 }
 }

 RA08_SetCLASS(&ra08h, &huart2);
 RA08_SetJoinMode(&ra08h, &huart2);
 RA08_SetWindowsParam(&ra08h, &huart2);
 RA08_SetFreqBAND(&ra08h, &huart2);
 RA08_SetDevEUI(&ra08h, &huart2);
 RA08_SetAppEUI(&ra08h, &huart2);
 RA08_SetAppKEY(&ra08h, &huart2);
 RA08_SetADR(&ra08h, &huart2);

 /*-- SET THE SPREADING FACTOR IF THE ADR IS OFF --*/

 if (ra08h.adr[0] == 0) RA08_SetSF(&ra08h, &huart2);

 RA08_SetULDLMODE(&ra08h, &huart2);
 RA08_SetConfirm(&ra08h, &huart2);

 RA08_SaveParam(&ra08h, &huart2);

 /*-------------------------*/

 /*-- JOIN LORAWAN SERVER --*/

 joinFlag = RA08_JoinNET(&ra08h, &huart2);

 if (joinFlag == HAL_ERROR)
 {
	 // LORA MODULE DID NOT RESPOND AFTER AT COMMAND
	 HAL_UART_Transmit(&huart2, error201, sizeof(error201), UART_TIMEOUT);
 }
 else if (joinFlag == HAL_TIMEOUT)
 {
	 // DEVICE WAS UNABLE TO JOIN THE SERVER BECAUSE IT REACHED NUMBER OF TR
	 HAL_UART_Transmit(&huart2, error202, sizeof(error202), UART_TIMEOUT);
 }

 RA08_SendPacket(&ra08h, &huart2, packetToSend);
 // RA08_ReadBuffer(&ra08h, &huart2, downlinkBuff);

 /*- THE DOWNLINK PACKET KEEPS TH HOUR UPDATED, AND AN OPTIONAL COMMAND, THIS FUNCTION SAVES THE HOUR IN currentTime TO SAVE IT LATER IN THE RTC -*/

 // RA08_exeCommand(&currentTime, &huart2, downlinkBuff);

 // HAL_RTC_SetTime(&hrtc, &currentTime, RTC_FORMAT_BIN);

 /* - WE GET THE VALUE OF THE ALARM PREVIOUSLY SET, AND CHANGE THE TIME OF THE ALARM BY current.Time + alarmInterval. */

 HAL_RTC_GetAlarm(&hrtc, &alarmA, RTC_ALARM_A, FORMAT_BIN);
 HAL_RTC_GetAlarm(&hrtc, &alarmB, RTC_ALARM_B, FORMAT_BIN);

 adjustAlarm(&hrtc, &alarmA, AN_INTERVAL);
 adjustAlarm(&hrtc, &alarmB, DIG_INTERVAL);

 HAL_ADC_Stop(&hadc1);
 HAL_ADCEx_Calibration_Start(&hadc1, ADC_CALIB_OFFSET_LINEARITY, ADC_SINGLE_ENDED);
 HAL_Delay(1000);

 anTimer = HAL_GetTick();
 /* USER CODE END 2 */

 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {

	 /*- GetTime Y GetDate DEBEN IR JUNTOS EN ESTE ORDEN -*/

	 /*
	 HAL_RTC_GetTime(&hrtc, &currentTime, FORMAT_BIN);
	 HAL_RTC_GetDate(&hrtc, &currentDate, FORMAT_BIN);

	 itoa(currentTime.Hours, hora_char, 10);
	 itoa(currentTime.Minutes, minutos_char, 10);
	 */

	 if(HAL_GetTick() - anTimer >= ANA_WAIT)
	 {

		 /*- analog alarm */

		 HAL_RTC_GetAlarm(&hrtc, &alarmA, RTC_ALARM_A, FORMAT_BIN);
		 adjustAlarm(&hrtc, &alarmA, AN_INTERVAL);

	 // TURN ON DC/DC CONVERTER GATE

	 // AN 1 ROUTINE

	 analog_ch3 = ADC_ConvertRank3(&hadc1);
		 anValue3[anCounter] = analog_ch3;
	 // Convertir el valor a texto para UART
	 sprintf(uart_buffer, "\r\nADC Ch3 Value: %lu\r\n", analog_ch3);
	 // Transmitir por UART
	 HAL_UART_Transmit(&huart2, (uint8_t*)uart_buffer, strlen(uart_buffer), 500);

	 /*
	 *
	 * HERE GOES AN 2 ROUTINE
	 *
	 */

	 anCounter ++; // IT INCREASES EACH LECTURE, USED TO KNOW THE SIZE OF THE PAGE

	 anTimer = HAL_GetTick();

		 /*
		 * 	TAREAS PENDIENTES:
		 *
		 * 		1. ANADIR LOS DATOS EN UN ARRAY, O EN UNA EEPROM.
		 * 		2. REALIZAR LA MEDIA Y ALMACENARLA EN LA EEPROM, O ENVIARLA A LA BASE DE DATOS
		 * 		3. GESTIONAR LAS ALARMAS, PUESTO QUE HAY VARIOS TIPOS DE EVENTOS, PERO SOLAMENTE DOS ALARMAS
		 *
		 */

	 }

	 if(flagAlarmA == 1)
	 {

		 for(int x = 0; x <= anCounter; x++)
		 {
			 avgAna3 = avgAna3 + anValue3[x];
		 }

		 avgAna3 = avgAna3 / anCounter; // AVERAGE OF ANALOG 3 LECTURES

		 saveAnalogAvg(&hi2c2, avgAna3, eepromAddressAn3);

		 eepromAddressAn3 = eepromAddressAn3 + 7; // PARA LA TRAMA DE DATOS QUE VAMOS A ENVIAR, NECESITAMOS 6 DIRECCIONES DE DATOS DE LA EEPROM

		 anCounter = 0;
		 avgAna3 = 0;
		 memset(anValue3, 0, sizeof(anValue3 ));
		 anCounterAdd ++;

		 adjustAlarm(&hrtc, &alarmA, AN_INTERVAL);

		 flagAlarmA = 0;
	 }

	 if(flagAlarmB == 1)
	 {

		 transmitAllData(&ra08h, &hi2c2, anCounterAdd);

		 /*
		 * DIGITAL LECTURE
		 */

/*- EN TEORIA, adjustAlarm será innecesaria, porque esta alarma será cada 24 horas.-*/
		 adjustAlarm(&hrtc, &alarmB, DIG_INTERVAL);

		 anCounterAdd = 0;

		 flagAlarmB = 0;

	 }

	 // Retardo para evitar saturar la transmisión

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

 /** Configure the main internal regulator output voltage
 */
 if (HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE4) != HAL_OK)
 {
 Error_Handler();
 }

 /** Initializes the CPU, AHB and APB buses clocks
 */
 RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI|RCC_OSCILLATORTYPE_LSI
 |RCC_OSCILLATORTYPE_MSI;
 RCC_OscInitStruct.HSIState = RCC_HSI_ON;
 RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
 RCC_OscInitStruct.LSIState = RCC_LSI_ON;
 RCC_OscInitStruct.MSIState = RCC_MSI_ON;
 RCC_OscInitStruct.MSICalibrationValue = RCC_MSICALIBRATION_DEFAULT;
 RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_4;
 RCC_OscInitStruct.LSIDiv = RCC_LSI_DIV1;
 RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
 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_PCLK3;
 RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_MSI;
 RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
 RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
 RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
 RCC_ClkInitStruct.APB3CLKDivider = RCC_HCLK_DIV1;

 if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
 {
 Error_Handler();
 }
}

/* USER CODE BEGIN 4 */
void saveAnalogAvg(I2C_HandleTypeDef *hi2c2, uint32_t avgAna, uint16_t eepromAddress)
{
	RTC_TimeTypeDef currentTime;
	RTC_DateTypeDef currentDate;

	uint8_t anaWritingBuffer[4] = {0};

	HAL_RTC_GetTime(&hrtc, &currentTime, FORMAT_BIN);
	HAL_RTC_GetDate(&hrtc, &currentDate, FORMAT_BIN);

	anaWritingBuffer[0] = currentTime.Hours;
	anaWritingBuffer[1] = currentTime.Minutes;
	anaWritingBuffer[2] = 0; // IT CAN BE C00, OR 01
	anaWritingBuffer[3] = (avgAna >> 24) & 0xFF;
	anaWritingBuffer[4] = (avgAna >> 16) & 0xFF;
	anaWritingBuffer[5] = (avgAna >> 8) & 0xFF;
	anaWritingBuffer[6] = avgAna & 0xFF;

	FM24CL_WRITE(hi2c2, FM24_1, eepromAddress, anaWritingBuffer, sizeof(anaWritingBuffer));

}
uint32_t ADC_ConvertRank3(ADC_HandleTypeDef *hadc)
{

	/*
	 * ESTA FUNCION NOS PERMITE REALIZAR VARIAS LECTURAS ANALOGICAS, A TRAVES DE DIFERENTES CANALES SIN USAR DMA.
	 * HABRA UNA FUNCION POR CADA CANAL, EN CADA CUAL SE ASIGNARA EL RANK 1 AL CANAL CORRESPONDIENTE, PARA MAXIMIZAR SU PRIORIDAD
	 */

	ADC_ChannelConfTypeDef sConfig = {0};

	sConfig.Channel = ADC_CHANNEL_3;
	sConfig.Rank = ADC_REGULAR_RANK_2; // PARA QUE AMBOS CANALES FUNCIONEN, DEBEN AMBOS PERMANECER EN RANK 2
	sConfig.SamplingTime = ADC_SAMPLETIME_5CYCLE;
	sConfig.SingleDiff = ADC_SINGLE_ENDED;
	sConfig.OffsetNumber = ADC_OFFSET_NONE;
	sConfig.Offset = 0;

	if (HAL_ADC_ConfigChannel(hadc, &sConfig) != HAL_OK)
	{
		Error_Handler();
	}

	HAL_ADC_Start(hadc);

	HAL_ADC_PollForConversion(hadc, 100);
	uint32_t adcval = HAL_ADC_GetValue(hadc);

	HAL_ADC_Stop(&hadc1);


	return adcval;

}

uint32_t ADC_ConvertRank4(ADC_HandleTypeDef *hadc)
{

	ADC_ChannelConfTypeDef sConfig = {0};

	sConfig.Channel = ADC_CHANNEL_4;
	sConfig.Rank = ADC_REGULAR_RANK_2;
	sConfig.SamplingTime = ADC_SAMPLETIME_5CYCLE;
	sConfig.SingleDiff = ADC_SINGLE_ENDED;
	sConfig.OffsetNumber = ADC_OFFSET_NONE;
	sConfig.Offset = 0;

	if (HAL_ADC_ConfigChannel(hadc, &sConfig) != HAL_OK)
	{
		Error_Handler();
	}

	HAL_ADC_Start(hadc);

	HAL_ADC_PollForConversion(hadc, 100);
	uint32_t adcval = HAL_ADC_GetValue(hadc);

	HAL_ADC_Stop(&hadc1);


	return adcval;

}

HAL_StatusTypeDef transmitAllData(RA08_Handle *ra08h, I2C_HandleTypeDef *hi2c2, uint8_t counterAdd)
{
	HAL_StatusTypeDef errorFlag;

	char packetToSend[60] = {0};

	uint8_t bufferSend[60] = {0};
	uint8_t i = 0; // Var for iteration
	uint16_t address = 0;


	for(i = 0; i < counterAdd; i++)
	{
		address = 7 * i;
		errorFlag = FM24CL_RANDOM_READ(hi2c2, FM24_1, address, &bufferSend[address], 7);

		itoa(bufferSend[i], &packetToSend[i], 10);
	}


	RA08_SendPacket(ra08h, ra08h->uart, packetToSend);

	return errorFlag;

}

void adjustAlarm(RTC_HandleTypeDef *hrtc, RTC_AlarmTypeDef *sAlarm, uint8_t interval)
{

	 /*
	 * ACTUALIZA EL TIEMPO DE ALARMA SEGUN EL INTERVALO INDICADO POR EL USUARIO Y LA HORA ACTUAL
	 * AÑADIR SEGUNDOS TAMBIÉN. DOS ALARMAS NO PUEDEN COINCIDIR.
	 * E.G. ALARMa AT 01:59, ALARMb AT 01:57
	 *
	 */

	 uint8_t anAlarm;

	 RTC_DateTypeDef currentDate;
	 RTC_TimeTypeDef currentTime;

	 HAL_RTC_GetTime(hrtc, &currentTime, FORMAT_BIN);
	 HAL_RTC_GetDate(hrtc, &currentDate, FORMAT_BIN);

	 anAlarm = interval + currentTime.Minutes;

	 if(anAlarm > 59)
	 {
		 anAlarm = anAlarm - 59;
	 }
	 sAlarm->AlarmTime.Minutes = anAlarm;

/*- PASAMOS DE 0 SEGUNDOS A 9. ESTO SE HACE PARA EVITAR QUE SE SOLAPEN LAS ALARMAS ENTRE ELLAS, ESPECIALMENTE CUANDO UNA ES CADA MINUTO, Y LA OTRA ES CADA DOS MINUTOS -*/
	 /*
	 if(interval >= 2)
	 {

		 sAlarm->AlarmTime.Seconds = 7;
	 }
	 */
	 HAL_RTC_SetAlarm_IT(hrtc, sAlarm, FORMAT_BIN);

}

void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc)
{

	flagAlarmA = 1;
	HAL_RTC_DeactivateAlarm(hrtc, RTC_ALARM_A);

	/*
	 * CALLBACK FUNCTION FOR WHEN THE ALARM GOES OFF
	 *
	 * 1 SET THE ALARM AGAIN
	 * 2 CHANGE THE ALARM TIME
	 *
	 * e.g.
	 *
	 *	ALARMA DE 1 SEGUNDO, QUE SE REEDITA CONSTANTEMENTE
	 *
	 * RTC_AlarmTypeDef sAlarm;
	 * HAL_RTC_GetAlarm(hrtc,&sAlarm,RTC_ALARM_A,FORMAT_BIN);
	 *
	 * NECESITAMOS ALMACENAR LOS PARAMETROS DE RTC ALARM A EN UNA STRUCT DE TIPO RTC_AlarmTypeDef
	 *
	 * if(sAlarm.AlarmTime.Seconds>58)
	 * {
	 * 		sAlarm.AlarmTime.Seconds=0;
	 *
	 * }
	 * else
	 * {
	 * sAlarm.AlarmTime.Seconds=sAlarm.AlarmTime.Seconds+1;
	 * }
	 *
	 * VOLVEMOS A COLOCAR LA ALARMA CON INTERRUPCION
	 *
	 * while(HAL_RTC_SetAlarm_IT(hrtc, &sAlarm, FORMAT_BIN)!=HAL_OK){}
	 *
	 *
	 */

	//alarmFlag = 1;

}

void HAL_RTCEx_AlarmBEventCallback(RTC_HandleTypeDef *hrtc)
{
	flagAlarmB = 1;
	HAL_RTC_DeactivateAlarm(hrtc, RTC_ALARM_B);

	/*
	 * WRITE YOUR CODE HERE
	 */

}
/* 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 can add his own implementation to report the HAL error return state */
 __disable_irq();
 while (1)
 {
 }
 /* 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.
 * @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 CODE BEGIN 6 */
 /* 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) */
 /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

  

    This topic has been closed for replies.

    1 reply

    Technical Moderator
    April 8, 2025

    Hello @oliverTelecom and welcome to the community;

     

    I recommend to look at the Getting started with RTC - stm32mcu wiki and check the RTC initialization.

    Then, you can based on STM32CubeMX toolchain to use the alarm masks to ignore days, hours as mentioned in this wiki.

     

    I hope this help you.

    Thank you.

    Kaouthar