为什么 STM32G474RE 上未启用 RCC PLL

th3*_*os0 2 c stm32

我正在尝试使用 HSI16 作为时钟源和 PLLM = 1、PLLN = 10、AHB = 1、APB1 = 1 和 APB2 = 4 作为配置,使用 PLL 配置 STM32G474RE 板的 RCC 时钟。然而,当我运行代码时,PLLRDY 标志从未设置,我陷入了无限循环。

#include "main.h"

void SytemClockConfig(void){
    /*Enable HSI16*/
    RCC->CR |= RCC_CR_HSION;
    while(!(RCC->CR & RCC_CR_HSIRDY)){}
    
    /*Configure PWR and FLASH*/
    RCC->APB1ENR1 |= RCC_APB1ENR1_PWREN;
    PWR->CR1 |= (0x01 & PWR_CR1_VOS_Msk);
    FLASH->ACR |= FLASH_ACR_ICEN | FLASH_ACR_DCEN | FLASH_ACR_LATENCY_2WS | FLASH_ACR_PRFTEN;
        
    /*Configure AHB and APB*/
    RCC->CFGR |= (0x00 & RCC_CFGR_HPRE_Msk);
    RCC->CFGR |= (0x00 & RCC_CFGR_PPRE1_Msk);
    RCC->CFGR |= (0x05 & RCC_CFGR_PPRE2_Msk);
        
    /*Config PLL*/
    RCC->PLLCFGR |= (0x02 & RCC_PLLCFGR_PLLSRC_Msk);
    RCC->PLLCFGR |= (0x00 & RCC_PLLCFGR_PLLM_Msk);
    RCC->PLLCFGR &= ~(RCC_PLLCFGR_PLLN_Msk);
    RCC->PLLCFGR |= (0x0A & RCC_PLLCFGR_PLLN_Msk);
    RCC->PLLCFGR |= (0x01 & RCC_PLLCFGR_PLLREN_Msk);
    RCC->PLLCFGR |= (0x00 & RCC_PLLCFGR_PLLR_Msk);

        
    /*Enable PLL*/
    RCC->CR |= (0x01 & RCC_CR_PLLON);
    while(!(RCC->CR & RCC_CR_PLLRDY)){}
        
    RCC->CFGR |= (0x05 & RCC_CFGR_SW_Msk);
    while((RCC->CFGR & RCC_CFGR_SWS) != (0x03 & RCC_CFGR_SWS_Msk)){}
} 

int main(void){
    SytemClockConfig();
    
}
Run Code Online (Sandbox Code Playgroud)

gul*_*lpr 8

你根本就没有写下你认为你写下的值。您需要了解二进制逻辑运算的工作原理。基本上,几乎所有的操作都是错误的。我仅举一些例子。

  • RCC->CR |= (0x01 & RCC_CR_PLLON);这个操作什么也不做。PLLON 位位于位置 24。您可以进行二进制 AND11 << 24。结果是0。然后将其二进制 OR 到 RCC -> CR 寄存器。这个操作什么也不做。你需要RCC->CR |= RCC_CR_PLLON;

  • RCC->CFGR |= (0x00 & RCC_CFGR_HPRE_Msk);RCC->CFGR |= 0它与;相同。(它不会将 HPRE 位归零!!!)

还有更多(几乎全部)。

我建议在尝试任何裸机编程之前练习二进制逻辑运算。

如果你想:

  • 将位设置为位置n-VAL |= (1U << n)
  • 复位位置n-VAL &= ~(1 << n)
  • 切换位位于n-VAL ^= (1 << n)

如果要将值放入5寄存器PPRE2中的位中

uint32_t tmp = RCC->CFGR;
tmp &= ~RCC_CFGR_PPRE2_Msk;
tmp |= 5UL << RCC_CFGR_PPRE2_Pos
RCC->CFGR = tmp;
Run Code Online (Sandbox Code Playgroud)

我建议使用临时变量并将值分配给寄存器。