int RTC_alarm_Init(uint8_t date, uint8_t month, uint8_t year, uint8_t hour, uint8_t minute, uint8_t sec) { //printf("%d %d %d %d %d %d\r\n",year, month, date, hour, minute, sec); //RTC_HandleTypeDef hrtc; RTC_TimeTypeDef sTime = { 0 }; RTC_DateTypeDef sDate = { 0 }; /** Initialize RTC Only */ 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) { //if (HAL_RTC_Init(&hrtc) == HAL_ERROR)printf("Rtc HAL_ERROR\r\n"); //if (HAL_RTC_Init(&hrtc) == HAL_BUSY)printf("Rtc HAL_BUSY\r\n"); //if (HAL_RTC_Init(&hrtc) == HAL_TIMEOUT)printf("Rtc HAL_TIMEOUT\r\n"); Error_Handler(); } /** Initialize RTC and set the Time and Date */ sTime.Hours = decToBcd(hour); sTime.Minutes = decToBcd(minute); sTime.Seconds = decToBcd(sec); 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 = decToBcd(month); sDate.Date = decToBcd(date); sDate.Year = decToBcd(year); if (HAL_RTC_SetDate(&hrtc, &sDate, RTC_FORMAT_BCD) != HAL_OK) { Error_Handler(); return 1; } return 0; } void setAlarm(int sec){ /** Enable the Alarm A */ RTC_AlarmTypeDef sAlarm = {0}; RTC_TimeTypeDef sTime = {0}; RTC_DateTypeDef sDate = {0}; uint8_t H = sec /3600; uint8_t M = (sec %3600)/60; uint8_t S = ((sec %3600)%60); HAL_RTC_GetTime(&hrtc, &sTime, RTC_FORMAT_BCD); HAL_RTC_GetDate(&hrtc, &sDate, RTC_FORMAT_BCD); uint8_t minute = bcdToDec(sTime.Minutes); uint8_t hour = bcdToDec(sTime.Hours); uint8_t second = bcdToDec(sTime.Seconds); if (H + hour > 23 ) sAlarm.AlarmTime.Hours = decToBcd(H+hour-24); else sAlarm.AlarmTime.Hours = decToBcd(H+hour); if (M + minute >59 ) { if (H + hour + 1 > 23 ) sAlarm.AlarmTime.Hours = decToBcd(H+hour-23); else sAlarm.AlarmTime.Hours = decToBcd(H+hour+1); sAlarm.AlarmTime.Minutes = decToBcd(M+minute-60); } else sAlarm.AlarmTime.Minutes = decToBcd(M+minute); if (S+second>59){ if (M + minute + 1 >59 ) { if (H + hour + 1 > 23 ) sAlarm.AlarmTime.Hours = decToBcd(H+hour-23); else sAlarm.AlarmTime.Hours = decToBcd(H+hour+1); sAlarm.AlarmTime.Minutes = decToBcd(M+minute-60); sAlarm.AlarmTime.Seconds = decToBcd(S+second-60); }else sAlarm.AlarmTime.Minutes = decToBcd(M+minute+1); sAlarm.AlarmTime.Seconds = decToBcd(S+second-60); } else sAlarm.AlarmTime.Seconds = decToBcd(S+second); // sAlarm.AlarmTime.Seconds = sTime.Seconds; sAlarm.AlarmTime.SubSeconds = 0x0; sAlarm.AlarmTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE; sAlarm.AlarmTime.StoreOperation = RTC_STOREOPERATION_RESET; //sAlarm.AlarmMask = RTC_ALARMMASK_NONE; sAlarm.AlarmMask = RTC_ALARMMASK_DATEWEEKDAY; sAlarm.AlarmSubSecondMask = RTC_ALARMSUBSECONDMASK_ALL; //sAlarm.AlarmDateWeekDaySel = RTC_ALARMDATEWEEKDAYSEL_DATE; sAlarm.AlarmDateWeekDaySel = RTC_ALARMDATEWEEKDAYSEL_WEEKDAY; //sAlarm.AlarmDateWeekDay = 0x01|0x02|0x03|0x04|0x05|0x06|0x07; sAlarm.Alarm = RTC_ALARM_A; if (HAL_RTC_SetAlarm_IT(&hrtc, &sAlarm, RTC_FORMAT_BCD) != HAL_OK) { Error_Handler(); } RTC->CR |= RTC_CR_ALRAE | RTC_CR_ALRAIE; //Enable Alarm-A NVIC_SetVector(RTC_Alarm_IRQn, (uint32_t)&alarm_irq_handler); NVIC_EnableIRQ(RTC_Alarm_IRQn); } / void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; RCC_PeriphCLKInitTypeDef PeriphClkInit = {0}; /** Configure LSE Drive Capability */ HAL_PWR_EnableBkUpAccess(); __HAL_RCC_LSEDRIVE_CONFIG(RCC_LSEDRIVE_LOW); /** Initializes the CPU, AHB and APB busses clocks */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI|RCC_OSCILLATORTYPE_LSE; RCC_OscInitStruct.LSEState = RCC_LSE_ON; RCC_OscInitStruct.HSIState = RCC_HSI_ON; RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { Error_Handler(); } /** Initializes the CPU, AHB and APB busses clocks */ RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; RCC_ClkInitStruct.APB2CLKDivider = 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_LSE; if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) { Error_Handler(); } /** Configure the main internal regulator output voltage */ if (HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1) != HAL_OK) { Error_Handler(); } } void configPinsBeforeSleep() { //Config peripheral input pins GPIO_InitTypeDef GPIO_InitStruct = { 0, 0, 0, 0, 0 }; //serial pins GPIO_InitStruct.Pin = (GPIO_PIN_2); GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); //flash pins GPIO_InitStruct.Pin = (GPIO_PIN_14); GPIO_InitStruct.Alternate = GPIO_AF5_SPI2; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); //UltraSonic serial pins GPIO_InitStruct.Pin = (GPIO_PIN_0); GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); GPIO_InitStruct.Pin = (GPIO_PIN_1); GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(GPIOC, &GPIO_InitStruct); } void EXTI15_10_IRQHandler(void) { wait(0.03); if (violate==0) forced=1; //printf("Violate interrupt\r\n"); HAL_NVIC_ClearPendingIRQ(EXTI15_10_IRQn); HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_13); // EXT15_10 line interrupt detected } void GoToSleep(int mode) { /* goToSleep(0) --> stop , goToSleep(1) --> standby */ if (mode == 0) { RCC->AHB1ENR |= RCC_APB1ENR1_PWREN; //stopwuck: msi/hsi clock selection after wake up RCC->CFGR |= RCC_CFGR_STOPWUCK; //PWR->CR1 &= ~PWR_CR1_LPMS; PWR->CR1 |= PWR_CR1_LPMS_STOP2; // Set SLEEPDEEP bit of Cortex system control register SCB->SCR |= (uint32_t) SCB_SCR_SLEEPDEEP_Msk; __WFI(); SCB->SCR &= ~((uint32_t) SCB_SCR_SLEEPDEEP_Msk); USART2->CR1 &= (~1); // fix serial sychronization after wakeup USART2->CR1 |= (0x8000); // Set break point here and step over this line } else { MODIFY_REG(PWR->CR1, PWR_CR1_LPMS, PWR_CR1_LPMS_STANDBY); /* Set SLEEPDEEP bit of Cortex System Control Register */ SET_BIT(SCB->SCR, ((uint32_t)SCB_SCR_SLEEPDEEP_Msk)); __WFI(); } } void alarm_irq_handler(void) { //Clear RTC + EXTI interrupt flags PWR->CR1 |= PWR_CR1_DBP; // Enable power domain //RTC->ISR |= RTC_ISR_ALRAF; RTC->CR &= 0x00ff00ff; // just in case //RTC->WPR = 0xCA; // Disable RTC write protection //RTC->WPR = 0x53; //RTC->CR &= ~(RTC_CR_ALRAE | RTC_CR_ALRAIE); //DisEnable Alarm-A //RTC->WPR = 0xFF; // Enable RTC write protection EXTI->PR1 = RTC_EXTI_LINE_ALARM_EVENT; PWR->CR1 &= ~PWR_CR1_DBP; // Disable power domain //RTC->ISR |= RTC_ISR_ALRAF; }