2017-03-27 9 views
0

최근에 NUCLEO-F446RE 보드 (STM32F4 제품)를 구입했으며 PWR 레지스터의 비트를 활성화하는 데 큰 문제가 있습니다.stm32f4 클록 구성으로 PWR 레지스터의 비트가 활성화되지 않습니다

내 목표는 타이머를 사용하여 LED를 깜박이고 180MHz의 최대 시스템 주파수로 HSI 클럭을 구성하려고합니다.

참조 설명서의 지침을 'T'로 따라 왔습니다. Screenshot to reference manual

IDE : 카일 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 낭비 루프를 사용하고 있습니다 :

이 내 코드입니다.

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

나는 위의 코드를 실행

1.

, 그것은 무한 루프에 걸리면 :

2 문제 (& 1 주 1 부)이 있습니다. 값이 기본적으로 사용되는 것으로 간주하면 큰 문제는 아닙니다. 나는 이것이 왜 일어나는지 알고 싶지만. 다음 코드 블록을 실행하기 위해이 블록을 주석 처리했습니다.

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); 

을하지만 여전히 코드의 두 번째 줄에 stucks을 얻을 : 나는 또한 사용하여 비트를 가능하게 시도했습니다.

참조 설명서에는이 레지스터를 구성하는 데 특별한 내용이 표시되어 있지 않습니다. 나는 여기서 완전히 잃어 버렸어.

이상하게도 2 블록의 코드를 완전히 생략하면 프로그램이 실행되고 LED가 깜박입니다. 그러나 위에 표시된 문제를 해결하고 이것이 왜 발생하는지 이해하고 싶습니다.

도움을 주시면 대단히 감사하겠습니다. 그리고 긴 포스트에 대해 유감스럽게 생각합니다.

답변

2

PWR을 포함하는 (거의) 주변 장치를 사용하려면 STM32에서 먼저 RCC 모듈의 시계를 사용해야합니다. 비트 012에 대한 설명은 APB1ENRRCC에 있습니다. 이 단계가 없으면 디스 에이블 된 주변 장치의 레지스터에 대한 쓰기가 무시되고 읽음을 통해 0이 출력됩니다.

+0

와우! 나는 블록 다이어그램에서 그것을 놓쳐 버렸음에 틀림 없다. 매력처럼 일했습니다. 고맙습니다. – Patattack760

+0

RM을 읽고 읽는 것이 좋습니다. 모든 것이 거기에있다. –