IAR Workbench仿真STM32G0时卡在等待PLL就绪环节的问题求助
IAR Workbench仿真STM32G0时卡在等待PLL就绪环节的问题求助
你遇到的这个问题其实挺常见的,刚接触STM32仿真的时候很容易踩这个坑😉。我来给你分析下原因和解决办法:
首先得明白:IAR的仿真器虽然能模拟很多STM32外设行为,但默认情况下并不会主动触发像PLL就绪(PLLRDY)这类硬件寄存器的状态变化——毕竟仿真环境里没有真实的硬件PLL模块在工作,自然不会自己把这个标志位置1,程序就会一直卡在那个while循环里。
下面是几个实用的解决办法,你可以根据需求选:
1. 修改代码适配仿真环境(推荐长期用)
你可以通过预编译指令,让代码在仿真模式下跳过PLL等待,或者直接改用HSI作为系统时钟(不需要PLL)。
方案A:跳过PLL等待循环
在项目的编译选项里先定义一个SIMULATOR宏(路径:Project > Options > C/C++ Compiler > Preprocessor > Defined symbols,添加SIMULATOR),然后修改时钟配置里的等待代码:
/* Wait till PLL is ready */ #ifdef SIMULATOR // 仿真模式下直接跳过等待,无真实硬件PLL无需等待就绪 #else uint32_t tickstart = HAL_GetTick(); while (READ_BIT(RCC->CR, RCC_CR_PLLRDY) == 0U) { if ((HAL_GetTick() - tickstart) > PLL_TIMEOUT_VALUE) { return HAL_TIMEOUT; } } #endif
方案B:仿真时改用HSI时钟
如果不想用PLL,也可以直接在仿真模式下切换到HSI作为系统时钟,这样连PLL初始化都可以跳过:
void SystemClock_Config(void) { #ifdef SIMULATOR // 仿真环境下使用HSI作为系统时钟 RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; // 启用HSI振荡器 RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI; RCC_OscInitStruct.HSIState = RCC_HSI_ON; RCC_OscInitStruct.HSIDiv = RCC_HSI_DIV1; RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { Error_Handler(); } // 配置系统时钟源为HSI RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK |RCC_CLOCKTYPE_PCLK1; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK) { Error_Handler(); } #else // 真实硬件上的时钟配置(保留你原来的PLL相关代码) ... #endif }
2. 配置IAR仿真器的外设模拟
如果你不想改代码,可以试试在IAR的调试配置里开启RCC外设的PLL模拟:
- 打开项目的调试选项:Project > Options > Debugger > Simulator
- 找到「Peripherals」相关的设置,找到RCC模块,确保PLL的模拟功能是启用的(不同版本IAR界面可能略有差异,你可以找找类似“Simulate PLL”的选项)
- 保存配置后重新启动仿真,仿真器应该会自动模拟PLL就绪的状态,让程序通过等待循环
3. 调试时手动置位寄存器(临时应急)
如果只是临时调试,不想改代码也不想配置仿真器,可以这么做:
- 程序卡在循环里后,点击调试工具栏的暂停按钮
- 打开寄存器窗口(View > Registers > Core / Peripherals > RCC)
- 找到
RCC->CR寄存器,手动把第25位(PLLRDY)置为1 - 点击继续运行,程序就能跳过这个等待循环了
不过这个方法每次调试都要手动操作,适合临时验证功能的时候用。
备注:内容来源于stack exchange,提问作者user217354
相关产品推荐
相关产品推荐

