在上次使用STM32CubeMX生成RTC工程[闹钟中断]基础上实现周期间隔的闹钟
一些场合需要周期性的闹钟
现在为了方便设置每十秒来一次。
备注:
当然可以直接修改HAL库static HAL_StatusTypeDef RTC_WriteAlarmCounter(RTC_HandleTypeDef* hrtc, uint32_t AlarmCounter)将这个开发出来,但是本着能不修改底层库就尽然不修改的原则。好了废话少说上代码:
/** ****************************************************************************** * File Name : main.c * Description : Main program body ****************************************************************************** ** This notice applies to any and all portions of this file * that are not between comment pairs USER CODE BEGIN and * USER CODE END. Other portions of this file, whether * inserted by the user or by software development tools * are owned by their respective copyright owners. * * COPYRIGHT(c) 2017 STMicroelectronics * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * 3. Neither the name of STMicroelectronics nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * ****************************************************************************** */ /* Includes ------------------------------------------------------------------*/ #include "main.h" #include "stm32f1xx_hal.h" /* USER CODE BEGIN Includes */ /* USER CODE END Includes */ /* Private variables ---------------------------------------------------------*/ RTC_HandleTypeDef hrtc; /* USER CODE BEGIN PV */ /* Private variables ---------------------------------------------------------*/ /* Buffer used for displaying Time */ uint8_t aShowTime[50] = {0}; uint8_t ShowTime1[50] = {0}; uint8_t ShowTime2[50] = {0}; uint8_t rtc_alarm_flag = 0; uint8_t rtc_event_flag = 0; /* USER CODE END PV */ /* Private function prototypes -----------------------------------------------*/ void SystemClock_Config(void); static void MX_GPIO_Init(void); static void MX_RTC_Init(void); /* USER CODE BEGIN PFP */ /* Private function prototypes -----------------------------------------------*/ /* USER CODE END PFP */ /* USER CODE BEGIN 0 */ uint8_t BIN2BCD(uint8_t byte) { uint8_t low, high; low = byte & 0x0F; high = ((byte >> 4) & 0x0F) * 10; return high + low; } uint8_t BCD2BIN(uint8_t byte) { return ((byte/10)<<4) + (byte%10); } /** * @brief Sets the specified RTC Alarm with Interrupt * @param AlarmCounter: Counter to write in RTC_ALR registers * @note The HAL_RTC_SetTime() must be called before enabling the Alarm feature. */ void APP_RTC_SetAlarmCounter_IT(uint32_t AlarmCounter) { RTC_AlarmTypeDef sAlarm; uint32_t counter_alarm = 0; uint32_t counter_time = 0; RTC_TimeTypeDef stime = {0}; // assert_param(AlarmCounter<= 86400); HAL_RTC_GetTime(&hrtc, &stime, RTC_FORMAT_BIN); sprintf((char*)ShowTime1," GetTime %02d:%02d:%02d",stime.Hours, stime.Minutes, stime.Seconds); /* Convert time in seconds */ counter_time = (uint32_t)(((uint32_t)stime.Hours * 3600) + ((uint32_t)stime.Minutes * 60) + ((uint32_t)stime.Seconds)); counter_alarm = counter_time+AlarmCounter; sAlarm.Alarm = RTC_ALARM_A; sAlarm.AlarmTime.Hours = (uint32_t)((counter_alarm / 3600) % 24); sAlarm.AlarmTime.Minutes = (uint32_t)((counter_alarm % 3600) / 60); sAlarm.AlarmTime.Seconds = (uint32_t)((counter_alarm % 3600) % 60); sprintf((char*)ShowTime2,"SetAlarm %02d:%02d:%02d", sAlarm.AlarmTime.Hours, sAlarm.AlarmTime.Minutes, sAlarm.AlarmTime.Seconds); if(HAL_RTC_SetAlarm_IT(&hrtc,&sAlarm,RTC_FORMAT_BIN) != HAL_OK) { /* Initialization Error */ Error_Handler(); } } /** * @brief Configure the current time and date. * @param None * @retval None */ static void RTC_AlarmConfig(void) { RTC_AlarmTypeDef salarmstructure; /*##-1- Configure the RTC Alarm peripheral #################################*/ /* Set Alarm to 01:17:30 RTC Alarm Generation: Alarm on Hours, Minutes and Seconds */ salarmstructure.Alarm = RTC_ALARM_A; salarmstructure.AlarmTime.Hours = 0x1; salarmstructure.AlarmTime.Minutes = 0x24; salarmstructure.AlarmTime.Seconds = 0x00; if(HAL_RTC_SetAlarm_IT(&hrtc,&salarmstructure,RTC_FORMAT_BCD) != HAL_OK) { /* Initialization Error */ Error_Handler(); } } /** * @brief Display the current time. * @param showtime : pointer to buffer * @retval None */ static void RTC_TimeShow(uint8_t* showtime) { RTC_DateTypeDef sdatestructureget; RTC_TimeTypeDef stimestructureget; /* Get the RTC current Time */ HAL_RTC_GetTime(&hrtc, &stimestructureget, RTC_FORMAT_BIN); /* Get the RTC current Date */ HAL_RTC_GetDate(&hrtc, &sdatestructureget, RTC_FORMAT_BIN); /* Display time Format : hh:mm:ss */ sprintf((char*)showtime,"%02d:%02d:%02d",stimestructureget.Hours, stimestructureget.Minutes, stimestructureget.Seconds); } /* USER CODE END 0 */ int main(void) { /* USER CODE BEGIN 1 */ /* 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_RTC_Init(); /* USER CODE BEGIN 2 */ /*##-1- Configure Alarm ####################################################*/ /* Configure RTC Alarm */ //RTC_AlarmConfig(); APP_RTC_SetAlarmCounter_IT(10); HAL_RTCEx_SetSecond_IT(&hrtc); /* USER CODE END 2 */ /* Infinite loop */ /* USER CODE BEGIN WHILE */ while (1) { /* USER CODE END WHILE */ /* USER CODE BEGIN 3 */ /*##-2- Display the updated Time #########################################*/ RTC_TimeShow(aShowTime); } /* USER CODE END 3 */ } /** System Clock Configuration */ void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct; RCC_ClkInitTypeDef RCC_ClkInitStruct; RCC_PeriphCLKInitTypeDef PeriphClkInit; /**Initializes the CPU, AHB and APB busses clocks */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI|RCC_OSCILLATORTYPE_HSE; RCC_OscInitStruct.HSEState = RCC_HSE_ON; RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1; RCC_OscInitStruct.HSIState = RCC_HSI_ON; RCC_OscInitStruct.LSIState = RCC_LSI_ON; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9; if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); } /**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_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); } PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_RTC; PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_LSI; if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); } /**Configure the Systick interrupt time */ HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000); /**Configure the Systick */ HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK); /* SysTick_IRQn interrupt configuration */ HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0); } /* RTC init function */ static void MX_RTC_Init(void) { RTC_TimeTypeDef sTime; RTC_DateTypeDef DateToUpdate; /**Initialize RTC Only */ hrtc.Instance = RTC; hrtc.Init.AsynchPrediv = RTC_AUTO_1_SECOND; hrtc.Init.OutPut = RTC_OUTPUTSOURCE_NONE; if (HAL_RTC_Init(&hrtc) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); } /**Initialize RTC and set the Time and Date */ if(HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_DR1) != 0x32F2){ sTime.Hours = 0x1; sTime.Minutes = 0x17; sTime.Seconds = 0x0; if (HAL_RTC_SetTime(&hrtc, &sTime, RTC_FORMAT_BCD) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); } DateToUpdate.WeekDay = RTC_WEEKDAY_FRIDAY; DateToUpdate.Month = RTC_MONTH_JULY; DateToUpdate.Date = 0x14; DateToUpdate.Year = 0x17; if (HAL_RTC_SetDate(&hrtc, &DateToUpdate, RTC_FORMAT_BCD) != HAL_OK) { _Error_Handler(__FILE__, __LINE__); } HAL_RTCEx_BKUPWrite(&hrtc,RTC_BKP_DR1,0x32F2); } } /** Configure pins as * Analog * Input * Output * EVENT_OUT * EXTI */ static void MX_GPIO_Init(void) { /* GPIO Ports Clock Enable */ __HAL_RCC_GPIOC_CLK_ENABLE(); __HAL_RCC_GPIOD_CLK_ENABLE(); __HAL_RCC_GPIOA_CLK_ENABLE(); } /* USER CODE BEGIN 4 */ void HAL_RTCEx_RTCEventCallback (RTC_HandleTypeDef *hrtc) { rtc_event_flag++; } /** * @brief Alarm callback * @param hrtc : RTC handle * @retval None */ void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc) { APP_RTC_SetAlarmCounter_IT(10); rtc_alarm_flag++; } /* USER CODE END 4 */ /** * @brief This function is executed in case of error occurrence. * @param None * @retval None */ void _Error_Handler(char * file, int line) { /* USER CODE BEGIN Error_Handler_Debug */ /* User can add his own implementation to report the HAL error return state */ 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 ", file, line) */ /* USER CODE END 6 */ } #endif /** * @} */ /** * @} */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
仿真结果如下: