2017-03-27 12 views
0

最近、NUCLEO-F446REボード(STM32F4製品)を購入しましたが、PWRレジスタのビットを有効にする際に大きな問題があります。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) { 

} 

私は、タイマーの設定が終了していないので、私はちょうどLEDを点滅させ、CPUの消耗ループを使用しています。

2つの問題(1つのマイナー& 1は、主要な)があります

1.

PWR->CR |= PWR_CR_VOS; 
while(!(PWR->CSR & PWR_CSR_VOSRDY)); 

私は上記のコードを実行すると、それは無限ループで立ち往生。値がデフォルトで有効になっているため、これは大きな問題ではありません。私はなぜこれが起こっているのか知りたいですが。私はこのブロックを次のコードブロックを実行するためにコメントしています。

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は有効にならず、最終的に2行目の無限ループに突き当たります。私はまた、ビットを使用してビットを有効にしようとしました:

PWR->CR |= (1 << 16); 

しかし、それでもコードの2番目の行にスタックします。

リファレンスマニュアルでは、このレジスタを設定する際に特別なことは示されていません。私はここで完全に迷っています。

奇妙なことに、2ブロックのコードを完全に省略すると、プログラムは実行され、LEDが点滅します。しかし、私は上記の問題を解決し、なぜこれが起こっているのか理解したいと思います。

ご協力いただきまして誠にありがとうございます。そして、長いポストのために残念。

答えて

2

PWRを含む(ほぼ)周辺機器を使用するSTM32では、まずクロックをRCCモジュールで有効にする必要があります。 のAPB1ENRレジスタのビット28の説明を参照してください。そのステップがなければ、ディセーブルされたペリフェラルのレジスタへの書き込みは無視され、読み込みによって0が与えられます。

+0

うわー!私はブロックダイアグラムでそれを忘れていたに違いない。魅力のように働いた。どうもありがとうございました。 – Patattack760

+0

RMを開いて読むことをお勧めします。すべてがそこにある –

関連する問題