0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

stm32f4-discovery 評価ボードで、クロックの初期化に失敗する話

Last updated at Posted at 2025-07-02

返事がない。ただの屍のようだ。

CubeMXでstm32f4-discovery用のサンプルコードを吐かせてステップ実行すると、HAL_Init()の後にある

 SystemClock_Config();

で反応が帰ってこない。これは中で呼ばれている HAL_RCC_OscConfig() がエラーを返すから。

HAL_RCC_OscConfig() が定義されている stm32f4xx_hal_rc.c の541行目あたり

pll_config = RCC->PLLCFGR;
...
//[1]
if (((RCC_OscInitStruct->PLL.PLLState) == RCC_PLL_OFF) ||
 (READ_BIT(pll_config, RCC_PLLCFGR_PLLSRC) != RCC_OscInitStruct->PLL.PLLSource) ||
 (READ_BIT(pll_config, RCC_PLLCFGR_PLLM) != (RCC_OscInitStruct->PLL.PLLM) << RCC_PLLCFGR_PLLM_Pos) ||
 (READ_BIT(pll_config, RCC_PLLCFGR_PLLN) != (RCC_OscInitStruct->PLL.PLLN) << RCC_PLLCFGR_PLLN_Pos) ||
 (READ_BIT(pll_config, RCC_PLLCFGR_PLLP) != (((RCC_OscInitStruct->PLL.PLLP >> 1U) - 1U)) << RCC_PLLCFGR_PLLP_Pos) ||
 (READ_BIT(pll_config, RCC_PLLCFGR_PLLQ) != (RCC_OscInitStruct->PLL.PLLQ << RCC_PLLCFGR_PLLQ_Pos)))

のチェックで、PLLの設定レジスタPLLCFGRが意図した設定になっていないため、エラーが返ってくる。

どうしてそうなった

PLLの設定レジスタPLLFGRへの書き込みはstm32f4xx_hal_rc.cの492行目

//[2]
        WRITE_REG(RCC->PLLCFGR, (RCC_OscInitStruct->PLL.PLLSource                                            | \
                                 RCC_OscInitStruct->PLL.PLLM                                                 | \
                                 (RCC_OscInitStruct->PLL.PLLN << RCC_PLLCFGR_PLLN_Pos)             | \
                                 (((RCC_OscInitStruct->PLL.PLLP >> 1U) - 1U) << RCC_PLLCFGR_PLLP_Pos) | \
                                 (RCC_OscInitStruct->PLL.PLLQ << RCC_PLLCFGR_PLLQ_Pos)));

で行われている。しかしここを通過するには465行目の

//[3]
if (__HAL_RCC_GET_SYSCLK_SOURCE() != RCC_CFGR_SWS_PLL)

のチェックで、RCC_CFGRのSWSレジスタがPLL以外に指定されていないといけない。

デフォルトがPLLになっている、リセットでクリアされない、など色々要因はあると思うがここは深掘りしていない。しかしどういう事情であれ、一旦このレジスタでPLLが設定されると、以後レジスタの設定はシレっとスキップされてしまう。

じゃあどうしよう?

これを避けるには、main.cで予めRCC_CFGRのSWSレジスタをHSEに倒しておくのが良かった。
main.cの87行目あたりにユーザが書いても変更されない区画があるので、そこに

  /* USER CODE BEGIN Init */
  __HAL_RCC_SYSCLK_CONFIG(RCC_SYSCLKSOURCE_HSE);
  /* USER CODE END Init */

とかして、[2]のチェックにいく手前でSWSビットをPLL以外とする。これでPLL設定ルーチンがスキップされなくなるので、ことなきを得る。

が、これって文句出てないのだろうか??

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?