闲来无事突然对32的超频来了兴趣。其实是学校有个实训,给的单片机是STM32F1做,想着能弄的更好点就想着把F1超频一下,感觉能完成更多的事情吧。
平台是淘宝上通用的ST32F103C8T6最小系统板。
看了正点原子的论坛之后感觉,虽然很多大佬都超频过,但是具体超频的方法好像没有路子,我查了好久是没有查到。可能太简单了,大佬们都懒得写。一开始确实是无从下手,不过弄懂之后也感觉确实是不难。不过我感觉我改的有点弄巧成拙,确实不是很好,各位大佬如果有更好的方法也可以指出,小弟虚心求教。而且我似乎是只改了主频,还有外设等等一堆频率没有动,我感觉这个东西应该是牵一发而动全身,所以说暂时应该也只是一个半成品。
首先是查了《STM32不完全手册_库函数版本_V3.1》这个PDF,上面虽然说得简单,但是都是对的而且给了我一个大概的方向。然后又认真看了遍时钟树,但是还是很懵,英文差的一塌糊涂。
言归正传,开始说方法。主要就是system_stm32f10x.c这个文件。对这个文件稍加修改就可以了。这个文件里面采用了大量的条件编译,就是给使用者选择频率的,文件里面最大的频率是72M。红色部分是我自己添加的一点代码。
#ifdef SYSCLK_FREQ_HSE。
#ifdef SYSCLK_FREQ_HSE。
uint32_t SystemCoreClock = SYSCLK_FREQ_HSE; /*!< System Clock Frequency (Core Clock) */
#elif defined SYSCLK_FREQ_24MHz
uint32_t SystemCoreClock = SYSCLK_FREQ_24MHz; /*!< System Clock Frequency (Core Clock) */
#elif defined SYSCLK_FREQ_36MHz
uint32_t SystemCoreClock = SYSCLK_FREQ_36MHz; /*!< System Clock Frequency (Core Clock) */
#elif defined SYSCLK_FREQ_48MHz
uint32_t SystemCoreClock = SYSCLK_FREQ_48MHz; /*!< System Clock Frequency (Core Clock) */
#elif defined SYSCLK_FREQ_56MHz
uint32_t SystemCoreClock = SYSCLK_FREQ_56MHz; /*!< System Clock Frequency (Core Clock) */
#elif defined SYSCLK_FREQ_72MHz
uint32_t SystemCoreClock = SYSCLK_FREQ_72MHz; /*!< System Clock Frequency (Core Clock) */
#elif defined SYSCLK_FREQ_CHAOPIN
uint32_t SystemCoreClock = SYSCLK_FREQ_CHAOPIN;
#else /*!< HSI Selected as System Clock source */
uint32_t SystemCoreClock = HSI_VALUE; /*!< System Clock Frequency (Core Clock) */
#endif
static void SetSysClock(void);
static void SetSysClock(void);
#ifdef SYSCLK_FREQ_HSE
static void SetSysClockToHSE(void);
#elif defined SYSCLK_FREQ_24MHz
static void SetSysClockTo24(void);
#elif defined SYSCLK_FREQ_36MHz
static void SetSysClockTo36(void);
#elif defined SYSCLK_FREQ_48MHz
static void SetSysClockTo48(void);
#elif defined SYSCLK_FREQ_56MHz
static void SetSysClockTo56(void);
#elif defined SYSCLK_FREQ_72MHz
static void SetSysClockTo72(void);
#elif defined SYSCLK_FREQ_CHAOPIN
static void SetSysClockToCHAOPIN(void);
#endif
static void SetSysClock(void)
static void SetSysClock(void)
{
#ifdef SYSCLK_FREQ_HSE
SetSysClockToHSE();
#elif defined SYSCLK_FREQ_24MHz
SetSysClockTo24();
#elif defined SYSCLK_FREQ_36MHz
SetSysClockTo36();
#elif defined SYSCLK_FREQ_48MHz
SetSysClockTo48();
#elif defined SYSCLK_FREQ_56MHz
SetSysClockTo56();
#elif defined SYSCLK_FREQ_72MHz
SetSysClockTo72();
#elif defined SYSCLK_FREQ_CHAOPIN
SetSysClockToCHAOPIN();
#endif
/* If none of the define above is enabled, the HSI is used as System clock
source (default after reset) */
}
频率设置宏定义
#else //频率设置宏定义在这里
/* #define SYSCLK_FREQ_HSE HSE_VALUE */
/* #define SYSCLK_FREQ_24MHz 24000000 */
/* #define SYSCLK_FREQ_36MHz 36000000 */
/* #define SYSCLK_FREQ_48MHz 48000000 */
/* #define SYSCLK_FREQ_56MHz 56000000 */
//#define SYSCLK_FREQ_72MHz 72000000
#define SYSCLK_FREQ_CHAOPIN 120000000 //在这里修改频率
#endif
又在#elifdefined SYSCLK_FREQ_72MHz后面加了一个#elif defined SYSCLK_FREQ_CHAOPIN
#elif defined SYSCLK_FREQ_CHAOPIN
/**
* @brief Sets System clock frequency to nMHz and configure HCLK, PCLK2
* and PCLK1 prescalers.
* @note This function should be used only after reset.
* @param None
* @retval None
*/
static void SetSysClockToCHAOPIN(void)
{
__IO uint32_t StartUpCounter = 0, HSEStatus = 0;
/* SYSCLK, HCLK, PCLK2 and PCLK1 configuration ---------------------------*/
/* Enable HSE */
RCC->CR |= ((uint32_t)RCC_CR_HSEON);
/* Wait till HSE is ready and if Time out is reached exit */
do
{
HSEStatus = RCC->CR & RCC_CR_HSERDY;
StartUpCounter++;
} while((HSEStatus == 0) && (StartUpCounter != HSE_STARTUP_TIMEOUT));if ((RCC->CR & RCC_CR_HSERDY) != RESET)
{
HSEStatus = (uint32_t)0x01;
}
else
{
HSEStatus = (uint32_t)0x00;
}if (HSEStatus == (uint32_t)0x01)
{
/* Enable Prefetch Buffer */
FLASH->ACR |= FLASH_ACR_PRFTBE;/* Flash 2 wait state */
FLASH->ACR &= (uint32_t)((uint32_t)~FLASH_ACR_LATENCY);
FLASH->ACR |= (uint32_t)FLASH_ACR_LATENCY_2;
/* HCLK = SYSCLK */
RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1;
/* PCLK2 = HCLK */
RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1;
/* PCLK1 = HCLK */
RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2;#ifdef STM32F10X_CL
/* Configure PLLs ------------------------------------------------------*/
/* PLL2 configuration: PLL2CLK = (HSE / 5) * 8 = 40 MHz */
/* PREDIV1 configuration: PREDIV1CLK = PLL2 / 5 = 8 MHz */
RCC->CFGR2 &= (uint32_t)~(RCC_CFGR2_PREDIV2 | RCC_CFGR2_PLL2MUL |
RCC_CFGR2_PREDIV1 | RCC_CFGR2_PREDIV1SRC);
RCC->CFGR2 |= (uint32_t)(RCC_CFGR2_PREDIV2_DIV5 | RCC_CFGR2_PLL2MUL8 |
RCC_CFGR2_PREDIV1SRC_PLL2 | RCC_CFGR2_PREDIV1_DIV5);
/* Enable PLL2 */
RCC->CR |= RCC_CR_PLL2ON;
/* Wait till PLL2 is ready */
while((RCC->CR & RCC_CR_PLL2RDY) == 0)
{
}
/* PLL configuration: PLLCLK = PREDIV1 * 9 = 72 MHz */
RCC->CFGR &= (uint32_t)~(RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLSRC | RCC_CFGR_PLLMULL);
RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLXTPRE_PREDIV1 | RCC_CFGR_PLLSRC_PREDIV1 |
RCC_CFGR_PLLMULL9);
#else
/* PLL configuration: PLLCLK = HSE * n = 8*n MHz */
RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_PLLSRC | RCC_CFGR_PLLXTPRE | RCC_CFGR_PLLMULL));
RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL15); //修改乘积倍数
#endif /* STM32F10X_CL *//* Enable PLL */
RCC->CR |= RCC_CR_PLLON;/* Wait till PLL is ready */
while((RCC->CR & RCC_CR_PLLRDY) == 0)
{
}
/* Select PLL as system clock source */
RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW));
RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL;/* Wait till PLL is used as system clock source */
while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08)
{
}
}
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 */
}
}#endif
大概是修改了这么多内容
个人理解是每次超频应该都是8MHz的倍数,因为晶振是8M的,后面经过不断的倍频产生各种的频率。
RCC_CFGR_PLLMULL15这个是一个宏定义,打开后是一堆数字,不用管那么多,基本上最后两个数字15代表了对8M15倍频的意思,然后对应的8M*15=120000000 修改到#define SYSCLK_FREQ_CHAOPIN 120000000 这条语句上面就可以了
然后是对结果的验证
本人采用了__NOP();这个函数,因为这个函数的执行速度全部却决于主频。
LED0=1;
for(i=0;i<5000000;i++)__NOP();
LED0=0;
for(i=0;i<5000000;i++)__NOP();
主函数里面循环让灯闪
拍视频手机的延迟比较大,所以就不拍了。
第一次灯闪的时候按下秒表,至第三次灯闪的时候停止,在72M下耗时10.01s,在120M下耗时6.02s。
10.01/6.02和120/72应该是差不多的。