为什么我无法正确配置 PLL 时钟?

问题描述 投票:0回答:0

我目前正在尝试使用 C++ 为 STM32F401 微控制器编写引导加载程序。在这个项目中,我使用

-nostartfiles
删除了所有启动文件,并自己编写了所有启动代码。我目前遇到的主要问题是从 25MHz 的外部晶振源设置系统时钟以使系统达到大约 84MHz。使用 STM32CubeIDE 我已经确认我尝试配置的时钟设置确实是有效值。

我的主要问题是我无法设置 PLL 就绪位以继续执行我的程序。我已经更改了有关 HSE 配置和 PLL 配置的操作顺序,但无济于事。每个外围设备都被构造为一个类,其中覆盖了新运算符以返回内存中的确切地址。

RCC::EnableExternalSystemClock()
函数是我在
boot_main()
条目中调用的第一个函数。以下是我现在拥有的当前时钟配置代码的一些片段:

碾压混凝土.cpp

/**
 * @brief Sets the system clock to the specified TARGET_SYSTEM_CLOCK through
 * the external oscillator.
 *
 */
void RCC::EnableExternalSystemClock() {
    size_t timeout = 0;

    // Enable HSE
    this->CR.bits.HSEON = 1;
    while (this->CR.bits.HSERDY != 0b1 || timeout < this->HSE_TIMEOUT) {
        timeout++;
    }

    // Enable power controller
    this->APB1ENR.bits.PWREN = 1;

    // Configure voltage regulator scaling
    PWR &power = *new PWR();
    power.SetRegulatorScale(PWR::Scale::DIV2);

    // Enable flash prefetch & caches
    FLASH &flash = *new FLASH();
    flash.EnablePrefetchCache();

    // Calculate actual system clock
    constexpr auto pll_clocks =
        RCC::CalculatePLLClocks(RCC::HSE_CRYSTAL_FREQ_HZ, RCC::TARGET_SYSTEM_CLOCK);
    constexpr auto sys_clock = RCC::CalculateSysClock(RCC::HSE_CRYSTAL_FREQ_HZ, pll_clocks.pll_m,
                                                      pll_clocks.pll_n, pll_clocks.pll_p);

    // Set APB scalers
    constexpr auto lsapb2_prescaler = RCC::CalculateLSAPB2Prescaler(sys_clock);
    this->CFGR.bits.HPRE = 0b000;
    this->CFGR.bits.PPRE1 = lsapb2_prescaler; // calculates as 0x04
    this->CFGR.bits.PPRE2 = 0b000;

    // Enable system config click
    this->APB2ENR.bits.SYSCFGEN = 1;

    // Disable PLL
    this->CR.bits.PLLON = 0;
    while (this->CR.bits.PLLRDY != 0) {
        // Do nothing
    }

    // Set PLL scalers
    this->PLLCFGR.bits.PLLM = pll_clocks.pll_m; // calculates as 13
    this->PLLCFGR.bits.PLLN = pll_clocks.pll_n; // calclulates as 87
    this->PLLCFGR.bits.PLLP = pll_clocks.pll_p; // calculates as 0x00
    this->PLLCFGR.bits.PLLQ = 4;

    // Set PLL source
    this->PLLCFGR.bits.PLLSRC = 1;

    // Enable PLL
    this->CR.bits.PLLON = 1;
    while (this->CR.bits.PLLRDY == 0) { // currently stuck here
        // Do nothing
    }

    // Set clock source
    this->CFGR.bits.SW = 0b10;
    while (this->CFGR.bits.SWS != 0b10) {
        // Do nothing
    }
}

FLASH.hpp

void FLASH::EnablePrefetchCache() {
    this->ACR.bits.DCEN = 1;
    this->ACR.bits.ICEN = 1;
    this->ACR.bits.PRFTEN = 1;

    constexpr int sys_clock = RCC::GetSystemClock(RCC::HSE_CRYSTAL_FREQ_HZ);
    constexpr uint8_t latency = FLASH::CalculateFlashLatency(TARGET_SYSTEM_VOLTAGE, sys_clock);
    this->ACR.bits.LATENCY = latency;
}

可以在这里找到RCC.hpp文件。

这里是 STM32CubeIDE 中预期的系统时钟配置图:

我缺少什么才能正确设置系统时钟?

c++ stm32 microcontroller
© www.soinside.com 2019 - 2024. All rights reserved.