/** * @brief This function handles RCC interrupt request. * @param None * @retval None */ void RCC_IRQHandler(void) { if(RCC_GetITStatus(RCC_IT_HSERDY) != RESET) { /* Clear HSERDY interrupt pending bit */ RCC_ClearITPendingBit(RCC_IT_HSERDY); /* Check if the HSE clock is still available */ if (RCC_GetFlagStatus(RCC_FLAG_HSERDY) != RESET) { #ifdef SYSCLK_HSE /* Select HSE as system clock source */ RCC_SYSCLKConfig(RCC_SYSCLKSource_HSE); #else #ifdef STM32F10X_CL /* Enable PLL2 */ RCC_PLL2Cmd(ENABLE); #else /* Enable PLL: once the PLL is ready the PLLRDY interrupt is generated */ RCC_PLLCmd(ENABLE); #endif /* STM32F10X_CL */ #endif /* SYSCLK_HSE */ } } #ifdef STM32F10X_CL if(RCC_GetITStatus(RCC_IT_PLL2RDY) != RESET) { /* Clear PLL2RDY interrupt pending bit */ RCC_ClearITPendingBit(RCC_IT_PLL2RDY); /* Enable PLL: once the PLL is ready the PLLRDY interrupt is generated */ RCC_PLLCmd(ENABLE); } #endif /* STM32F10X_CL */ if(RCC_GetITStatus(RCC_IT_PLLRDY) != RESET) { /* Clear PLLRDY interrupt pending bit */ RCC_ClearITPendingBit(RCC_IT_PLLRDY); /* Check if the PLL is still locked */ if (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) != RESET) { /* Select PLL as system clock source */ RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); } } }
/** * @brief This function handles NMI exception. * @param None * @retval None */ void NMI_Handler(void) { /* This interrupt is generated when HSE clock fails */ if (RCC_GetITStatus(RCC_IT_CSS) != RESET) { /* At this stage: HSE, PLL are disabled (but no change on PLL config) and MSI is selected as system clock source */ /* Enable HSE */ RCC_HSEConfig(RCC_HSE_ON); /* Enable HSE Ready interrupt */ RCC_ITConfig(RCC_IT_HSERDY, ENABLE); /* Enable PLL Ready interrupt */ RCC_ITConfig(RCC_IT_PLLRDY, ENABLE); /* Clear Clock Security System interrupt pending bit */ RCC_ClearITPendingBit(RCC_IT_CSS); /* Once HSE clock recover, the HSERDY interrupt is generated and in the RCC ISR routine the system clock will be reconfigured to its previous state (before HSE clock failure) */ } }
/******************************************************************************* * Function Name : NMI_Handler * Description : This function handles NMI exception. * Input : None * Output : None * Return : None *******************************************************************************/ void NMI_Handler(void) { /* This interrupt is generated when HSE clock fails */ if (RCC_GetITStatus(RCC_IT_CSS) != RESET) { SystemCoreClockUpdate(); /* Clear Clock Security System interrupt pending bit */ RCC_ClearITPendingBit(RCC_IT_CSS); } }
/* Przerwanie NMI jest generowane m. in. przez system nadzoru zegara. Jeżeli zegar zewnętrzny * padnie, wtedy można przełączyć się na zegar wewnętrzny. Niestety, aby płynnie przechodzić między * domenami zegara bez zmiany konfiguracji peryferiów, zegar systemowy nie może być szybszy niż maks * co się dla uzyskać PLL napędzanej z HSI, czyli 64MHz. Obsługa jest mało koszerna, gdyż trwa długo * ale jak pada zegar, to chyba jest to mało ważne, czy obsługjemy inne przerwania, ważne, żeby * przywrócić system do działania. */ void NMI_Handler(void) { if (RCC_GetITStatus(RCC_IT_CSS) == SET) { RCC_HSEConfig(RCC_HSE_ON); if (RCC_WaitForHSEStartUp() == SUCCESS) { RCC_PLLCmd(ENABLE); while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET); RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); while (RCC_GetSYSCLKSource() != 0x08); } else { RCC_PLLConfig(RCC_PLLSource_HSI_Div2, RCC_PLLMul_16); RCC_PLLCmd(ENABLE); while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET); RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); while (RCC_GetSYSCLKSource() != 0x08); } RCC_ClearITPendingBit(RCC_IT_CSS); } }
/******************************************************************************* * Function Name : NMI_Handler * Description : This function handles NMI exception. * Input : None * Output : None * Return : None *******************************************************************************/ void NMI_Handler(void) { uint32_t tmp = 318, index = 0; /* Disable LCD Window mode */ LCD_WindowModeDisable(); /* If HSE is not detected at program startup or HSE clock failed during program execution */ if((Get_HSEStartUpStatus() == ERROR) || (RCC_GetITStatus(RCC_IT_CSS) != RESET)) { /* Clear the LCD */ LCD_Clear(White); /* Set the LCD Back Color */ LCD_SetBackColor(Blue); /* Set the LCD Text Color */ LCD_SetTextColor(White); /* Display " No Clock Detected " message */ LCD_DisplayStringLine(Line0, "No HSE Clock "); LCD_DisplayStringLine(Line1, "Detected. STANDBY "); LCD_DisplayStringLine(Line2, "mode in few seconds. "); LCD_DisplayStringLine(Line5, "If HSE Clock "); LCD_DisplayStringLine(Line6, "recovers before the "); LCD_DisplayStringLine(Line7, "time out, a System "); LCD_DisplayStringLine(Line8, "Reset is generated. "); LCD_ClearLine(Line9); /* Clear Clock Security System interrupt pending bit */ RCC_ClearITPendingBit(RCC_IT_CSS); GPIO_SetBits(GPIOC, GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9); /* Enable HSE */ RCC_HSEConfig(RCC_HSE_ON); LCD_ClearLine(Line4); /* Set the Back Color */ LCD_SetBackColor(White); /* Set the Text Color */ LCD_SetTextColor(Red); LCD_DrawRect(71, 319, 25, 320); LCD_SetBackColor(Green); LCD_SetTextColor(White); /* Wait till HSE is ready */ while(RCC_GetFlagStatus(RCC_FLAG_HSERDY) == RESET) { if(index == 0x3FFFF) { LCD_DisplayChar(Line3, tmp, 0x20); tmp -= 16; index = 0; } index++; /* Enters the system in STANDBY mode */ if(tmp < 16) { LCD_SetBackColor(Blue); LCD_ClearLine(Line3); LCD_ClearLine(Line4); LCD_ClearLine(Line5); LCD_ClearLine(Line6); LCD_DisplayStringLine(Line7, " MCU in STANDBY Mode"); LCD_DisplayStringLine(Line8, "To exit press Wakeup"); /* Request to enter STANDBY mode */ PWR_EnterSTANDBYMode(); } } /* Generate a system reset */ NVIC_SystemReset(); } }