cancel
Showing results for 
Search instead for 
Did you mean: 

RTC Alarm Minutes and Seconds on STM32U575VI

oliverTelecom
Associate

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 */
View more

  

0 REPLIES 0