stm32f4时钟配置不能使能PWR寄存器中的位

时间:2017-03-27 08:59:59

标签: microcontroller stm32 stm32f4 system-clock

我最近购买了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。但是,我想解决上面显示的问题并理解为什么会这样。

非常感谢任何帮助。对于这篇长篇文章感到抱歉。

1 个答案:

答案 0 :(得分:2)

在STM32中使用(几乎)任何外设 - 包括PWR - 你必须首先在RCC模块中启用它的时钟。请参阅APB1ENRRCC寄存器中第28位的说明。如果没有该步骤,将忽略对禁用外设寄存器的任何写操作,任何读操作都将为0。