举报
关于STM32F401RCT6的PLL就绪标志(PLLRDY)问题,以下是关键排查点:
HSE启动顺序
// 启用HSE(假设使用外部晶振)
unsafe { ptr::write_volatile(RCC_CR, ptr::read_volatile(RCC_CR) | RCC_CR_HSEON) };
// 等待HSE就绪(超时保护很重要)
while (unsafe { ptr::read_volatile(RCC_CR) } & RCC_CR_HSERDY) == 0 {}PLL配置规范
// 关闭PLL
unsafe { ptr::write_volatile(RCC_CR, ptr::read_volatile(RCC_CR) & !RCC_CR_PLLON) };
// 等待PLL停止
while (unsafe { ptr::read_volatile(RCC_CR) } & RCC_CR_PLLRDY) != 0 {}let pllcfgr = RCC_PLLCFGR_PLLSRC_HSE // 选择HSE作为PLL输入
| (8 << RCC_PLLCFGR_PLLM_Pos) // 输入分频M=8(假设HSE=8MHz)
| (336 << RCC_PLLCFGR_PLLN_Pos) // VCO倍频N=336
| (0 << RCC_PLLCFGR_PLLP_Pos); // 系统时钟分频P=2(PLLP=0对应/2)
unsafe { ptr::write_volatile(RCC_PLLCFGR, pllcfgr) };PLL启动顺序
// 启动PLL
unsafe { ptr::write_volatile(RCC_CR, ptr::read_volatile(RCC_CR) | RCC_CR_PLLON) };
// 等待PLL就绪(必须循环等待)
while (unsafe { ptr::read_volatile(RCC_CR) } & RCC_CR_PLLRDY) == 0 {}关键参数验证
VCO = (HSE_FREQ / PLLM) * PLLNSYSCLK = VCO / PLLP寄存器位域定义检查
const RCC_CR: *mut u32 = (RCC_BASE + 0x00) as *mut u32;
const RCC_CR_PLLRDY: u32 = 1 << 25;
const RCC_CR_PLLON: u32 = 1 << 24;
const RCC_CR_HSERDY: u32 = 1 << 17;
const RCC_CR_HSEON: u32 = 1 << 16;调试建议
let rcc_cr = unsafe { ptr::read_volatile(RCC_CR) };
defmt::info!("RCC_CR: {:032b}", rcc_cr);常见错误排查
建议使用STM32CubeMX生成的初始化代码作为参考,特别是:
// CubeMX生成的典型初始化序列
__HAL_RCC_HSE_CONFIG(RCC_HSE_ON);
while(!__HAL_RCC_GET_FLAG(RCC_FLAG_HSERDY));
// 配置PLL前必须关闭PLL
RCC->CR &= ~RCC_CR_PLLON;
while((RCC->CR & RCC_CR_PLLRDY) != 0);
// 配置PLL参数
RCC->PLLCFGR = RCC_PLLCFGR_PLLSRC_HSE | ...
RCC->CR |= RCC_CR_PLLON;
while((RCC->CR & RCC_CR_PLLRDY) == 0);最后检查您的defmt输出值1000000010101101110000011(二进制)转换为十六进制是0x405B83,对应RCC_CR寄存器值:
举报
更多回帖