最近、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が点滅します。しかし、私は上記の問題を解決し、なぜこれが起こっているのか理解したいと思います。
ご協力いただきまして誠にありがとうございます。そして、長いポストのために残念。
うわー!私はブロックダイアグラムでそれを忘れていたに違いない。魅力のように働いた。どうもありがとうございました。 – Patattack760
RMを開いて読むことをお勧めします。すべてがそこにある –