最近秋月で STM32F405 を置き始める等、需要に対して適切な供給が確保されつつある現状です。いいことですね。ということで STM32F405 最初の関門であろう、PLL 設定について述べたいと思います。
この F4 シリーズの PLL は結構複雑で、逓倍率(?)を決める箇所が3箇所もあります。リファレンスマニュアルを見ても正直分かりにくいかなというところなので、例によって CubeMX のダイヤグラムをパクりながらもまとめていきます。
各クロックの制限
リファレンスマニュアルを見てみると以下の記述がありました。これは RCC のクロックについてのセクションで見つけたものです。
まとめると、USB FS と I2S 等は PLL から直接、その他は SYSCLK から分周して得るということです。そして APB2 は最大84MHz、APB1は最大42MHzです。これに注意しつつ設定をしていきましょう。
ダイヤグラムと設定レジスタ
すなわち PLL の M, N, P でシステムクロック出力を設定、Q で USB FS 用の 48MHz を設定するというわけです。そして SYSCLK からいろいろ分周をしていくことになります。
まず入力ですが、ひとまず HSI RC の 16MHz を8分周しておきましょう。これはなんとなくです。続いて PLL の逓倍出力ですが、最大システムクロック周波数の 168MHz を目指して168 / 2倍したいです。しかしながら後置する分周器(P)の値が2分周からとなっていますので、逓倍を168倍としておきます。これによってひとまず PLL ブロック全体の出力が
$$\frac{16\mathrm{[MHz]}}{8}\mathrm{(M)} \cdot 168\mathrm{(N)} / 2\mathrm{(P)} = 168 \mathrm{[MHz]}$$
ということで所望の最大クロックを得ることができました。F303 では最大クロックが 72MHz なのに対し 内部クロックだけだと 64MHz までしか得られませんでしたが、この F4 シリーズでは内部クロックだけで各ブロックの最大クロック周波数を得られてとても嬉しいですね。
この部分の設定を以下に示しておきます。
RCC->PLLCFGR |= (8 << RCC_PLLCFGR_PLLM_Pos); // divide HSI by 8 (= 2MHz)
RCC->PLLCFGR |= (168 << RCC_PLLCFGR_PLLN_Pos); // multiple the value above by 168 (= 336MHz) as VCO output
続いて Q の値の導出をしようかと思ったんですが、面倒くさくなってしまったので省きます。Qは7にしておけばOKです。
各種ブロックのための分周
先に述べたとおり、APB1 と APB2 のためにクロックを分周しなければなりません。APB1 は最大 42MHz なので、168/42 = 4分周、APB2 は最大 84MHz なので 168/84 = 2分周が必要となります。
コード全体
以上、PLL の有効化も含めて設定のコード全体を掲載します。
〆
え?「CubeMX に頼ればいいじゃないか」??聞こえませんねえ...