前言
STM32F1x系列官方推荐最大系统时钟频率为72MHz,今天看时钟树时发现其可以进行超频,PLL锁相环最大支持16倍频,所以笔者尝试了一下用外界的8MHz晶振进行倍频至128MHz的实验。
1.代码部分
1.初始化配置RCC和MCO模式的gpio
#include "stm32f10x.h"
/*初始化RCC并配置系统时钟频率*/
void HSE_Init(uint32_t RCC_PLLMul_x)//范围2-16
{
//ErrorStatus HSEStatus;//定义
__IO uint32_t HSEStatus=0;
//重置RCC,否则不会有效果
RCC_DeInit();
//使能HSE
RCC_HSEConfig(RCC_HSE_ON);
//获取HSI状态,等待HSI稳定
HSEStatus=RCC_WaitForHSEStartUp();
//判断HSE的状态,是否已启动
if(HSEStatus==SUCCESS)
{
//flash预取指使能
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
//flash预取指等待时间配置
FLASH_SetLatency(FLASH_Latency_2);
//对AHB APB1 APB2分频
RCC_HCLKConfig( RCC_SYSCLK_Div1 );
RCC_PCLK1Config( RCC_HCLK_Div2 );
RCC_PCLK2Config( RCC_HCLK_Div1 );
//配置PLL时钟源和倍频因子(官方库中声明要先设置后打开PLL)
RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_x);
//使能PLL
RCC_PLLCmd(ENABLE);
//等待PLL状态稳定后跳出语句
while( RCC_GetFlagStatus( RCC_FLAG_PLLRDY) == RESET);
//等待系统时钟切换完成
RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK );
while(RCC_GetSYSCLKSource()!=0x08);
}
else
{
//HSE启动识别,当启动错误时在此操作
}
}
/*初始化MCO的GPIO口,用以检测观察系统时钟的频率*/
void MCO_Init()
{
GPIO_InitTypeDef GPIO_InitStruct;
//打开外设时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
//配置外设,初始化结构体
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_8;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
//调用外设初始化函数,将配置好的结构体成员写入寄存器
GPIO_Init(GPIOA, &GPIO_InitStruct);
}
2.flash预取
//flash预取指使能
FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
//flash预取指等待时间配置
FLASH_SetLatency(FLASH_Latency_2);
在stm32中,代码存放在flash中的,程序运行时内核要读flash中的code,它的过程是一条一条读,一条一条执行的。
芯片在运行过程中,CPU的运行速度比FLASH的存取速度要快很多,为了使芯片在运行时不被Flash拖慢速度,所以M3内核对于读完第一条,还没读第二条代码时,就先会把将要读的第二条代码先取好,放好等待它去读,这个过程称为预取指。
系统时钟频率速度越快,CPU等待flash预取的时间周期就越长,但在手册中最大等待周期只有两个,所以超频官方是不支持的,如果要超频就要对芯片运行时的稳定性有所考量。
3.主函数
#include "stm32f10x.h"
#include "clk.h"
int main(void)
{
HSE_Init(RCC_PLLMul_16);
MCO_Init();
//MCO时钟来源选择系统时钟
RCC_MCOConfig(RCC_MCO_SYSCLK);
while(1)
{
}
}
3. 实验现象
示波器探头检测PA5口观测系统时钟波形。
总结
超过最大主频72MHz,有会存在一些潜在的风险。比如:时序紊乱,程序跑飞,芯片发热等。
所以超频工作需要考虑实际情况和环境因素。比如干扰特别大的环境,一般不建议超频。