我最近购买了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。但是,我想解决上面显示的问题并理解为什么会这样。
非常感谢任何帮助。对于这篇长篇文章感到抱歉。
答案 0 :(得分:2)
在STM32中使用(几乎)任何外设 - 包括PWR
- 你必须首先在RCC
模块中启用它的时钟。请参阅APB1ENR
中RCC
寄存器中第28位的说明。如果没有该步骤,将忽略对禁用外设寄存器的任何写操作,任何读操作都将为0。