第二章:SystemInit系统初始化函数详解

本文深入探讨了STM32F4系列微控制器的SystemInit函数,详细解释了如何在系统初始化阶段设置带FPU的ARM Cortex-M4内核。同时,提到了STM32F4xxx.h头文件中关于浮点运算的宏定义,为理解FPU在嵌入式系统中的应用提供了关键信息。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

void SystemInit(void)
{
  /* FPU settings ------------------------------------------------------------*/
  #if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
    SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2));  /* set CP10 and CP11 Full Access */
  #endif

  /* Reset the RCC clock configuration to the default reset state ------------*/


//1、PRRCC控制寄存器RCC_CR 主要是PLL和PLLI2S的使能和状态、外部时钟的使能、内部时钟的校准、修正、状态、使能等
//2、PLL配置寄存器RCC_PLLCFGR 是关于PLL输出时钟的计算公司参数的设定,PLLQ/PLLP/PLLN/PLLM等
//3、RCC时钟配置寄存器RCC_CFGR 是设置输出时钟MCO12、RTC时钟分频、I2C时钟选择、AHB/APB1/APB2等时钟的分频、系统时钟的切换等。
//4、RCC时钟中断寄存器RCC_CIR 主要是各种时钟稳定后触发中断的使能以及相关的标志清零
//5、RCC_AHB1、AHB2、AHB3、APB1、APB2总线相关的寄存器主要是SET和RESET各种外设的时钟源
<think>好的,我现在要回答用户关于STM32SystemInit函数调用时机以及是否需要显式调用的问题。首先,我需要回顾一下自己对STM32启动流程的理解,特别是系统初始化的部分。 用户的问题集中在SystemInit函数的调用时间和是否需要显式调用它。我记得在STM32的标准库中,启动文件(startup_stm32fxxx.s)会在复位后首先执行SystemInit函数,然后再跳转到main函数。所以,大部分情况下用户不需要自己调用这个函数,因为启动代码已经处理了。但可能有些特殊情况,比如用户自己修改了启动文件,或者使用了不同的库,这时候可能需要显式调用。 接下来,我需要确认各个引用内容中的信息是否支持我的记忆。引用[2]提到SystemInit和SetSysClockTo72函数的作用,并指出需要理解时钟框图。引用[4]和[5]详细描述了SystemInit的配置步骤,比如配置HSE、PLL等,最终设置系统时钟为72MHz。引用[3]提到SystemInit属于库函数的一部分,可能用户在学习时需要了解它的调用时机。 用户可能想知道,如果在main函数中再次调用SystemInit会不会有问题。通常来说,SystemInit会重新配置时钟,如果在程序运行中调用可能会导致时钟设置被重置,影响外设的工作。但默认情况下,启动文件已经调用了,所以不需要在main里再调用。 另外,是否需要显式调用可能取决于项目配置。比如,如果使用HAL库,可能初始化流程有所不同,但标准库的话,启动文件已经处理好了。用户如果自己编写启动代码,可能需要显式调用,但这种情况较少见。 总结一下,回答应该包括以下几点: 1. SystemInit的调用时机是在启动阶段,由启动文件自动调用。 2. 一般情况下不需要显式调用,除非有特殊需求。 3. 显式调用可能导致的问题,比如重复配置时钟。 4. 不同库或配置下的情况差异,比如标准库和HAL库的区别。 同时,生成的相关问题要围绕SystemInit的作用、时钟配置步骤、不同库中的处理方式等展开。</think>在STM32开发中,`SystemInit`函数是时钟系统初始化的核心函数,其调用时机与显式调用需求如下: ### 1. **调用时机** - **自动调用**:在标准库(如STM32F1xx/F4xx标准外设库)中,`SystemInit`函数**启动文件**(例如`startup_stm32f10x.s`)在系统复位后**自动调用**,早于`main`函数的执行[^2][^4][^5]。 - **执行顺序**:启动文件首先初始化堆栈指针,然后调用`SystemInit`完成时钟配置(如HSE/PLL使能、系统时钟源选择),最后跳转到`main`函数- **无需手动干预**:开发者通常无需显式调用`SystemInit`,除非需要**重新配置系统时钟**(如动态切换时钟源)。 ### 2. **是否需要显式调用?** - **标准库场景**:无需显式调用。启动文件已确保时钟初始化完成,直接使用默认配置(如72MHz SYSCLK)即可。 - **特殊需求场景**- 若需修改默认时钟配置(如超频或降频),可在`main`函数中重新调用`SystemInit`或手动调整时钟寄存器。 - 若使用**自定义启动文件****非标准库**(如HAL库),需检查是否已集成`SystemInit`调用逻辑[^3]。 - **注意**:重复调用可能导致时钟参数被覆盖,需谨慎处理外设依赖的时钟频率。 ### 3. **函数作用详解** `SystemInit`主要完成以下操作[^4]: 1. 使能HSE(外部高速时钟)并等待就绪。 2. 配置PLL参数(M/N/P分频系数),生成目标频率(如72MHz)。 3. 切换系统时钟源至PLL输出。 4. 设置AHB/APB总线分频系数(如APB1=36MHz, APB2=72MHz)。 5. 更新全局变量`SystemCoreClock`,反映当前系统时钟频率。 ### 4. **代码示例(标准库调用流程)** ```c // 启动文件自动调用SystemInit void SystemInit(void) { // 具体实现参考库文件,如配置Flash延迟、复位时钟等 } int main(void) { // 此时系统时钟已初始化完成,可直接使用 while(1) { // 用户代码 } } ``` ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值