我正在尝试使用HSI16作为时钟源并使用PLLM配置STM32G474RE板的RCC时钟,PLLM = 1,PLLN = 10,AHB = 1,APB1 = 1和APB2 = 4作为配置。然而,当我运行代码时,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();
}
您根本没有写下您认为自己写下的值。您需要了解二进制逻辑运算的工作原理。基本上,几乎所有的操作都是错误的。我只会给你一些例子。
RCC->CR |= (0x01 & RCC_CR_PLLON);
这个操作没有任何作用。 PLLON 位位于位置 24。您可以对 1
和 1 << 24
进行二进制 AND。结果是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)
如果你想将值
5
放入寄存器中的PPRE2
位
uint32_t tmp = RCC->CFGR;
tmp &= ~RCC_CFGR_PPRE2_Msk;
tmp |= 5UL << RCC_CFGR_PPRE2_Pos
RCC->CFGR = tmp;