欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 新闻 > 国际 > STM32学习 修改系统主频

STM32学习 修改系统主频

2024/10/25 4:55:15 来源:https://blog.csdn.net/m0_60633015/article/details/139904915  浏览:    关键词:STM32学习 修改系统主频

前面时钟树的学习说明单片机的主频是可以修改的,那么怎么更改系统的主频,这里做一个简单的介绍。首先要明白,单片机的程序是如何运行,这里简单说明一下。

对应的代码在startup_stm32....文件里面,这里是复位程序的汇编代码。

复位子程序是系统上电后第一个执行的程序,调用 SystemInit 函数初始化系统时钟,然后调用 C 库函数 _mian,最终调用 main 函数去到 C 的世界。

WEAK:表示弱定义,如果外部文件优先定义了该标号则首先引用该标号,如果外部文件没有声 明也不会出错。这里表示复位子程序可以由用户在其他文件重新实现,这里并不是唯一的。 IMPORT:表示该标号来自外部文件,跟 C 语言中的 EXTERN 关键字类似。这里表示 SystemInit 和 __main 这两个函数均来自外部的文件。

SystemInit() 是一个标准的库函数,在 system_stm32f103xe.c 这个库文件中定义。主要作用是配置 系统时钟,这里调用这个函数之后,单片机的系统时钟配被配置为 72M。

__main 是一个标准的 C 库函数,主要作用是初始化用户堆栈,并在函数的最后调用 main 函数去 到 C 的世界。这就是为什么我们写的程序都有一个 main 函数的原因。

所以更改主频应该找到SystemInit()函数,这个函数在system_stm32f10x.c文件中。这里给出一个详细的代码。

void SystemInit (void)
{/* Reset the RCC clock configuration to the default reset state(for debug purpose) *//* Set HSION bit */RCC->CR |= (uint32_t)0x00000001;/* Reset SW, HPRE, PPRE1, PPRE2, ADCPRE and MCO bits */
#ifndef STM32F10X_CLRCC->CFGR &= (uint32_t)0xF8FF0000;
#elseRCC->CFGR &= (uint32_t)0xF0FF0000;
#endif /* STM32F10X_CL */   /* Reset HSEON, CSSON and PLLON bits */RCC->CR &= (uint32_t)0xFEF6FFFF;/* Reset HSEBYP bit */RCC->CR &= (uint32_t)0xFFFBFFFF;/* Reset PLLSRC, PLLXTPRE, PLLMUL and USBPRE/OTGFSPRE bits */RCC->CFGR &= (uint32_t)0xFF80FFFF;#ifdef STM32F10X_CL/* Reset PLL2ON and PLL3ON bits */RCC->CR &= (uint32_t)0xEBFFFFFF;/* Disable all interrupts and clear pending bits  */RCC->CIR = 0x00FF0000;/* Reset CFGR2 register */RCC->CFGR2 = 0x00000000;
#elif defined (STM32F10X_LD_VL) || defined (STM32F10X_MD_VL) || (defined STM32F10X_HD_VL)/* Disable all interrupts and clear pending bits  */RCC->CIR = 0x009F0000;/* Reset CFGR2 register */RCC->CFGR2 = 0x00000000;      
#else/* Disable all interrupts and clear pending bits  */RCC->CIR = 0x009F0000;
#endif /* STM32F10X_CL */#if defined (STM32F10X_HD) || (defined STM32F10X_XL) || (defined STM32F10X_HD_VL)#ifdef DATA_IN_ExtSRAMSystemInit_ExtMemCtl(); #endif /* DATA_IN_ExtSRAM */
#endif /* Configure the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers *//* Configure the Flash Latency cycles and enable prefetch buffer */SetSysClock();#ifdef VECT_TAB_SRAMSCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM. */
#elseSCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH. */
#endif 
}

其中是复杂的宏定义,抛开未被使用到的部分,两个重要的函数

SystemInit_ExtMemCtl()//外部时钟的引脚配置函数

SetSysClock()//时钟初始化函数

接下来看这两个函数是如何定义的

可以看到这个文档里面给出了一些宏定义,这个就是系统的频率,选定哪个,就是设定哪个频率,这里就以72MHZ为例子看是如何配置时钟的,在文档中搜索一些使用到72MHZ的地方。可以看到如果宏定义了SYSCLK_FREQ_72MHz,那 SystemCoreClock=SYSCLK_FREQ_72MHz并且定义了一个SetSysClockTo72()的函数。并且在SetSysClock()中使用SetSysClockTo72()函数。SetSysClockTo72()函数里面进行了详细的配置是系统的频率达到72MHZ。

SystemInit_ExtMemCtl()中就是对一些外部时钟引脚的定义

void SystemInit_ExtMemCtl(void) 
{
/*!< FSMC Bank1 NOR/SRAM3 is used for the STM3210E-EVAL, if another Bank is required, then adjust the Register Addresses *//* Enable FSMC clock */RCC->AHBENR = 0x00000114;/* Enable GPIOD, GPIOE, GPIOF and GPIOG clocks */  RCC->APB2ENR = 0x000001E0;GPIOD->CRL = 0x44BB44BB;  GPIOD->CRH = 0xBBBBBBBB;GPIOE->CRL = 0xB44444BB;  GPIOE->CRH = 0xBBBBBBBB;GPIOF->CRL = 0x44BBBBBB;  GPIOF->CRH = 0xBBBB4444;GPIOG->CRL = 0x44BBBBBB;  GPIOG->CRH = 0x44444B44;/*----------------  FSMC Configuration ---------------------------------------*/  
/*----------------  Enable FSMC Bank1_SRAM Bank ------------------------------*/FSMC_Bank1->BTCR[4] = 0x00001011;FSMC_Bank1->BTCR[5] = 0x00000200;
}

使用的F103系列的引脚是GPIOD,所以可以看到使用寄存器的方式配置了相关的引脚,能够使用外部晶振。 

最终调用SystemInit()完成时钟的配置,所以只要在宏定义处使用官方配置好的一些就行,如果想要自己定义,就要重新编写寄存器相关的操作。

参考资料

STM32标准库修改HSI时钟教程_stm32 l011 hsi 时钟 不准确-CSDN博客

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com