LL_RCC_HSE_Enable(); while (LL_RCC_HSE_IsReady() != 1) { }
从代码上面分析,程序在获取外部晶振的状态时失败,即外部晶振未起振。
在与该网友询问后,该段代码生成自stm32cubemx。后经查找官方示例,官方示例又恰巧全部使用了内部晶振,即HSI来做为STM32C031的系统时钟,又避开了HSE的问题。难道是STM32C031的外部时钟有问题,官方也是避之?——这样的bug不会出现在流片,更不会发生在ST这样的大厂。
既然ST官方的芯片不会出山问题,那问题一定出在了配置侧,即我的代码哪里还有不完善的地方。于是,返回时钟配置界面,再仔细查看。
从上图的下拉菜单里,我们可以看到,C031芯片对于外部晶振是支持两种模式。不会是模式选择错误了吧?再返过头查看代码,看到晶振初始化代码里,并没有HSE的输入源类型选择。这时,我再使用仿真器回读了RCC寄存器的数值,看到对于HSE的类型上,默认的输入源还真是“bypass clock source”。我通过仿真器将其修改为“Crystal/Ceramic”类型后,再次运行程序,则HSE晶振成功初始化。
至此,STM32C031晶振不起振的原因到了。因为修改默认的HSE类型为Crystal/Ceramic晶振即可。为了规避此类问题的再次发生,将晶振初始化程序修改为下面的内容即可。
/** * @brief System Clock Configuration * @retval None */ void SystemClock_Config_HSE(void) { LL_FLASH_SetLatency(LL_FLASH_LATENCY_1); /* HSE configuration and activation */ LL_RCC_HSE_DisableBypass(); LL_RCC_HSE_Enable(); while (LL_RCC_HSE_IsReady() != 1) { } /* Set AHB prescaler*/ LL_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_1); /* Sysclk activation on the HSE */ LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_HSE); while (LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_HSE) { } /* Set APB1 prescaler*/ LL_RCC_SetAPB1Prescaler(LL_RCC_APB1_DIV_1); LL_SetSystemCoreClock(48000000); }