配置STM32F411CEU6的系统时钟-避免芯片内核锁死

一.了解

我在尝试建立HAL库的时候使用的正点原子的sys.c的工程,结果出现芯片内核锁死的问题。究其原因是因为正点原子使用的是8M的晶振,就导致程序下进去就会锁死内核

这是正点原子的晶振,这是我的板载晶振。

这是我最小系统的晶振。所以我们只能重写sys.c和sys.h文件解决问题。

二.程序

1.sys.c

cs 复制代码
#include "sys.h"
#include "stm32f4xx.h"

/**
  * @brief  STM32F411 对齐CubeMX配置:25M晶振→96MHz 系统时钟
  * @param  None
  * @note   1、完全匹配CubeMX参数:PLLM=25, PLLN=192, PLLP=2 → 96MHz
  *         2、保留超时兜底+时钟源顺序,永不卡死/GPIO乱跳
  *         3、校准延时精准到500ms,兼容HAL_Delay
  */
void SystemClock_Config(void)
{
    uint32_t timeout = 0xFFFFFFF;

    // 1. FLASH配置(96MHz必备)
    FLASH->ACR = FLASH_ACR_ICEN | FLASH_ACR_DCEN | FLASH_ACR_PRFTEN | FLASH_ACR_LATENCY_3WS;

    // 2. 复位RCC+超时兜底
    RCC->CR |= RCC_CR_HSION;                
    while((RCC->CR & RCC_CR_HSIRDY) == 0 && --timeout);
    if(timeout == 0) { Error_Handler(); }
    
    RCC->CFGR = 0x00000000;                 
    RCC->CR &= ~(RCC_CR_PLLON | RCC_CR_HSEON); 
    RCC->CIR = 0x00000000;                  

    // 3. 使能25M晶振+超时兜底
    timeout = 0xFFFFFFF;
    RCC->CR |= RCC_CR_HSEON;
    while((RCC->CR & RCC_CR_HSERDY) == 0 && --timeout);
    if(timeout == 0) { Error_Handler(); }

    if(timeout > 0) 
    {
        // 4. 完全对齐CubeMX的PLL参数(关键!)
        RCC->PLLCFGR = 0x00000000;
        RCC->PLLCFGR |= RCC_PLLCFGR_PLLSRC_HSE; // 先开时钟源(防失效)
        RCC->PLLCFGR |= 25;                 // ? CubeMX的PLLM=25
        RCC->PLLCFGR |= (192 << 6);         // ? CubeMX的PLLN=192
        RCC->PLLCFGR |= (0 << 16);          // ? CubeMX的PLLP=2(对应位00)
        RCC->PLLCFGR |= (4 << 24);          // PLLQ=4(CubeMX默认)

        // 5. 使能PLL+超时兜底
        timeout = 0xFFFFFFF;
        RCC->CR |= RCC_CR_PLLON;
        while((RCC->CR & RCC_CR_PLLRDY) == 0 && --timeout);
        if(timeout == 0) { Error_Handler(); }

        if(timeout > 0) 
        {
            // 6. 总线分频(CubeMX同款:AHB=1, APB1=2, APB2=1)
            RCC->CFGR |= RCC_CFGR_HPRE_DIV1;    
            RCC->CFGR |= RCC_CFGR_PPRE1_DIV2;   
            RCC->CFGR |= RCC_CFGR_PPRE2_DIV1;   

            // 7. 切PLL时钟源
            RCC->CFGR |= RCC_CFGR_SW_PLL;
            while((RCC->CFGR & RCC_CFGR_SWS) != RCC_CFGR_SWS_PLL);
        }
    }

    // 8. 校准延时:从400ms→500ms精准(只改这行!)
    SystemCoreClock = 96000000UL;   // ? 校准值:25M晶振+CubeMX参数,完美匹配500ms
    SysTick->CTRL &= ~(1 << 2);          // 清脏位
    SysTick->CTRL |=  (1 << 2);          // 关8分频
    HAL_SYSTICK_Config(SystemCoreClock / 1000);
    HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
}

void Error_Handler(void)
{
    __disable_irq();
    while(1) {}
}

2.sys.h

cs 复制代码
#ifndef __SYS__H
#define __SYS__H

#include "stm32f4xx.h"  // STM32F4核心头文件
#include "stm32f4xx_hal.h" // HAL库基础定义(必须,因为用到__HAL_XXX宏)

// 声明【CubeMX原生无修改】的系统时钟配置函数
void SystemClock_Config(void);

// 声明报错函数(原代码里的调用,必须声明)
void Error_Handler(void);

#endif

三.晶振不起震

我最开始把正点原子的一个低功耗删去,程序也可以运行,但是使用的是内部低速时钟16Mhz,我发现我delay(500)ms实测只有130ms,我又开始继续修复,最终搞定了完整的版本,把时钟跑起来。我还进行了测试。

生成了四路PWM波形,发现恨我吗预计的是可以的,我们最终给他修复完成。

相关推荐
liuyicenysabel6 小时前
多服务上线日记三:
运维·服务器·笔记·学习
CHENGQUAN_kenan7 小时前
佛山亚马逊卖家出口退税合规指南|9610免税、一般贸易退税、无票采购、申报误区全覆盖
大数据·经验分享·笔记·百度
YM52e7 小时前
鸿蒙ArkTS实战项目 - 门店陈列巡检台:巡检卡片与多列切换实现
学习·华为·harmonyos
嵌入式阿蔡7 小时前
传感器_03:电机驱动——让 GPIO 当指挥官,别让 GPIO 当电源
网络·stm32·单片机·嵌入式硬件·嵌入式实时数据库
一只小小的芙厨8 小时前
基础数论总结
笔记·学习·算法
国科安芯9 小时前
ASL706S:让 MCU 不再“失忆跑飞“的守护芯片
分布式·单片机·嵌入式硬件·安全·fpga开发·架构
hsjiasb9 小时前
FreeRTOS学习(三十七)——常见错误与工程规范
学习·学习笔记·freertos
小席是个热心肠10 小时前
Redis的自我学习
数据库·redis·学习
zyf10441610 小时前
暑期实践日志 Day33:完成全部字幕添加,工作基本收尾
学习·计算机网络·剪辑·暑期实践·课题任务
@Mike@11 小时前
09-数据库学习笔记(数据库索引与过滤器)
数据库·笔记