STM32F0xx Standard Peripherals Firmware Library: main.c Source File

STM32F0xx Standard Peripherals Library

STM32F0xx_StdPeriph_Examples/PWR/PWR_Standby/main.c
Go to the documentation of this file.
00001 /**
00002   ******************************************************************************
00003   * @file    PWR/PWR_STANDBY/main.c 
00004   * @author  MCD Application Team
00005   * @version V1.4.0
00006   * @date    24-July-2014
00007   * @brief   Main program body
00008   ******************************************************************************
00009   * @attention
00010   *
00011   * <h2><center>&copy; COPYRIGHT 2014 STMicroelectronics</center></h2>
00012   *
00013   * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
00014   * You may not use this file except in compliance with the License.
00015   * You may obtain a copy of the License at:
00016   *
00017   *        http://www.st.com/software_license_agreement_liberty_v2
00018   *
00019   * Unless required by applicable law or agreed to in writing, software 
00020   * distributed under the License is distributed on an "AS IS" BASIS, 
00021   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00022   * See the License for the specific language governing permissions and
00023   * limitations under the License.
00024   *
00025   ******************************************************************************
00026   */
00027 
00028 /* Includes ------------------------------------------------------------------*/
00029 #include "main.h"
00030 
00031 /** @addtogroup STM32F0xx_StdPeriph_Examples
00032   * @{
00033   */
00034 
00035 /** @addtogroup PWR_STANDBY
00036   * @{
00037   */
00038 
00039 /* Private typedef -----------------------------------------------------------*/
00040 /* Private define ------------------------------------------------------------*/
00041 /* Private macro -------------------------------------------------------------*/
00042 /* Private variables ---------------------------------------------------------*/
00043 extern __IO uint32_t CaptureNumber, PeriodValue;
00044 
00045 /* Private function prototypes -----------------------------------------------*/
00046 static void RTC_Config(void);
00047 static void EnterSTANDBYMode(void);
00048 static uint32_t GetLSIFrequency(void);
00049 void SysTick_Configuration(void);
00050 
00051 /* Private functions ---------------------------------------------------------*/
00052 
00053 /**
00054   * @brief  Main program.
00055   * @param  None
00056   * @retval None
00057   */
00058 int main(void)
00059 {
00060   /*!< At this stage the microcontroller clock setting is already configured, 
00061        this is done through SystemInit() function which is called from startup
00062        file (startup_stm32f0xx.s) before to branch to application main.
00063        To reconfigure the default setting of SystemInit() function, refer to
00064        system_stm32f0xx.c file
00065      */
00066       
00067   /* Configure LED3 */
00068   STM_EVAL_LEDInit(LED3);
00069   
00070   /* Configure Systick */
00071   SysTick_Configuration();
00072   
00073   /* Turn ON LED3 */
00074   STM_EVAL_LEDOn(LED3);  
00075 
00076   /* Configures Tamper button */
00077   STM_EVAL_PBInit(BUTTON_TAMPER,BUTTON_MODE_GPIO);
00078                  
00079   /* Configure RTC clock source and prescaler */
00080   RTC_Config();
00081 
00082   /* Wait till Tamper button is pressed */  
00083   while(STM_EVAL_PBGetState(BUTTON_TAMPER) != RESET);
00084 
00085   /* Enter STANDBY mode, RTC Alarm within 3 second or an external RESET will 
00086    wake-up the system from STANDBY */
00087   EnterSTANDBYMode();
00088   
00089   while(1)
00090   {}
00091 }
00092 
00093 /**
00094   * @brief  Configures the RTC clock source.
00095   * @param  None
00096   * @retval None
00097   */
00098 static void RTC_Config(void)
00099 {  
00100   RTC_InitTypeDef   RTC_InitStructure;
00101   RTC_TimeTypeDef   RTC_TimeStructure;
00102   uint32_t LSIFreq = 0;
00103 
00104   /* Enable the PWR clock */
00105   RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE);
00106   
00107   /* Allow access to Backup Domain */
00108   PWR_BackupAccessCmd(ENABLE);
00109   
00110   /* Disable wake-up source(ALARM) to guarantee free access to WUT level-OR input */
00111   RTC_ITConfig(RTC_IT_ALRA, DISABLE);
00112 
00113   /* Clear Wakeup flag */
00114   PWR_ClearFlag(PWR_FLAG_WU);
00115 
00116   /* Enable wake-up source(ALARM) to guarantee free access to WUT level-OR input */
00117   RTC_ITConfig(RTC_IT_ALRA, ENABLE);
00118   
00119   /* Enable the LSI OSC */
00120   RCC_LSICmd(ENABLE);
00121   
00122   /* Wait till LSI is ready */
00123   while (RCC_GetFlagStatus(RCC_FLAG_LSIRDY) == RESET)
00124   {} 
00125       
00126   /* Check if the StandBy flag is set */
00127   if (PWR_GetFlagStatus(PWR_FLAG_SB) != RESET)
00128   {                 
00129     /* Clear StandBy flag */
00130     PWR_ClearFlag(PWR_FLAG_SB);  
00131 
00132     /* Check if the StandBy flag is cleared */
00133     if (PWR_GetFlagStatus(PWR_FLAG_SB) != RESET)
00134     {
00135       while(1);
00136     }
00137         
00138     RTC_WaitForSynchro();
00139     
00140     /* No need to configure the RTC as the RTC config(clock source, enable,
00141     prescaler,...) are kept after wake-up from STANDBY */
00142   }
00143   else
00144   {        
00145     /* RTC Configuration ******************************************************/
00146     /* Reset Backup Domain */
00147     RCC_BackupResetCmd(ENABLE);
00148     RCC_BackupResetCmd(DISABLE);
00149  
00150     /* Select the RTC Clock Source */
00151     RCC_RTCCLKConfig(RCC_RTCCLKSource_LSI);
00152 
00153     /* Enable the RTC Clock */
00154     RCC_RTCCLKCmd(ENABLE);
00155 
00156     /* Wait for RTC APB registers synchronisation */
00157     RTC_WaitForSynchro();
00158 
00159     /* Get the LSI frequency:  TIM14 is used to measure the LSI frequency */    
00160     LSIFreq = GetLSIFrequency();
00161     
00162     RTC_InitStructure.RTC_HourFormat = RTC_HourFormat_24;
00163     RTC_InitStructure.RTC_AsynchPrediv = 99;
00164     RTC_InitStructure.RTC_SynchPrediv =  (LSIFreq/100) - 1;
00165 
00166     RTC_Init(&RTC_InitStructure);
00167 
00168     /* Set the time to 01h 00mn 00s AM */
00169     RTC_TimeStructure.RTC_H12     = RTC_H12_AM;
00170     RTC_TimeStructure.RTC_Hours   = 0x01;
00171     RTC_TimeStructure.RTC_Minutes = 0x00;
00172     RTC_TimeStructure.RTC_Seconds = 0x00;
00173 
00174     RTC_SetTime(RTC_Format_BIN, &RTC_TimeStructure); 
00175   }     
00176 }
00177 
00178 /**
00179   * @brief  Enters STANDBY mode, RTC Alarm within 3 second or an external RESET 
00180   *         will wake-up the system from STANDBY
00181   * @param  None
00182   * @retval None
00183   */
00184 static void EnterSTANDBYMode(void)
00185 {
00186   RTC_AlarmTypeDef  RTC_AlarmStructure;
00187   RTC_TimeTypeDef   RTC_TimeStructure;
00188 
00189   /* Disable the Alarm A */
00190   RTC_AlarmCmd(RTC_Alarm_A, DISABLE);
00191   
00192   /* Get the current time */
00193   RTC_GetTime(RTC_Format_BIN, &RTC_TimeStructure);
00194   
00195   /* Set the alarm to current time + 3s */
00196   RTC_AlarmStructure.RTC_AlarmTime.RTC_H12     = RTC_TimeStructure.RTC_H12;
00197   RTC_AlarmStructure.RTC_AlarmTime.RTC_Hours   = RTC_TimeStructure.RTC_Hours;
00198   RTC_AlarmStructure.RTC_AlarmTime.RTC_Minutes = RTC_TimeStructure.RTC_Minutes;
00199   RTC_AlarmStructure.RTC_AlarmTime.RTC_Seconds = (RTC_TimeStructure.RTC_Seconds + 0x3) % 60;
00200   RTC_AlarmStructure.RTC_AlarmDateWeekDay = 31;
00201   RTC_AlarmStructure.RTC_AlarmDateWeekDaySel = RTC_AlarmDateWeekDaySel_Date;
00202   RTC_AlarmStructure.RTC_AlarmMask = RTC_AlarmMask_DateWeekDay | RTC_AlarmMask_Hours | RTC_AlarmMask_Minutes;
00203   RTC_SetAlarm(RTC_Format_BIN, RTC_Alarm_A, &RTC_AlarmStructure);
00204   
00205   /* Enable RTC Alarm A Interrupt: this Interrupt will wake-up the system from
00206   STANDBY mode (RTC Alarm IT not enabled in NVIC) */
00207   RTC_ITConfig(RTC_IT_ALRA, ENABLE);
00208   
00209   /* Enable the Alarm A */
00210   RTC_AlarmCmd(RTC_Alarm_A, ENABLE);
00211   
00212   /* Clear RTC Alarm Flag */ 
00213   RTC_ClearFlag(RTC_FLAG_ALRAF);
00214   
00215   /* Request to enter STANDBY mode (Wake Up flag is cleared in PWR_EnterSTANDBYMode function) */
00216   PWR_EnterSTANDBYMode();
00217 }
00218 
00219 /**
00220   * @brief  Configures TIM14 to measure the LSI oscillator frequency. 
00221   * @param  None
00222   * @retval LSI Frequency
00223   */
00224 static uint32_t GetLSIFrequency(void)
00225 {
00226   NVIC_InitTypeDef   NVIC_InitStructure;
00227   TIM_ICInitTypeDef  TIM_ICInitStructure;
00228   RCC_ClocksTypeDef  RCC_ClockFreq;
00229 
00230   /* TIM14 configuration *******************************************************/ 
00231   /* Enable TIM14 clock */
00232   RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM14, ENABLE);
00233   
00234   /* Reset TIM14 registers */
00235   TIM_DeInit(TIM14);
00236 
00237   /* Configure TIM14 prescaler */
00238   TIM_PrescalerConfig(TIM14, 0, TIM_PSCReloadMode_Immediate);
00239 
00240   /* Connect internally the TIM14_CH1 to the RTC clock output */
00241   TIM_RemapConfig(TIM14, TIM14_RTC_CLK);
00242 
00243   /* TIM14 configuration: Input Capture mode ---------------------
00244      The reference clock(LSE or external) is connected to TIM14 CH1
00245      The Rising edge is used as active edge,
00246      The TIM14 CCR1 is used to compute the frequency value 
00247   ------------------------------------------------------------ */
00248   TIM_ICInitStructure.TIM_Channel     = TIM_Channel_1;
00249   TIM_ICInitStructure.TIM_ICPolarity  = TIM_ICPolarity_Rising;
00250   TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
00251   TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV8;
00252   TIM_ICInitStructure.TIM_ICFilter = 0x0;
00253   TIM_ICInit(TIM14, &TIM_ICInitStructure);
00254 
00255   /* Enable the TIM14 global Interrupt */
00256   NVIC_InitStructure.NVIC_IRQChannel = TIM14_IRQn;
00257   NVIC_InitStructure.NVIC_IRQChannelPriority = 0;
00258   NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
00259   NVIC_Init(&NVIC_InitStructure);
00260 
00261   /* Enable TIM14 counter */
00262   TIM_Cmd(TIM14, ENABLE);
00263 
00264   /* Reset the flags */
00265   TIM14->SR = 0;
00266     
00267   /* Enable the CC1 Interrupt Request */  
00268   TIM_ITConfig(TIM14, TIM_IT_CC1, ENABLE);
00269 
00270 
00271   /* Wait until the TIM14 get 2 LSI edges (refer to TIM14_IRQHandler() in 
00272     stm32F0xx_it.c file) ******************************************************/
00273   while(CaptureNumber != 2)
00274   {
00275   }
00276   /* Deinitialize the TIM14 peripheral registers to their default reset values */
00277   TIM_DeInit(TIM14);
00278 
00279 
00280   /* Compute the LSI frequency, depending on TIM14 input clock frequency (PCLK1)*/
00281   /* Get SYSCLK, HCLK and PCLKx frequency */
00282   RCC_GetClocksFreq(&RCC_ClockFreq);
00283   
00284   /* PCLK1 prescaler equal to 1 => TIMCLK = PCLK1 */
00285   return ((RCC_ClockFreq.PCLK_Frequency / PeriodValue) * 8);
00286 }
00287 
00288 /**
00289   * @brief  Configures the SysTick to generate an interrupt each 250 ms.
00290   * @param  None
00291   * @retval None
00292   */
00293 void SysTick_Configuration(void)
00294 {
00295   /* SysTick interrupt each 250 ms */
00296   if (SysTick_Config((SystemCoreClock/8) / 4))
00297   { 
00298     /* Capture error */ 
00299     while (1);
00300   }
00301 
00302   /* Select AHB clock(HCLK) divided by 8 as SysTick clock source */
00303   SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);
00304 
00305   /* Set SysTick Preemption Priority to 1 */
00306   NVIC_SetPriority(SysTick_IRQn, 0x04);
00307 }
00308 
00309 #ifdef  USE_FULL_ASSERT
00310 
00311 /**
00312   * @brief  Reports the name of the source file and the source line number
00313   *         where the assert_param error has occurred.
00314   * @param  file: pointer to the source file name
00315   * @param  line: assert_param error line source number
00316   * @retval None
00317   */
00318 void assert_failed(uint8_t* file, uint32_t line)
00319 { 
00320   /* User can add his own implementation to report the file name and line number,
00321      ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
00322 
00323   /* Infinite loop */
00324   while (1)
00325   {
00326   }
00327 }
00328 #endif
00329 
00330 /**
00331   * @}
00332   */
00333 
00334 /**
00335   * @}
00336   */
00337 
00338 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
STM32L1xx Standard Peripherals Library: Footer

 

 

 For complete documentation on STM32 Microcontrollers visit www.st.com/STM32