stm32f4 时钟配置不会启用 PWR 寄存器中的位
stm32f4 clock configuration won't enable bits in PWR register
我最近购买了一块 NUCLEO-F446RE 板(一种 STM32F4 产品),但在启用 PWR 寄存器中的位时遇到了重大问题。
我的目标是使用计时器使 LED 闪烁,我正在尝试将 HSI 时钟配置为最大系统频率 180 MHz。
我已经按照参考手册中的说明进行了 'T'。以下是说明的屏幕截图:Screenshot to reference manual
IDE: Keil v5
主板是运行最新固件。
这是我的代码:
/* Includes ------------------------------------------------------------------*/
#include "stm32f4xx.h"
/* Private function prototypes -----------------------------------------------*/
static void sysClockConfig(void);
static void tim3Config(void);
/**
******************************************************************************
* @brief Main program.
* @note None
* @param None
* @retval None
******************************************************************************
*/
int main(void) {
sysClockConfig();
tim3Config();
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN; //Enable GPIOA CLK
GPIOA->MODER |= GPIO_MODER_MODE5_0; //GPIOA pin5 selected as output
GPIOA->ODR |= GPIO_ODR_OD5; //GPIOA pin5 set high
volatile int i;
while(1) {
GPIOA->ODR |= GPIO_ODR_OD5;
for(i=0; i<1000000; i++);
GPIOA->ODR &= ~GPIO_ODR_OD5;
for(i=0; i<1000000; i++);
}
}
/**
******************************************************************************
* @brief Configures sysmtem clock and main PLL.
* Initializes voltage regulator scaling and overdrive mode.
* Initializes flash memory.
* @note CLK SRC = HSI -> PLL
# SYS CLK = 180 MHz
* AHB CLK = 180 MHz
* APB1 CLK = 45 MHz
* APB2 CLK = 90 MHz
* Change latency depending on freq and voltage (see table 5, pg.63)
* Look at pg.94 for CLK config sequence
* @param None
* @retval None
******************************************************************************
*/
static void sysClockConfig(void) {
RCC->CR |= RCC_CR_HSION; //Enables HSI clock
while( !(RCC->CR & RCC_CR_HSIRDY) ); //Waits until HSI is stable
RCC->CFGR |= RCC_CFGR_SW_HSI; //Select HSI is SYS CLK
while( RCC->CFGR & RCC_CFGR_SWS_HSI ); //Wait until HSI is SYS CLK
RCC->CR &= ~RCC_CR_PLLON; //Disables PLL
//-----> ISSUE #1 <-----
PWR->CR |= PWR_CR_VOS; //Voltage reg = scale 3
while( !(PWR->CSR & PWR_CSR_VOSRDY) ); //Waits until scaling is ready
/** PLL config: I2S/SAI/SPDIF = VCO / R
* USB/SDIO = VCO / Q
* SYS CLK = VCO / P
* VCO = HSI * (N/M)
*/
RCC->PLLCFGR |= ( 8u | //PLL_M = 8
(180u << 6) | //PLL_N = 180
( 0u << 16) | //PLL_P = 2
(RCC_PLLCFGR_PLLSRC_HSI)| //PLL SRC = HSI
( 8u << 24) | //PLL_Q = 8
( 4u << 28) ); //PLL_R = 4
RCC->CR |= RCC_CR_PLLON; //Enable PLL
//-----> ISSUE #2 <-----
PWR->CR |= PWR_CR_ODEN; //Enables Overdrive mode
while( !(PWR->CSR & PWR_CSR_ODRDY) ); //Waits until OD is ready
PWR->CR |= PWR_CR_ODSWEN; //Swites Overdrive mode
while( !(PWR->CSR & PWR_CSR_ODSWRDY) ); //Waits until OD switch is ready
FLASH->ACR |= (FLASH_ACR_PRFTEN | //Prefetch enable
FLASH_ACR_ICEN | //Intruction cache enable
FLASH_ACR_DCEN | //Data cache enable
FLASH_ACR_LATENCY_5WS ); //FLASH 5 wait states
while( !(RCC->CR & RCC_CR_PLLRDY) ); //Waits until PLL is locked
RCC->CFGR |= (RCC_CFGR_HPRE_DIV1 | //AHB = Sys CLK DIV_1
RCC_CFGR_PPRE1_DIV4 | //APB1 = AHB CLK DIV_4
RCC_CFGR_PPRE2_DIV2 | //APB2 = AHB CLK DIV_2
RCC_CFGR_SW_PLL ); //Select PLL as SYS CLK
while( !(RCC->CFGR & RCC_CFGR_SWS_PLL) ); //Waits until PLL is SYS CLK
}
/**
******************************************************************************
* @brief Configures TIM3.
* @note None
* @param None
* @retval None
******************************************************************************
*/
static void tim3Config(void) {
}
我还没有完成定时器的设置,所以我只是使用 CPU 浪费循环来闪烁 LED。
有 2 个问题(1 个小问题和 1 个大问题):
1.
PWR->CR |= PWR_CR_VOS;
while( !(PWR->CSR & PWR_CSR_VOSRDY) );
当我执行上面的代码时,它陷入了死循环。考虑到该值默认启用,这不是什么大问题。虽然我想知道为什么会这样。我一直在评论这个块来执行下面的代码块。
2.
PWR->CR |= PWR_CR_ODEN;
while( !(PWR->CSR & PWR_CSR_ODRDY) );
PWR->CR |= PWR_CR_ODSWEN;
while( !(PWR->CSR & PWR_CSR_ODSWRDY) );
上面的代码是最麻烦的。当我调试我的代码时,PWR_CR_ODEN 没有启用并最终陷入第二行的无限循环。我还尝试使用以下方式启用该位:
PWR->CR |= (1 << 16);
但是还是卡在第二行代码
参考手册没有说明配置这个寄存器有什么特别之处。我完全迷失在这里。
奇怪的是,如果我完全省略 2 段代码,程序将执行并闪烁 LED。但是,我想解决上面显示的问题并理解为什么会这样。
非常感谢任何帮助。很抱歉 post.
在 STM32 中使用(几乎)任何外设 - 包括 PWR
- 你必须首先在 RCC
模块中启用它的时钟。参见RCC
中APB1ENR
寄存器的第28位的说明。如果没有这一步,任何对禁用外围设备寄存器的写入都将被忽略,任何读取都会给你 0.
我最近购买了一块 NUCLEO-F446RE 板(一种 STM32F4 产品),但在启用 PWR 寄存器中的位时遇到了重大问题。
我的目标是使用计时器使 LED 闪烁,我正在尝试将 HSI 时钟配置为最大系统频率 180 MHz。
我已经按照参考手册中的说明进行了 'T'。以下是说明的屏幕截图:Screenshot to reference manual
IDE: Keil v5
主板是运行最新固件。
这是我的代码:
/* Includes ------------------------------------------------------------------*/
#include "stm32f4xx.h"
/* Private function prototypes -----------------------------------------------*/
static void sysClockConfig(void);
static void tim3Config(void);
/**
******************************************************************************
* @brief Main program.
* @note None
* @param None
* @retval None
******************************************************************************
*/
int main(void) {
sysClockConfig();
tim3Config();
RCC->AHB1ENR |= RCC_AHB1ENR_GPIOAEN; //Enable GPIOA CLK
GPIOA->MODER |= GPIO_MODER_MODE5_0; //GPIOA pin5 selected as output
GPIOA->ODR |= GPIO_ODR_OD5; //GPIOA pin5 set high
volatile int i;
while(1) {
GPIOA->ODR |= GPIO_ODR_OD5;
for(i=0; i<1000000; i++);
GPIOA->ODR &= ~GPIO_ODR_OD5;
for(i=0; i<1000000; i++);
}
}
/**
******************************************************************************
* @brief Configures sysmtem clock and main PLL.
* Initializes voltage regulator scaling and overdrive mode.
* Initializes flash memory.
* @note CLK SRC = HSI -> PLL
# SYS CLK = 180 MHz
* AHB CLK = 180 MHz
* APB1 CLK = 45 MHz
* APB2 CLK = 90 MHz
* Change latency depending on freq and voltage (see table 5, pg.63)
* Look at pg.94 for CLK config sequence
* @param None
* @retval None
******************************************************************************
*/
static void sysClockConfig(void) {
RCC->CR |= RCC_CR_HSION; //Enables HSI clock
while( !(RCC->CR & RCC_CR_HSIRDY) ); //Waits until HSI is stable
RCC->CFGR |= RCC_CFGR_SW_HSI; //Select HSI is SYS CLK
while( RCC->CFGR & RCC_CFGR_SWS_HSI ); //Wait until HSI is SYS CLK
RCC->CR &= ~RCC_CR_PLLON; //Disables PLL
//-----> ISSUE #1 <-----
PWR->CR |= PWR_CR_VOS; //Voltage reg = scale 3
while( !(PWR->CSR & PWR_CSR_VOSRDY) ); //Waits until scaling is ready
/** PLL config: I2S/SAI/SPDIF = VCO / R
* USB/SDIO = VCO / Q
* SYS CLK = VCO / P
* VCO = HSI * (N/M)
*/
RCC->PLLCFGR |= ( 8u | //PLL_M = 8
(180u << 6) | //PLL_N = 180
( 0u << 16) | //PLL_P = 2
(RCC_PLLCFGR_PLLSRC_HSI)| //PLL SRC = HSI
( 8u << 24) | //PLL_Q = 8
( 4u << 28) ); //PLL_R = 4
RCC->CR |= RCC_CR_PLLON; //Enable PLL
//-----> ISSUE #2 <-----
PWR->CR |= PWR_CR_ODEN; //Enables Overdrive mode
while( !(PWR->CSR & PWR_CSR_ODRDY) ); //Waits until OD is ready
PWR->CR |= PWR_CR_ODSWEN; //Swites Overdrive mode
while( !(PWR->CSR & PWR_CSR_ODSWRDY) ); //Waits until OD switch is ready
FLASH->ACR |= (FLASH_ACR_PRFTEN | //Prefetch enable
FLASH_ACR_ICEN | //Intruction cache enable
FLASH_ACR_DCEN | //Data cache enable
FLASH_ACR_LATENCY_5WS ); //FLASH 5 wait states
while( !(RCC->CR & RCC_CR_PLLRDY) ); //Waits until PLL is locked
RCC->CFGR |= (RCC_CFGR_HPRE_DIV1 | //AHB = Sys CLK DIV_1
RCC_CFGR_PPRE1_DIV4 | //APB1 = AHB CLK DIV_4
RCC_CFGR_PPRE2_DIV2 | //APB2 = AHB CLK DIV_2
RCC_CFGR_SW_PLL ); //Select PLL as SYS CLK
while( !(RCC->CFGR & RCC_CFGR_SWS_PLL) ); //Waits until PLL is SYS CLK
}
/**
******************************************************************************
* @brief Configures TIM3.
* @note None
* @param None
* @retval None
******************************************************************************
*/
static void tim3Config(void) {
}
我还没有完成定时器的设置,所以我只是使用 CPU 浪费循环来闪烁 LED。
有 2 个问题(1 个小问题和 1 个大问题):
1.
PWR->CR |= PWR_CR_VOS;
while( !(PWR->CSR & PWR_CSR_VOSRDY) );
当我执行上面的代码时,它陷入了死循环。考虑到该值默认启用,这不是什么大问题。虽然我想知道为什么会这样。我一直在评论这个块来执行下面的代码块。
2.
PWR->CR |= PWR_CR_ODEN;
while( !(PWR->CSR & PWR_CSR_ODRDY) );
PWR->CR |= PWR_CR_ODSWEN;
while( !(PWR->CSR & PWR_CSR_ODSWRDY) );
上面的代码是最麻烦的。当我调试我的代码时,PWR_CR_ODEN 没有启用并最终陷入第二行的无限循环。我还尝试使用以下方式启用该位:
PWR->CR |= (1 << 16);
但是还是卡在第二行代码
参考手册没有说明配置这个寄存器有什么特别之处。我完全迷失在这里。
奇怪的是,如果我完全省略 2 段代码,程序将执行并闪烁 LED。但是,我想解决上面显示的问题并理解为什么会这样。
非常感谢任何帮助。很抱歉 post.
在 STM32 中使用(几乎)任何外设 - 包括 PWR
- 你必须首先在 RCC
模块中启用它的时钟。参见RCC
中APB1ENR
寄存器的第28位的说明。如果没有这一步,任何对禁用外围设备寄存器的写入都将被忽略,任何读取都会给你 0.