In the company's project some time ago, it was required to use the STM32 processor to automatically switch to the internal crystal oscillator when the external crystal oscillator is abnormal. After searching for a lot of information on the Internet, I finally found an official seminar PPT on the Internet that briefly introduced it. So I followed this idea to try to write code. I didn't expect that the idea provided by the official was quite reliable!
———————————————————I am a gorgeous dividing line——————————————————— —————————————————I am a gorgeous dividing line——————————————————— Function 1, void INIT_CLOCK(void) { #if 1 ErrorStatus HSEStartUpStatus; RCC_DeInit(); //Reset RCC register RCC_HSEConfig(RCC_HSE_ON); //Set external high-speed crystal oscillator (HSE) HSEStartUpStatus = RCC_WaitForHSEStartUp(); //Wait for HSE to start #if 1 //Judge whether the external crystal oscillator is OK. If OK, use the external crystal oscillator. If not, use the internal crystal oscillator, giving priority to the external crystal oscillator. if(HSEStartUpStatus == SUCCESS) { RCC_ClockSecuritySystemCmd(ENABLE); //Start the clock security system CSS //External crystal configuration RCC_HCLKConfig(RCC_SYSCLK_Div1); //Set ABH clock (HCLK): HCLK=SYSCLK //Set PLL clock source and multiplication factor, PLLCLK = HSE*PLLMul = 8*8 = 64MHz Actually: 8*8=64MHz RCC_PLLConfig(RCC_PLLSource_PREDIV1, RCC_PLLMul_2); RCC_PLLCmd(ENABLE); //Enable PLL //Check whether the specified RCC flag is set or not while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET); // Wait till PLL is ready RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); //Set system clock (SYSCLK) //Return the clock source used as system clock // Wait till PLL is used as system clock source while(RCC_GetSYSCLKSource() != 0x08); } else #endif { //Internal crystal configuration RCC_DeInit(); //Reset RCC register RCC_HSEConfig(RCC_HSE_OFF); //Turn off external crystal (HSE) RCC_HCLKConfig(RCC_SYSCLK_Div1); //Set ABH clock (HCLK): HCLK=SYSCLK //Set PLL clock source and multiplication factor, PLLCLK = HSI/2*PLLMul = 8/2*12 = 48MHz Actually: 48MHz RCC_PLLConfig(RCC_PLLSource_HSI_Div2, RCC_PLLMul_12); RCC_PLLCmd(ENABLE); //Enable PLL RCC_SYSCLKConfig (RCC_SYSCLKSource_PLLCLK ); //Set system clock (SYSCLK) //Return the clock source of the system clock // Wait till PLL is used as system clock source while(RCC_GetSYSCLKSource() != 0x08); } #endif } —————————————————I am a gorgeous dividing line——————————————————— In which of the above functions is the clock safety system started only during the external crystal oscillator startup initialization (PS: the red bold part) because only when the external crystal oscillator fails initially will it switch to the internal crystal oscillator. In this function, the external crystal oscillator is started first and the internal crystal oscillator is started only when the external crystal oscillator fails to start. Function 2, void NMIException(void) { if(RCC_GetITStatus(RCC_IT_CSS) != RESET) { #if 0 //Internal crystal configuration RCC_DeInit(); //Reset RCC register RCC_HSEConfig(RCC_HSE_OFF); //Turn off external crystal (HSE) RCC_HCLKConfig(RCC_SYSCLK_Div1); //Set ABH clock (HCLK): HCLK=SYSCLK
//Set PLL clock source and multiplication factor, PLLCLK = HSI/2*PLLMul = 8/2*12 = 48MHz Actually: 48MHz
RCC_PLLConfig(RCC_PLLSource_HSI_Div2, RCC_PLLMul_12);
RCC_PLLCmd(ENABLE); //Enable PLL
//Check whether the specified RCC flag is set
//while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); //Set system clock (SYSCLK)
//Return the clock source used as system clock
// Wait till PLL is used as system clock source
while(RCC_GetSYSCLKSource() != 0x08);
CLKOUT_8M_INIT(); //PA8 port clock output provides 8MHz clock for 24025RCC_ITConfig
(RCC_IT_HSIRDY,ENABLE); //Enable HSI ready interruptRCC_ITConfig
(RCC_IT_PLLRDY,ENABLE); //Enable PLL ready interrupt
#else
NVIC_SystemReset(); //RestartRCC_ITConfig
(RCC_IT_HSERDY,ENABLE); //Enable HSE ready
interruptRCC_ITConfig(RCC_IT_PLLRDY,ENABLE); //Enable PLL ready interrupt
#endif
RCC_ClearITPendingBit(RCC_IT_CSS); //Clear the pending bit of the clock security system interrupt
}
}
———————————————————I am a gorgeous dividing line—————————————————————
The NMIException() function is the crystal oscillator exception function processing function. This function is called in the exception interrupt function. The red part is the internal crystal oscillator initialization. So the red part of the code can achieve the "seamless" switch of the external crystal oscillator to the internal crystal oscillator (if it is used in specific occasions such as: medical equipment can use this code), but because our product does not have very high requirements for real-time performance, I decided to restart the device and initialize the crystal oscillator.
Function three,
void NMI_Handler(void)
{
NMIException();
}
—————————————————I am a gorgeous dividing line———————————————————
The NMI_Handler() function is in the "stm32f0xx_it.c" in the STM32 library file. We put the crystal oscillator exception processing function in this non-shieldable exception interrupt function to achieve the equivalent of handling when the crystal oscillator is abnormal.
—————————————————I am a gorgeous dividing line———————————————————
int main(void)
{
SystemInit();
INIT_CLOCK(); //Initialize the system clock using the HSI clock
for(;;)
{
......
}
}
Previous article:STM32F103 clock configuration process
Next article:OK6410-Experimental Instruction Notes
- Popular Resources
- Popular amplifiers
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- LED chemical incompatibility test to see which chemicals LEDs can be used with
- Application of ARM9 hardware coprocessor on WinCE embedded motherboard
- What are the key points for selecting rotor flowmeter?
- LM317 high power charger circuit
- A brief analysis of Embest's application and development of embedded medical devices
- Single-phase RC protection circuit
- stm32 PVD programmable voltage monitor
- Introduction and measurement of edge trigger and level trigger of 51 single chip microcomputer
- Improved design of Linux system software shell protection technology
- What to do if the ABB robot protection device stops
- Huawei's Strategic Department Director Gai Gang: The cumulative installed base of open source Euler operating system exceeds 10 million sets
- Download from the Internet--ARM Getting Started Notes
- Learn ARM development(22)
- Learn ARM development(21)
- Learn ARM development(20)
- Learn ARM development(19)
- Learn ARM development(14)
- Learn ARM development(15)
- Analysis of the application of several common contact parts in high-voltage connectors of new energy vehicles
- Wiring harness durability test and contact voltage drop test method
- position2Go Review 1. Getting to know
- GigaDevice RISC-V GD32VF103 Development Board --- Data Summary
- DSP28335 phase register phase shift problem
- How to debug a program in RAM?
- C2000 ePWM Module
- [RVB2601 Creative Application Development] MQTT Remote Control RGB Ambient Light
- [Silicon Labs BG22-EK4108A Bluetooth Development Evaluation] Part 1: Environment Construction and Bluetooth-SOC Blinky Example
- esp32-cam micropythonlt anyone know how to make it? ?
- TouchGFX design——by supermiao123
- Stepper Motor Driver PVT Interpolation Case - PUSIROBOT