STM32F401RE无HAL库LED闪烁程序故障排查求助
STM32F401RE LED仅闪烁一次后常亮的修复方案
问题根源分析
- FLASH等待周期配置错误:代码中设置了
FLASH_ACR_LATENCY_5WS(5个等待周期),但STM32F401在84MHz主频、Scale1电压配置下,仅需要2个等待周期。过高的等待周期会导致系统运行异常,GPIO复位操作可能无法正确执行。 - 延时参数过小:系统时钟切换到84MHz后,
delay(100000)的实际时长仅约1.2ms,熄灭时间太短,肉眼几乎无法察觉,看起来像是LED一直常亮。
修复后的完整代码
#include "stm32f401xe.h" #define PLL_M 4 #define PLL_N 84 #define PLL_P 0 void sys_clk_cfg(void) { //1. 使能HSE并等待就绪 RCC->CR |= RCC_CR_HSEON; while(!(RCC->CR & RCC_CR_HSERDY)); //2. 使能电源时钟并配置电压调节器 RCC->APB1ENR |= RCC_APB1ENR_PWREN; PWR->CR |= PWR_CR_VOS; //配置FLASH访问:修正等待周期为2WS(匹配84MHz主频) FLASH->ACR |= FLASH_ACR_PRFTEN | FLASH_ACR_ICEN | FLASH_ACR_DCEN | FLASH_ACR_LATENCY_2WS; //配置时钟预分频器 //AHB预分频 RCC->CFGR |= RCC_CFGR_HPRE_DIV1; //APB1预分频 RCC->CFGR |= RCC_CFGR_PPRE1_DIV2; //APB2预分频 RCC->CFGR |= RCC_CFGR_PPRE2_DIV1; //配置PLL RCC->PLLCFGR = (PLL_M <<0) | (PLL_N << 6) | (PLL_P << 16) | (RCC_PLLCFGR_PLLSRC_HSE); //使能PLL并等待就绪 RCC->CR |= RCC_CR_PLLON; while(!(RCC->CR & RCC_CR_PLLRDY)); //切换系统时钟到PLL RCC->CFGR |= RCC_CFGR_SW_PLL; while((RCC->CFGR & RCC_CFGR_SW) != RCC_CFGR_SW_PLL); } void GPIO_Config(void) { //使能GPIOA时钟 RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN; //设置PA5为通用输出模式 GPIOA->MODER |= (1<<10); //配置输出模式为推挽、低速 GPIOA->OTYPER = 0; GPIOA->OSPEEDR = 0; } void delay(uint32_t time) { while(time--); } int main() { sys_clk_cfg(); GPIO_Config(); while(1) { //置位PA5,点亮LED GPIOA->BSRR = (1 << 5); delay(8400000); //约1秒延时(84MHz主频下) //复位PA5,熄灭LED GPIOA->BSRR = ((1 << 5) << 16); delay(8400000); } }
关键修复点说明
- FLASH等待周期修正:将
FLASH_ACR_LATENCY_5WS替换为FLASH_ACR_LATENCY_2WS,确保FLASH访问速度与系统时钟匹配,避免运行异常。 - 延时参数调整:将延时参数改为
8400000,对应84MHz主频下约1秒的循环时间,让闪烁间隔足够明显。 - BSRR寄存器写法优化:直接使用赋值操作
GPIOA->BSRR = ...替代|=,符合BSRR只写寄存器的使用规范,逻辑更清晰。
内容的提问来源于stack exchange,提问作者bigmacBucky
相关产品推荐
相关产品推荐

