Upgrade to PRO for Only $50/Year—Limited-Time Offer! 🔥

USB PD PPS制御IC CH224Aを動かしてみた

USB PD PPS制御IC CH224Aを動かしてみた

Avatar for tomorrow56 a.k.a ThousanDIY

tomorrow56 a.k.a ThousanDIY

November 29, 2025
Tweet

Transcript

  1. Masawo Yamazaki (@tomorrow56) • 電子回路設計エンジニア • 趣味: ガジェットの分解 ◦ Noteもやっています:

    https://note.com/tomorrow56 • 最近は3Dプリンタ成分と生成AI(ManusAI)が多めです X: @tomorrow56 https://manus.im/invitation/Z4GLFAVSBAWQYM 招待リンク @ManusAI
  2. USB PD PPS とは • USB PDとは ◦ 「USB Power

    Delivery(USBパワーデリバリー)」の略で、USB Type- Cケーブルを通じて機器に高出力の電力供給を行うための技術規格。 最大240Wの電力供給が可能。 • USB PD PPSとは ◦ USB PDの拡張機能で、「Programmable Power Supply」の略。 細かく電圧と電流を動的に調整できる。 • USB PDとPPSの違い ◦ USB PD: あらかじめ決められた電圧(5V、9V、15V、20Vなど)から選択。 ◦ USB PD PPS: 電圧を100mV単位、電流を50mA単位で調整可能。
  3. USB PD 急速充電受電IC CH224シリーズとは • USB PD規格対応機能が統合されたプロトコル受電チップ • 最新のPD3.2 EPR

    140W規格に対応する高性能モデルCH224Q/Aと、広く普及しているPD3.0 100Wに対応するCH224K/D/221Kモデルで構成 モデル別仕様比較 特徴 CH224Q/CH224A CH224K CH224D CH221K 対応プロトコル PD3.2 EPR, AVS, PPS, SPR, BC1.2 PD3.0 PD3.0 PD3.0 最大電力 140W 100W 100W 100W 設定方法 単一抵抗, I/Oレベル, I2C 単一抵抗, I/Oレベル 単一抵抗, I/Oレベル 単一抵抗 パッケージ DFN10 (CH224Q), ESSOP10 (CH224A) ESSOP10 QFN20 SOT23-6
  4. CH224Aのピンリスト ピン番号 名称 タイプ 機能説明 0 GND P 共通グランド、放熱用底面パッド。 1

    VHV P 動作電源入力。 外付けに1uFの対地コンデンサを接続(耐圧に注意) 2 CFG2/SCL I, PU 電源レベル設定入力ピン2、またはI2Cクロック入力ピン。 3 CFG3/SDA I/O, PU 電源レベル設定入力ピン3、またはI2Cデータ双方向ピン。 4 DP I/O USBバス DPライン。 5 DM I/O USBバス DMライン。 6 CC2 I/O Type-C CC信号線。 7 CC1 I/O Type-C CC信号線。 8 VBUS I 電圧検出入力。VHVピンに短絡する必要がある。 9 CFG1 I 電源レベル設定入力ピン1。 10 PG OD Power Goodインジケータ。ローレベル有効。 機能はカスタマイズ可能。
  5. CH224A I2Cレジスタマップ • 単一抵抗設定モードを選択した場合、I2C設定機能が自動的に有効になる • CH224Aの7ビットI2Cアドレスは 0x22 または 0x23 (今回は0x22を使用)

    アドレス 名称 機能 0x09 I2C状態レジスタ 現在のプロトコル状態を取得(読み取り専用) [0]: BC1.2, [1]QC2.0, [2]QC3.0, [3]PD, [4]EPR 0x0A 電圧制御レジスタ 要求電圧切替(書き込み専用) 0: 5V, 1: 9V, 2: 12V, 3: 15V 4: 20V, 5: 28V, 6:PPSモード, 7: AVSモード 0x50 電流データレジスタ 電源アダプタが供給可能な最大電流値(読み取り専用) 50mA単位 0x51 AVS電圧設定レジスタ(上位) AVSモードで要求する電圧を100mV単位で設定(書き込み専用) 最初に下位8ビット(0x52)を書き込み 次に上位7ビットと有効化ビット[15]:1(0x51)を書き込む 0x52 AVS電圧設定レジスタ(下位) 0x53 PPS電圧設定レジスタ PPSモードで要求する電圧を100mV単位で設定(書き込み専用) 最初にこのレジスタに電圧値を書き込み 次に電圧制御レジスタ(0x0A)をPPSモードに設定する 0x60 ~0x8F PD電源データレジスタ 電源アダプタが提供する全ての電源能力情報(読み取り専用) SRCCAPまたはEPR_SRCCAPが格納される PPSモードの基本制御で 使うのはこの2つだけ
  6. M5Stack用に実装したコード例 M5Stack_CH224A_PPS.ino ライブラリとPin定義 #include <M5Unified.h> #include <Wire.h> // M5Stack Pin

    config #define VBUS_I 35 #define VI_I 36 #define CFG2_O 22 #define CFG3_O 21 #define VBUSEN_O 2 #define PG_I 12 const int sdaPin = CFG3_O; const int sclPin = CFG2_O; CH224Aレジスタ定義 // CH224A I2Cアドレス #define CH224A_ADDR 0x22 // CH224Aレジスタアドレス #define REG_I2C_STATUS 0x09 #define REG_VOLTAGE_CTRL 0x0A #define REG_CURRENT_MAX 0x50 //50mA step #define REG_AVS_VOLTAGE_H 0x51 //100mV step #define REG_AVS_VOLTAGE_L 0x52 #define REG_PPS_VOLTAGE 0x53 //100mV step // 0x60-0x8F REG_SRCCAP_DATA_x // 電圧モード #define VOLTAGE_5V 0 #define VOLTAGE_9V 1 #define VOLTAGE_12V 2 #define VOLTAGE_15V 3 #define VOLTAGE_20V 4 #define VOLTAGE_28V 5 #define VOLTAGE_PPS 6 #define VOLTAGE_AVS 7
  7. M5Stack用に実装したコード例 M5Stack_CH224A_PPS.ino グローバル変数と関数プロトタイプ // 固定電圧プリセット const int fixedVoltages[] = {5,

    9, 12, 15, 20, 28}; const int fixedVoltageCount = 6; // グローバル変数 bool ppsMode = false; // PPSモード有効/無効 int currentFixedIndex = 0; // 現在の固定電圧インデックス int currentPPSVoltage = 55; // 現在のPPS電圧(0.1V単位、5.5V) int minPPSVoltage = 55; // 最小PPS電圧(5.5V) int maxPPSVoltage = 200; // 最大PPS電圧(20.0V) int ppsStep = 1; // PPS電圧ステップ(0.1V) // 関数プロトタイプ void writeRegister(uint8_t reg, uint8_t value); void setFixedVoltage(int voltageMode); void setPPSVoltage(int voltage); void updateDisplay(); void drawButton(int x, int y, int w, int h, const char* label, uint16_t color); 初期設定 void setup() { pinMode(VBUSEN_O, OUTPUT); digitalWrite(VBUSEN_O, LOW); auto cfg = M5.config(); cfg.internal_imu = false; cfg.internal_rtc = false; M5.begin(cfg); // I2C初期化 Wire.begin(sdaPin, sclPin); // 画面初期化 M5.Display.fillScreen(BLACK); M5.Display.setTextSize(2); M5.Display.setTextColor(WHITE); // タイトル表示 M5.Display.fillRect(0, 0, 320, 35, NAVY); M5.Display.setTextColor(WHITE); M5.Display.drawCentreString("CH224A PPS Controller", 160, 3, 2); // 初期電圧設定(5V) delay(100); setFixedVoltage(VOLTAGE_5V); currentFixedIndex = 0; updateDisplay(); // 出力ON digitalWrite(VBUSEN_O, HIGH); }
  8. M5Stack用に実装したコード例 M5Stack_CH224A_PPS.ino メインループ void loop() { M5.update(); // ボタンA: 電圧を下げる

    if (M5.BtnA.wasPressed()) { if (ppsMode) { // PPSモード: 電圧を下げる currentPPSVoltage -= ppsStep; if (currentPPSVoltage < minPPSVoltage) { currentPPSVoltage = minPPSVoltage; } setPPSVoltage(currentPPSVoltage); } else { // 固定電圧モード: 前の電圧に切り替え currentFixedIndex--; if (currentFixedIndex < 0) { currentFixedIndex = 0; } setFixedVoltage(currentFixedIndex); } updateDisplay(); } // ボタンB: モード切替 if (M5.BtnB.wasPressed()) { ppsMode = !ppsMode; if (ppsMode) { // PPSモードに切り替え setPPSVoltage(currentPPSVoltage); } else { // 固定電圧モードに切り替え setFixedVoltage(currentFixedIndex); } updateDisplay(); } // ボタンC: 電圧を上げる if (M5.BtnC.wasPressed()) { if (ppsMode) { // PPSモード: 電圧を上げる currentPPSVoltage += ppsStep; if (currentPPSVoltage > maxPPSVoltage) { currentPPSVoltage = maxPPSVoltage; } setPPSVoltage(currentPPSVoltage); } else { // 固定電圧モード: 次の電圧に切り替え currentFixedIndex++; if (currentFixedIndex >= fixedVoltageCount) { currentFixedIndex = fixedVoltageCount - 1; } setFixedVoltage(currentFixedIndex); } updateDisplay(); } delay(10); }
  9. M5Stack用に実装したコード例 M5Stack_CH224A_PPS.ino CH224Aレジスタ設定 // CH224Aレジスタに書き込み void writeRegister(uint8_t reg, uint8_t value)

    { Wire.beginTransmission(CH224A_ADDR); Wire.write(reg); Wire.write(value); Wire.endTransmission(); delay(50); // 設定反映待ち } // 固定電圧を設定 void setFixedVoltage(int voltageMode) { writeRegister(REG_VOLTAGE_CTRL, voltageMode); } // PPS電圧を設定 void setPPSVoltage(int voltage) { // PPS電圧設定(0.1V単位) writeRegister(REG_PPS_VOLTAGE, voltage); // PPSモードに切り替え writeRegister(REG_VOLTAGE_CTRL, VOLTAGE_PPS); }
  10. // 画面更新 void updateDisplay() { // メイン表示エリアをクリア M5.Display.fillRect(0, 40, 320,

    180, BLACK); // モード表示 M5.Display.setTextColor(YELLOW); M5.Display.setTextSize(2); if (ppsMode) { M5.Display.drawCentreString("Mode: PPS", 160, 50, 2); } else { M5.Display.drawCentreString("Mode: Fixed Voltage", 160, 50, 2); } // 電圧表示 M5.Display.setTextColor(GREEN); M5.Display.setTextSize(2); String voltageStr; if (ppsMode) { float voltage = currentPPSVoltage / 10.0; voltageStr = String(voltage, 1) + "V"; } else { voltageStr = String(fixedVoltages[currentFixedIndex]) + "V"; } M5.Display.drawCentreString(voltageStr, 160, 100, 4); // 電圧範囲表示(PPSモードのみ) if (ppsMode) { M5.Display.setTextColor(CYAN); M5.Display.setTextSize(2); String rangeStr = "Range: " + String(minPPSVoltage / 10.0, 1) + "V - " + String(maxPPSVoltage / 10.0, 1) + "V"; M5.Display.drawCentreString(rangeStr, 160, 160, 2); } M5Stack画面表示関連 M5Stack用に実装したコード例 M5Stack_CH224A_PPS.ino // ボタンラベル表示 drawButton(10, 220, 90, 20, "DOWN", BLUE); drawButton(115, 220, 90, 20, "MODE", ORANGE); drawButton(220, 220, 90, 20, "UP", BLUE); } // ボタンラベル描画 void drawButton(int x, int y, int w, int h, const char* label, uint16_t color) { M5.Display.fillRect(x, y, w, h, color); M5.Display.setTextColor(WHITE); M5.Display.setTextSize(1); int textX = x + w / 2; int textY = y + h / 2 - 8; M5.Display.drawCentreString(label, textX, textY, 2); }