历史上的今天
今天是:2025年03月18日(星期二)
2019年03月18日 | STM32 HSE初始化失败的解决以及HSI初始化
2019-03-18 来源:eefocus

偶然遇到一个问题,假设HSE初始化失败怎么办,库函数内没有提供处理只是写了
if (HSEStatus == (uint32_t)0x01)
{
。。。
}
else
{ /* If HSE fails to start-up, the application will have wrong clock
configuration. User can add here some code to deal with this error */
}
让我们自己处理。平常我们都是用SysClk =72M。这是在HSE的情况下才能达到的。如果HSE初始化不成功只能使用HSI。注意上图时钟树HSI想使用PLL要2分频。这样才4M的频率。PLL倍频16也才64M。没有达到我们常用的72M。这样如果我们设置HSI并且16倍频像定时器等外设就要重新计算频率。(UARTx如果使用库函数是不需要自己计算波特率的,库函数内部会自己计算,这点不用担心)。用HSE时又要计算72M的对应数据,想想挺麻烦。为了方便在满足系统运行速度的情况下。我可以设置HSE通过PLLXTPRE位2分频然后PLL16倍频这样SYSCLK就达到64M。如果初始化HSE成功SYSCLK为64M,如果HSE初始化失败继续初始化HSI。这样一来无论内部时钟还是外部时钟都会是64M。
将代码贴在此处方便以后查看
u16 nCount = 0;
ErrorStatus HSEStartUpStatus;
//时钟管理重置
RCC_DeInit();
//打开外部晶振
RCC_HSEConfig(RCC_HSE_ON);
//等待外部晶振就绪
while (RCC_GetFlagStatus(RCC_FLAG_HSERDY) == RESET && nCount++ < HSE_STARTUP_TIMEOUT);
//等待外部晶振就绪
HSEStartUpStatus = RCC_WaitForHSEStartUp();
if (HSEStartUpStatus == SUCCESS)
{
//flash读取缓冲, 加速
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
//flash操作的延时
FLASH_SetLatency(FLASH_Latency_2);
//-----------------------------------------------------------------
//AHB使用系统时钟
RCC_HCLKConfig(RCC_SYSCLK_Div1);
//注:AHB主要负责外部存储器时钟。
//PB2负责AD, I/O, 高级TIM, 串口1
//APB2(高速)为HCLK
RCC_PCLK2Config(RCC_HCLK_Div1);
//APB1负责DA, USB, SPI, I2C, CAN, 串口2345, 普通TIM
//APB1(低速)为HCLK的一半
RCC_PCLK1Config(RCC_HCLK_Div2);
//???
RCC_ADCCLKConfig(RCC_PCLK2_Div4);
//倍频设置---------------------------------------------------------
*(vu32 *)0x40022000 = 0x01;
//PLLCLK = 8MHZ/2 *16 = 64MHZ
RCC_PLLConfig (RCC_PLLSource_HSE_Div2, RCC_PLLMul_16);
//启动PLL
RCC_PLLCmd(ENABLE);
//等待PLL启动
while (RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET);
//将PLL设置为系统时钟源
RCC_SYSCLKConfig (RCC_SYSCLKSource_PLLCLK);
//等待系统时钟源的启动
while (RCC_GetSYSCLKSource() != 0x08);
}
//HSE初始化失败,初始化内部HSI
else
{
RCC_HSEConfig(RCC_HSE_OFF);
//时钟管理重置
RCC_DeInit();
//打开内部晶振
RCC_HSICmd(ENABLE);
//等待内部晶振就绪
nCount = 0;
while(RCC_GetFlagStatus(RCC_FLAG_HSIRDY)== RESET && nCount++ < HSE_STARTUP_TIMEOUT );
//flash读取缓冲, 加速
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
//flash操作的延时
FLASH_SetLatency(FLASH_Latency_2);
//AHB使用系统时钟 64M
RCC_HCLKConfig(RCC_SYSCLK_Div1);
//注:AHB主要负责外部存储器时钟。
//PB2负责AD, I/O, 高级TIM, 串口1
//APB2(高速)为HCLK 64M
RCC_PCLK2Config(RCC_HCLK_Div1);
//APB1负责DA, USB, SPI, I2C, CAN, 串口2345, 普通TIM
//APB1(低速)为HCLK的一半 32M
RCC_PCLK1Config(RCC_HCLK_Div2);
//PLLCLK = 8MHZ/2 *16 = 64MHZ
RCC_PLLConfig(RCC_PLLSource_HSI_Div2, RCC_PLLMul_16);
//启动PLL
RCC_PLLCmd(ENABLE);
//将PLL设置为系统时钟源 64M
RCC_SYSCLKConfig (RCC_SYSCLKSource_PLLCLK);
//等待系统时钟源的启动
while (RCC_GetSYSCLKSource() != 0x08);
}
PS:如果使用SYSTICK注意此时的时钟频率是64M
void ConfigSysTick(void)
{
//SysTick时钟源为AHB HCLK时钟除以8, 即72/8 = 9MHZ
SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK_Div8);
//SysTick_Config(SystemCoreClock / 1000);
SysTick_Config(64000000 /1000);
}
史海拾趣
|
我设计了一个对话框,点一下button控件,能够把数据导入进来,存放在一个数组里。 之前,我是把代码写在这个控件的函数里,但我现在想把这些数据存放在自己设计的一个类里,方便以后调用,请问如何设计?… 查看全部问答> |
|
我需要实现的功能为: 1、按下启动按钮,电机启动,V1卸荷阀受电打开。 2、时间继电器受电,设定时间后触点断开,V1卸荷阀关闭 2、再按下启动按钮,V2电磁阀受电,电池阀工作,液压泵站输出压力 3、松开启动按钮,V2电池阀失电,压力消 ...… 查看全部问答> |
|
28035 DSP开发板实验例程和手册全套发布(例程部分之二) TMS320F28035是TI新推出的Piccolo系列DSP之一,它具有很高的性价比和出色的DSP控制性能。对于入门来说,它比2812更适合:单电源供电,主频适中(60MHZ),附带一个浮点运算核,价格也没有2812那样有时贵得离谱。同样具有增强型eCAN、SPI,SCI等通信接 ...… 查看全部问答> |
|
求救于各路大侠,本人编了一个驱动 P2_7 LED的小程序,结果出现错误Error: L6218E:,源代码如下: c函数和头文件都是基于 ration的汉化说明版本。 #include \"nxplpc11xx.h\" #define CS_H &n ...… 查看全部问答> |
|
RT-Thread 1.0.1是1.0.0版本的bug修正版,仅在原来的基础上对已有的功能进行修正(新功能基本上没有)。1.0.1版本相对于1.0.0版本的更改:内核- 修正rt_sem_control/rt_event_control/rt_mb_control/rt_mq_control中可能引起的任务未及时调度的问题 ...… 查看全部问答> |
|
JLINK下载报错: Could not initialize target device! Please power cycle the board and try again. 是不是LM3S9B96芯片flash被锁了,应该如何修复?… 查看全部问答> |




