Upgrade to Pro — share decks privately, control downloads, hide ads and more …

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

Sponsored · Your Podcast. Everywhere. Effortlessly. Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.

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); }