STM32F0xx Standard Peripherals Firmware Library
|
STM32F0xx_StdPeriph_Examples/COMP/COMP_AnalogWatchdog/main.c
Go to the documentation of this file.
00001 /** 00002 ****************************************************************************** 00003 * @file COMP/COMP_AnalogWatchdog/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>© 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 COMP_AnalogWatchdog 00036 * @{ 00037 */ 00038 00039 /* Private typedef -----------------------------------------------------------*/ 00040 /* Private define ------------------------------------------------------------*/ 00041 /* Private macro -------------------------------------------------------------*/ 00042 /* Private variables ---------------------------------------------------------*/ 00043 __IO uint32_t State = 0; 00044 00045 /* Private function prototypes -----------------------------------------------*/ 00046 static void COMP_Config(void); 00047 static void STOPEntry(void); 00048 static void RestoreConfiguration(void); 00049 00050 /* Private functions ---------------------------------------------------------*/ 00051 00052 /** 00053 * @brief Main program. 00054 * @param None 00055 * @retval None 00056 */ 00057 int main(void) 00058 { 00059 /*!< At this stage the microcontroller clock setting is already configured, 00060 this is done through SystemInit() function which is called from startup 00061 file (startup_stm32f0xx.s) before to branch to application main. 00062 To reconfigure the default setting of SystemInit() function, refer to 00063 system_stm32f0xx.c file 00064 */ 00065 00066 /******* Initialize LEDs available on STM320518-EVAL board ******************/ 00067 STM_EVAL_LEDInit(LED1); 00068 STM_EVAL_LEDInit(LED2); 00069 STM_EVAL_LEDInit(LED3); 00070 STM_EVAL_LEDInit(LED4); 00071 00072 /* PWR Peripheral clock enable */ 00073 RCC_APB1PeriphClockCmd(RCC_APB1Periph_PWR, ENABLE); 00074 00075 /* configure COMP1 and COMP2 with interrupts enabled */ 00076 COMP_Config(); 00077 00078 /* Check input voltage level: within the thresholds, above the upper threshold 00079 or under the lower threshold */ 00080 CheckState(); 00081 00082 /* Infinite loop */ 00083 while (1) 00084 { 00085 if (State == STATE_OVER_THRESHOLD) 00086 { 00087 /* Restore config: clock, GPIO... */ 00088 RestoreConfiguration(); 00089 00090 /* Restore GPIO configuration */ 00091 STM_EVAL_LEDInit(LED1); 00092 STM_EVAL_LEDInit(LED2); 00093 STM_EVAL_LEDInit(LED3); 00094 STM_EVAL_LEDInit(LED4); 00095 00096 /* Turn on LD1 and LD3 and turn off LD2 and LD4 */ 00097 STM_EVAL_LEDOn(LED1); 00098 STM_EVAL_LEDOff(LED2); 00099 STM_EVAL_LEDOn(LED3); 00100 STM_EVAL_LEDOff(LED4); 00101 00102 while(State == STATE_OVER_THRESHOLD) 00103 { 00104 /* add your code here */ 00105 } 00106 } 00107 else if (State == STATE_WITHIN_THRESHOLD) 00108 { 00109 /* Input voltage is within the thresholds: higher and lower thresholds */ 00110 /* Enter STOP mode with regulator in low power */ 00111 STOPEntry(); 00112 } 00113 else /* (State == STATE_UNDER_THRESHOLD) */ 00114 { 00115 /* Restore config: clock, GPIO... */ 00116 RestoreConfiguration(); 00117 00118 /* Restore GPIO configuration */ 00119 STM_EVAL_LEDInit(LED1); 00120 STM_EVAL_LEDInit(LED2); 00121 STM_EVAL_LEDInit(LED3); 00122 STM_EVAL_LEDInit(LED4); 00123 00124 /* Turn on LD2 & LD4 and turn off LD1 & LD3 */ 00125 STM_EVAL_LEDOff(LED1); 00126 STM_EVAL_LEDOn(LED2); 00127 STM_EVAL_LEDOff(LED3); 00128 STM_EVAL_LEDOn(LED4); 00129 00130 while(State == STATE_UNDER_THRESHOLD) 00131 { 00132 /* add your code here */ 00133 } 00134 } 00135 } 00136 } 00137 00138 /** 00139 * @brief Configure COMP1 and COMP2 with interrupt 00140 * @param None 00141 * @retval None 00142 */ 00143 static void COMP_Config(void) 00144 { 00145 COMP_InitTypeDef COMP_InitStructure; 00146 EXTI_InitTypeDef EXTI_InitStructure; 00147 NVIC_InitTypeDef NVIC_InitStructure; 00148 GPIO_InitTypeDef GPIO_InitStructure; 00149 00150 /* GPIOA Peripheral clock enable */ 00151 RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE); 00152 00153 /* Configure PA1: PA1 is used as COMP1 and COMP2 non inveting input */ 00154 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; 00155 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN; 00156 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; 00157 GPIO_Init(GPIOA, &GPIO_InitStructure); 00158 00159 /* COMP Peripheral clock enable */ 00160 RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE); 00161 00162 /* COMP1 Init: the higher threshold is set to VREFINT ~ 1.22V 00163 but can be changed to other available possibilities */ 00164 COMP_StructInit(&COMP_InitStructure); 00165 COMP_InitStructure.COMP_InvertingInput = COMP_InvertingInput_VREFINT; 00166 COMP_InitStructure.COMP_Output = COMP_Output_None; 00167 COMP_InitStructure.COMP_Mode = COMP_Mode_LowPower; 00168 COMP_InitStructure.COMP_Hysteresis = COMP_Hysteresis_High; 00169 COMP_Init(COMP_Selection_COMP1, &COMP_InitStructure); 00170 00171 /* COMP2 Init: the lower threshold is set to VREFINT/4 ~ 1.22 / 4 ~ 0.305 V 00172 but can be changed to other available possibilities */ 00173 COMP_StructInit(&COMP_InitStructure); 00174 COMP_InitStructure.COMP_InvertingInput = COMP_InvertingInput_1_4VREFINT; 00175 COMP_InitStructure.COMP_Output = COMP_Output_None; 00176 COMP_InitStructure.COMP_Mode = COMP_Mode_LowPower; 00177 COMP_InitStructure.COMP_Hysteresis = COMP_Hysteresis_High; 00178 COMP_Init(COMP_Selection_COMP2, &COMP_InitStructure); 00179 00180 /* Enable Window mode */ 00181 COMP_WindowCmd(ENABLE); 00182 00183 /* Enable COMP1: the higher threshold is set to VREFINT ~ 1.22 V */ 00184 COMP_Cmd(COMP_Selection_COMP1, ENABLE); 00185 /* Enable COMP2: the lower threshold is set to VREFINT/4 ~ 0.305 V */ 00186 COMP_Cmd(COMP_Selection_COMP2, ENABLE); 00187 00188 /* Configure EXTI Line 21 in interrupt mode */ 00189 EXTI_InitStructure.EXTI_Line = EXTI_Line21; 00190 EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; 00191 EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling; 00192 EXTI_InitStructure.EXTI_LineCmd = ENABLE; 00193 EXTI_Init(&EXTI_InitStructure); 00194 00195 /* Configure EXTI Line 22 in interrupt mode */ 00196 EXTI_InitStructure.EXTI_Line = EXTI_Line22; 00197 EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; 00198 EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling; 00199 EXTI_InitStructure.EXTI_LineCmd = ENABLE; 00200 EXTI_Init(&EXTI_InitStructure); 00201 00202 /* Clear EXTI21 line */ 00203 EXTI_ClearITPendingBit(EXTI_Line21); 00204 00205 /* Clear EXTI22 line */ 00206 EXTI_ClearITPendingBit(EXTI_Line22); 00207 00208 /* Configure COMP IRQ */ 00209 NVIC_InitStructure.NVIC_IRQChannel = ADC1_COMP_IRQn; 00210 NVIC_InitStructure.NVIC_IRQChannelPriority = 0; 00211 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; 00212 NVIC_Init(&NVIC_InitStructure); 00213 } 00214 00215 /** 00216 * @brief Prepare the system to enter STOP mode. 00217 * @param None 00218 * @retval None 00219 */ 00220 static void STOPEntry(void) 00221 { 00222 GPIO_InitTypeDef GPIO_InitStructure; 00223 /* Enable GPIOs clock */ 00224 RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA | RCC_AHBPeriph_GPIOB | RCC_AHBPeriph_GPIOC | 00225 RCC_AHBPeriph_GPIOD | RCC_AHBPeriph_GPIOF, ENABLE); 00226 00227 /* Configure all GPIO port pins in Analog mode */ 00228 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All; 00229 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN; 00230 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; 00231 GPIO_Init(GPIOA, &GPIO_InitStructure); 00232 GPIO_Init(GPIOB, &GPIO_InitStructure); 00233 GPIO_Init(GPIOC, &GPIO_InitStructure); 00234 GPIO_Init(GPIOD, &GPIO_InitStructure); 00235 GPIO_Init(GPIOF, &GPIO_InitStructure); 00236 00237 /* Request to enter STOP mode with regulator in low power */ 00238 PWR_EnterSTOPMode(PWR_Regulator_LowPower, PWR_STOPEntry_WFI); 00239 } 00240 00241 /** 00242 * @brief check input voltage level: within the thresholds, above the upper 00243 * threshold or under the lower threshold 00244 * @param None 00245 * @retval None 00246 */ 00247 void CheckState(void) 00248 { 00249 /* Check if COMP2 output level is high */ 00250 if ((COMP_GetOutputLevel(COMP_Selection_COMP1) == COMP_OutputLevel_High) 00251 && (COMP_GetOutputLevel(COMP_Selection_COMP2) == COMP_OutputLevel_High)) 00252 { 00253 /* A rising edge is detected so the input voltage is higher than VREFINT */ 00254 State = STATE_OVER_THRESHOLD; 00255 } 00256 else if ((COMP_GetOutputLevel(COMP_Selection_COMP1) == COMP_OutputLevel_Low) 00257 && (COMP_GetOutputLevel(COMP_Selection_COMP2) == COMP_OutputLevel_High)) 00258 { 00259 /* A falling edge is detected so the input voltage is lower than VREFINT */ 00260 State = STATE_WITHIN_THRESHOLD; 00261 } 00262 else if ((COMP_GetOutputLevel(COMP_Selection_COMP1) == COMP_OutputLevel_Low) 00263 && (COMP_GetOutputLevel(COMP_Selection_COMP2) == COMP_OutputLevel_Low)) 00264 { 00265 State = STATE_UNDER_THRESHOLD; 00266 } 00267 } 00268 00269 /** 00270 * @brief Restore peripheral config before entering STOP mode. 00271 * @param None 00272 * @retval None 00273 */ 00274 static void RestoreConfiguration(void) 00275 { 00276 __IO uint32_t StartUpCounter = 0, HSEStatus = 0; 00277 00278 /* SYSCLK, HCLK, PCLK configuration ----------------------------------------*/ 00279 /* Enable HSE */ 00280 RCC_HSEConfig(RCC_HSE_ON); 00281 00282 /* Wait till HSE is ready and if Time out is reached exit */ 00283 HSEStatus = RCC_WaitForHSEStartUp(); 00284 00285 if (HSEStatus == (uint32_t)0x01) 00286 { 00287 /* Enable Prefetch Buffer */ 00288 FLASH_SetLatency(FLASH_Latency_1); 00289 00290 /* HCLK = SYSCLK */ 00291 RCC_HCLKConfig(RCC_SYSCLK_Div1); 00292 00293 /* PCLK = HCLK */ 00294 RCC_PCLKConfig(RCC_HCLK_Div1); 00295 00296 /* PLL configuration: = HSE * 6 = 48 MHz */ 00297 RCC_PREDIV1Config(RCC_PREDIV1_Div1); 00298 RCC_PLLConfig(RCC_PLLSource_PREDIV1, RCC_PLLMul_6); 00299 00300 /* Enable PLL */ 00301 RCC_PLLCmd(ENABLE); 00302 00303 /* PLL as system clock source */ 00304 RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); 00305 } 00306 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****/