历史上的今天
今天是:2024年10月10日(星期四)
2018年10月10日 | STM32系统时钟的监控和切换
2018-10-10 来源:eefocus
在前一段时间的公司的项目中要求用到STM32这款处理器在外部晶振异常的情况下自动的切换到内部晶振,在网上找了N多的资料终于在网上找到了一个官方的研讨会的PPT里面简单的介绍了一下,于是顺着这个思路试着去编写代码,没想到官方提供的思路还蛮靠谱!
—————————————————我是华丽的分割线———————————————————![[转载]STM32系统时钟的监控和切换 [转载]STM32系统时钟的监控和切换](https://8.eewimg.cn/news/uploadfile/2018/1010/20181010094206148.jpg?imageView2/2/w/550)
![[转载]STM32系统时钟的监控和切换 [转载]STM32系统时钟的监控和切换](https://8.eewimg.cn/news/uploadfile/2018/1010/20181010094206834.jpg?imageView2/2/w/550)
![[转载]STM32系统时钟的监控和切换 [转载]STM32系统时钟的监控和切换](https://8.eewimg.cn/news/uploadfile/2018/1010/20181010094206145.jpg?imageView2/2/w/550)
—————————————————我是华丽的分割线———————————————————
函数一、
void INIT_CLOCK(void)
{
#if 1
ErrorStatus HSEStartUpStatus;
RCC_DeInit(); //复位RCC寄存器
RCC_HSEConfig(RCC_HSE_ON); //设置外部高速晶振 (HSE)
HSEStartUpStatus = RCC_WaitForHSEStartUp(); //等待 HSE 起振
#if 1
//判断外部晶振是否OK,如果OK就用外部晶振,如果不行,就用内部晶振,优先用外部晶振。
if(HSEStartUpStatus == SUCCESS)
{
RCC_ClockSecuritySystemCmd(ENABLE); //启动时钟安全系统 CSS
//外部晶振配置
RCC_HCLKConfig(RCC_SYSCLK_Div1); //设置ABH时钟(HCLK):HCLK=SYSCLK
//设置PLL时钟源及倍频系数, PLLCLK = HSE*PLLMul = 8*8 = 64MHz 实际是:8*8=64MHz
RCC_PLLConfig(RCC_PLLSource_PREDIV1, RCC_PLLMul_2);
RCC_PLLCmd(ENABLE); //使能PLL
//检查指定的RCC标志位设置与否
while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET); // Wait till PLL is ready
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); //设置系统时钟 (SYSCLK)
//返回作用系统时钟的时钟源
// Wait till PLL is used as system clock source
while(RCC_GetSYSCLKSource() != 0x08);
}
else
#endif
{
//内部晶振配置
RCC_DeInit(); //复位RCC寄存器
RCC_HSEConfig(RCC_HSE_OFF); //关闭外部晶(HSE)
RCC_HCLKConfig(RCC_SYSCLK_Div1); //设置ABH时钟(HCLK):HCLK=SYSCLK
//设置PLL时钟源及倍频系数, PLLCLK = HSI/2*PLLMul = 8/2*12 = 48MHz 实际是:48MHz
RCC_PLLConfig(RCC_PLLSource_HSI_Div2, RCC_PLLMul_12);
RCC_PLLCmd(ENABLE); //使能PLL
//检查指定的RCC标志位设置与否
//while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET); // Wait till PLL is ready
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); //设置系统时钟 (SYSCLK)
//返回作用系统时钟的时钟源
// Wait till PLL is used as system clock source
while(RCC_GetSYSCLKSource() != 0x08);
}
#endif
}
—————————————————我是华丽的分割线———————————————————
在上面哪一个函数中只有在外部晶振启动初始化中才启动了时钟安全系统(PS:红色加粗部分)因为只有外部晶振初始失败再切换至内部晶振,此函数是外部晶振启动优先只有外部晶振启动失败再去启动内部晶振。
函数二、
void NMIException(void)
{
if(RCC_GetITStatus(RCC_IT_CSS) != RESET)
{
#if 0 //内部晶振配置
RCC_DeInit(); //复位RCC寄存器
RCC_HSEConfig(RCC_HSE_OFF); //关闭外部晶(HSE)
RCC_HCLKConfig(RCC_SYSCLK_Div1); //设置ABH时钟(HCLK):HCLK=SYSCLK
//设置PLL时钟源及倍频系数, PLLCLK = HSI/2*PLLMul = 8/2*12 = 48MHz 实际是:48MHz
RCC_PLLConfig(RCC_PLLSource_HSI_Div2, RCC_PLLMul_12);
RCC_PLLCmd(ENABLE); //使能PLL
//检查指定的RCC标志位设置与否
//while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); //设置系统时钟 (SYSCLK)
//返回作用系统时钟的时钟源
// Wait till PLL is used as system clock source
while(RCC_GetSYSCLKSource() != 0x08);
CLKOUT_8M_INIT(); //PA8端口时钟输出为24025提供8MHz时钟
RCC_ITConfig(RCC_IT_HSIRDY,ENABLE); //使能 HSI就绪中断
RCC_ITConfig(RCC_IT_PLLRDY,ENABLE); //使能 PLL就绪中断
#else
NVIC_SystemReset(); //重启
RCC_ITConfig(RCC_IT_HSERDY,ENABLE); //使能 HSE就绪中断
RCC_ITConfig(RCC_IT_PLLRDY,ENABLE); //使能 PLL就绪中断
#endif
RCC_ClearITPendingBit(RCC_IT_CSS); //清除时钟安全系统中断的挂起位
}
}
—————————————————我是华丽的分割线———————————————————
NMIException()函数是晶振异常函数的处理函数在异常中断函数中调用此函数,红色部分是内部晶振初始如果所以红色部分的代码可以实现外部晶振“无缝”的切换到内部晶振(如果是用于特定的场合如:医疗设备可以使用此段代码),但由于我们产品对实时性要求不是很高我还是决定重新重启设备再初始化晶振。
函数三、
void NMI_Handler(void)
{
NMIException();
}
—————————————————我是华丽的分割线———————————————————
NMI_Handler()函数是在STM32的库文件中的“stm32f0xx_it.c”中的我们把晶振异常处理函数放置此不可屏蔽的异常中断函数中就可以实现晶振异常时的相当于处理。
—————————————————我是华丽的分割线———————————————————
int main(void)
{
SystemInit();
INIT_CLOCK(); //使用HSI时钟初始化系统时钟
for(;;)
{
......
}
}
上一篇:STM32F103时钟配置流程
下一篇:OK6410-实验指令笔记
史海拾趣
|
前段时间买了2440开发板也没怎么搞,惭愧:$ 最近没啥其它事情就好好啃啃吧,哎……没什么基础啊,先欣赏下别人的东西吧 【mini2440开发板实现国际象棋人机对弈 】 我在机子上跑了一下,好像不太能跟电脑对弈啊,不知道哪个地方还有问题 ...… 查看全部问答> |
|
上面这张令人震惊的照片展示了世界最高建筑哈利法塔遭闪电击中时的场面。 照片的拍摄者是一位23岁名叫穆罕默德·哈姆丹的学生,来自巴基斯坦,目前在阿联酋攻读建筑工程学。当时,迪拜正遭受暴风雨的袭击。雷电中,高达828米的哈利法塔在紫色的 ...… 查看全部问答> |
|
VC如何发彩信,已经实现ATDT*99***1#这一步了,下一步应该是什么,内容打包?如果打包? VC如何发彩信,已经实现ATDT*99***1#这一步了,下一步应该是什么,内容打包?如果打包? ATE AT+CMGF=0 AT+CIMI AT+CIMI获得IMSI IMSI 国际移动用户识别码(IMSI) international mobile subscriber identity 国际上为唯一识别 ...… 查看全部问答> |
|
/*进行SAA7121H的初始化*/ GPIO_RSET(GPVAL,0x0); addrI2C = 0xB8 >>1; /*选择第0路的I2C的地址*/ /*将第0路的视频输入口的数据口设为高阻状态, 使能SCLK,将第27脚设为输入*/ _IIC_write(hSeeddm642i2 ...… 查看全部问答> |
|
问题是这样的:我用flash烧写了一个控制电机的程序,不能运行,就把代码改了一下,再进行烧程序的时候就烧不进去啦,我也没有动“lock”和密码(在flash烧写的时候一直很小心的),怎么会锁住呢?很是不解。请EEWORLD老师和各位高手解答一下,谢谢 ...… 查看全部问答> |




