我目前正在尝试使用 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文件。
我缺少什么才能正确设置系统时钟?