我正在尝试使用 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)
你根本就没有写下你认为你写下的值。您需要了解二进制逻辑运算的工作原理。基本上,几乎所有的操作都是错误的。我仅举一些例子。
RCC->CR |= (0x01 & RCC_CR_PLLON);这个操作什么也不做。PLLON 位位于位置 24。您可以进行二进制 AND1和1 << 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)
我建议使用临时变量并将值分配给寄存器。