STM32F103C8通过CubeMX生成系统时钟配置异常求助
我之前也踩过CubeMX生成STM32F1时钟配置不生效、默认跑内部RC的坑,结合你提到的定时器和USART因为时钟异常出问题的情况,给你梳理下排查和解决的关键点:
排查CubeMX时钟配置失效的核心步骤
首先先把你给出的SystemInit()代码片段贴出来方便对照:
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 */ RCC->CFGR &= (uint32_t)0xF8FF0000; /* 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; /* Disable all interrupts and clear pending bits */ RCC->CIR = 0x00000000; /* Configure the System clock frequency, HCLK, PCLK2 and PCLK1 prescalers */ /* Configure the Flash Latency cycles and enable prefetch buffer */ SetSysClock(); }
1. 先确认CubeMX的配置是否真的被保存
- 打开你的
.ioc工程,进入Clock Configuration页面,检查你设置的目标时钟参数(比如HSE晶振频率、PLL倍频系数、总线分频比)是否正确,一定要点击顶部工具栏的Apply Configuration(对勾图标)保存配置——很多时候就是忘了这一步,导致生成代码时还是用默认模板。 - 去Project Manager -> Settings里看Toolchain/IDE选项,别勾选“Generate under root”这类可能覆盖配置的选项,避免旧文件干扰。
2. 检查SetSysClock()函数的实现
SystemInit()最后调用的SetSysClock()才是真正执行时钟配置的核心函数:
- 如果CubeMX正确生成了你的时钟配置,这个函数里应该有HSE使能、PLL参数设置、时钟源切换的代码;如果它只做了HSI启用的操作,说明配置根本没被应用。
- 这时候可以尝试:删除工程目录下除了
.ioc之外的所有自动生成文件,关闭CubeMX再重新打开.ioc生成代码;或者新建一个空白工程,重新配置引脚和时钟,对比生成的代码差异,排查原.ioc是否损坏。
3. 确认工程编译时用的是最新生成的文件
有时候工程里可能残留了手动添加的旧版system_stm32f1xx.c,编译时优先链接了旧文件,导致新配置失效:
- 在IDE(Keil/STM32CubeIDE等)里检查工程文件列表,确保只有CubeMX生成的
system_stm32f1xx.c被包含,旧文件要么删除要么从工程中移除。 - 清理编译缓存(比如Keil的Clean、CubeIDE的Project -> Clean),然后重新全量编译。
4. 排查是否有代码覆盖了时钟配置
有些时候会在main()函数开头或者其他初始化函数里手动修改RCC寄存器,覆盖了CubeMX的配置:
- 检查
main.c的main()函数,以及HAL_Init()之后的代码,看是否有直接操作RCC寄存器或者调用自定义时钟配置函数的逻辑。
5. STM32F1的特殊硬件注意事项
- 如果用了外部晶振,要确保硬件上晶振和匹配电容已经正确焊接,否则HSE无法起振,部分HAL库版本会自动 fallback 到HSI。可以通过读取
RCC->CR寄存器的HSERDY位来判断HSE是否成功起振。 - 去CubeMX的Pinout & Configuration -> RCC选项,确认HSE模式设置的是
Crystal/Ceramic Resonator,而不是默认的Disabled。
内容的提问来源于stack exchange,提问作者AC Voltage




