【実践解説】RP2040のPLL設定コードをC/C++で書いてみよう

マイコンの心臓“クロック”を手動でチューニングする~

RP2040は、Raspberry Pi財団が開発したデュアルコアCortex-M0+搭載のマイコンです。通常はPico SDKなどが自動で初期化してくれる「PLL(フェーズ・ロックド・ループ)」ですが、自分でクロック設定を制御したいという場面も出てきます。

本記事では、PLLの初期化コード(C/C++)とその解説を通して、RP2040のクロック制御の仕組みを深掘りしていきます!


🧠 そもそもPLLとは?

PLL(Phase-Locked Loop)とは、低速なクロック信号(例:12MHz水晶)を基にして、高速で安定したクロック(例:133MHz)を生成する回路です。

RP2040には2つのPLLがあります:

  • PLL_SYS:CPUやバスに供給(最大133MHz)

  • PLL_USB:USB用の48MHz専用クロックを生成


🧪 PLL設定の前提条件

PLLを自前で設定するためには、次のような環境が前提です:

  • RP2040向けPico SDKC/C++

  • pico-sdk/src/rp2_common/hardware_clocks/ にあるヘッダーが使用可能

  • hardware/clocks.h などのAPI利用


🧾 PLL設定のサンプルコード

ここでは、PLL_SYSを使って133MHzのクロックを生成する例を紹介します。

c
 
#include "pico/stdlib.h"
#include "hardware/clocks.h"
#include "hardware/pll.h"
#include "hardware/xosc.h"
 
int main() {
  // 外部水晶(XOSC)を12MHzで初期化
  xosc_init();
 
 // PLL_SYS初期化(VCO = 1500MHz, POSTDIV1 = 6, POSTDIV2 = 2)
 // 出力 = 1500 / 6 / 2 = 125MHz(ここでは125MHz例)
 pll_init(pll_sys, 1, 1500 * MHZ, 6, 2);
 
  // CLK_SYSにPLL_SYSを接続
  clock_configure(clk_sys,
   CLOCKS_CLK_SYS_CTRL_SRC_VALUE_CLKSRC_CLK_SYS_AUX,
   CLOCKS_CLK_SYS_CTRL_AUXSRC_VALUE_CLKSRC_PLL_SYS,
   125 * MHZ,
   125 * MHZ);
 
  // UART用のクロックも設定(例:115200bpsに合わせる)
  stdio_init_all();
 
  while (true) {
   printf("Hello, PLL world!\n");
   sleep_ms(1000);
  }
  return 0;
}

🔍 解説:各ステップの意味

1. xosc_init();

外部水晶発振子(XOSC)を12MHzで初期化します。PLLの基準クロックとなる大事な部分です。

2. pll_init(...)

pll_init(pll_sys, refdiv, vco_freq, post_div1, post_div2);

ここでは以下の式で出力周波数が決まります:

 
PLL出力 = VCO周波数 / post_div1 / post_div2

たとえば:

  • refdiv = 1(12MHz ÷ 1 = 12MHz入力)

  • vco_freq = 1500MHz

  • post_div1 = 6

  • post_div2 = 2

結果的に:1500 / 6 / 2 = 125MHzのシステムクロックになります。

3. clock_configure(...)

PLL出力を clk_sys に供給する設定。CPUクロックを含めた全体システムがこれに従います。


💡 実用Tips

  • 最大値は133MHzだが、無理に引き上げると動作不安定になる場合も。

  • 低消費電力化が目的なら、PLL出力を減らしてCPUクロックを下げるのもアリ。

  • USBを使うならPLL_USB(固定48MHz)も別途設定が必要。


🧭 まとめ

項目 説明
xosc_init() 外部12MHzクロック起動
pll_init() PLL出力クロック生成
clock_configure() PLL出力をCPUなどに割り当て

Pico SDKのおかげで、PLLの設定はたった数行のコードで簡潔に記述可能です。自分でクロック設定をすることで、パフォーマンスと省電力の最適化が可能になります!


📎 おまけ:最大クロックに設定するには?

c
pll_init(pll_sys, 1, 1596 * MHZ, 6, 2); // ≒133MHz
clock_configure(clk_sys, ..., 133 * MHZ, 133 * MHZ);

公式の仕様上、133MHzが最大値とされていますが、個体差によって160MHz以上で動作することもあります(ただし自己責任で!)