先上时钟树,从时钟树可以看到,HSI作时钟,最大只能输出8MHz,要输出更高频率,要用PLLCLK。
HSI要先2分频,然后PLLSRC选择HSI,再进入PLL进行倍频,设置PLLCLK为SYSYCLK,这样才能超频输出。
从图上看,AHB,APB2最大能达到72MHz的,而APB1只能达到36MHz。
实际上,我们用HSI的话,时钟源是8MHz,二分频后,变成4MHz了,倍频最大是16倍,所以最大频率是64MHz。
HSI配置,可以参考system_stm32f10x.c文档中的HSE配置,流程如下:
1.因系统已经运行起来了,所以需要先复位RCC,不然寄存器中有些值是改不动的。
2.开启HSI。
3.设置flash预取缓冲器和延迟周期。
4.设置AHB、APB2、APB1分频系数。
5.设置PLLMUL倍频系数。
6.开启PLL。
7.切换系统时钟为PLL。
代码大部分都是system_stm32f10x.c文档中的SetSysClockToxx()中搬过来的,代码如下:
void SetSysClockToHSI(uint32_t pllmul)
//这里定义了一个pllmul的变量,这个值需要从stm32f10x.h文档中选,RCC_CFGR_PLLMULL2 - 16
{
//RCC复位,为了方便,直接调用库函数,这个函数和启动时调用的SystemInit()大部分是一样的。
RCC_DeInit();
//开启HSI
RCC->CR |= (uint32_t)0x00000001;
//等待HSI就绪完成的标志
while((RCC->CR & RCC_CR_HSIRDY) == 0){}
//开启Flash预存取缓冲区
FLASH->ACR |= FLASH_ACR_PRFTBE;
//Flash延迟周期设置,FLASH_ACR_LATENCY_0:0~24MHz;1:24~48MHz;2:48~72MHz
FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY);
FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_2;
//AHB不分频,APB2不分频,APB1 2分频
//APB1不能大于36MHz,36MHz及以下频率可以不分频,即设为RCC_CFGR_PPRE1_DIV1
RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;
RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;
RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2;
//设置PLL倍数
RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLMULL));
RCC->CFGR |= pllmul;
//开启PLL,等待就绪
RCC->CR |= RCC_CR_PLLON;
while((RCC->CR & RCC_CR_PLLRDY) == 0){}
//设置PLL为时钟源
RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL;
//等待就绪
while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08){}
}
这样就配置完成了,假如要用48MHz频率,可以在main函数里这么写:
SetSysClockToHSI(RCC_CFGR_PLLMULL12);
假如要64MHz频率:
SetSysClockToHSI(RCC_CFGR_PLLMULL16);