
做過帶電池的嵌入式產品就會知道選型階段讓人興奮的是 MCU 的主頻、外設數量和跑分真正裝機后讓人頭疼的卻是另外一回事待機電流壓不下去、DCDC 紋波把 ADC 采樣帶偏、外設上電時序不對導致偶發(fā)死機。最近一版項目里我把主控定為 TM4C1299KCZAD電源部分全部交給 PCA9422 這顆 PMIC 來管把原本板子上散落的多路 DCDC、LDO、充電管理和電壓監(jiān)測整合到了一顆芯片里。這篇文章就把這個組合的完整實現過程拆開講一遍從為什么這么選、硬件怎么接、軟件狀態(tài)機怎么寫到實測數據和踩過的坑。先交代一下場景。這套方案做的是一個帶電池供電的工業(yè)數據采集網關主控需要以太網、USB、多路串口和比較強的浮點運算能力TM4C1299KCZADCortex-M4F 內核非常合適。難的是供電鏈路系統里同時存在 3.3V 邏輯、1.8V 存儲、0.9V 內核電壓部分外設還要兼容鋰電池充電、外部 5V 適配器供電、深度休眠時整機電流控制在微安級。用分立器件搭這套電源樹林不是不行但動態(tài)調壓、模式切換、充電管理都要自己做邏輯稍有不慎就變成一個巨大的調試黑洞。PCA9422 就是把這些問題一次性打包處理掉。1. 方案選型與整體設計思路1.1 為什么省不掉 PMIC 這顆芯片很多工程師慣用的做法是一顆降壓芯片給 MCU 供電幾顆 LDO 給傳感器和外設供電再用 GPIO 控制負載開關實現外設斷電。這種方案的優(yōu)點是人人都能畫缺點卻在后半夜集中爆發(fā)。首先是啟動時序問題。MCU 上電不能比外設慢否則 IO 口可能出現倒灌電流多路 DCDC 的使能順序要靠 RC 延時甚至 CPLD 去湊每改一版硬件都要重新驗證。其次是功耗管理很粗暴系統進入低功耗狀態(tài)后LDO 自身的靜態(tài)電流常年掛在那里3.3V 待機想做到 100uA 以下都費勁。第三是動態(tài)電壓調節(jié)基本沒法做想根據負載高低調整電壓來省電分立的 DCDC 必須有反饋電阻網絡改電壓就要改電阻系統運行中根本做不到。PCA9422 這類 PMIC 把這些問題集中到一個芯片里解決多路 DCDC 和 LDO 集成在內部每一路的開關和輸出電壓都能通過 I2C 寄存器隨時調整有多檔預配置模式可以做到“硬件上電默認一個狀態(tài)、MCU 初始化后切換到另一個狀態(tài)”內置電池充電管理、電壓電流溫度監(jiān)測和中斷輸出正好填補了 MCU 在電源域上的管理盲區(qū)。1.2 PCA9422 與 TM4C1299KCZAD 的職責分配這套方案的總體邏輯非常簡單就是一句話PCA9422 負責“管電”TM4C1299 負責“控制”。PCA9422 處于系統電源鏈路的中心位置輸入來自鋰電池或外部 5V 適配器輸出給 MCU、存儲、通信模塊和傳感器。它內部有完整的電源路徑管理在適配器和電池同時存在時自動選擇供電來源并對電池進行充電。TM4C1299KCZAD 通過 I2C 總線讀寫 PCA9422 的寄存器執(zhí)行以下操作配置各路 DCDC/LDO 的電壓和開關狀態(tài)切換 PCA9422 的預配置模式例如從 BOOT 模式切到 RUN 模式再切到 SLEEP 模式讀取當前輸入電壓、電池電壓、內部溫度和各路輸出電流接收 PCA9422 的中斷通知低電壓告警、過溫保護、充電完成TM4C1299 本身也有很強的低功耗能力支持 Sleep、Deep Sleep 和 Hibernate 模式因此在系統級休眠時流程是MCU 先通過 I2C 讓 PCA9422 關掉外設供電通道再命令 PMIC 進入低功耗模式最后 MCU 自己進入 Hibernate。這樣整機功耗由“MCU 休眠功耗 PMIC 靜態(tài)功耗 必然泄漏電流”三部分組成可以做到非常低。1.3 目標系統的電源樹在具體畫板子之前先列出整機需要哪些電源軌這樣才知道 PCA9422 的通道怎么分配。我們這個項目的電源樹是這樣的電源軌電壓負載來源VCC_3V33.3VMCU、以太網 PHY、USB 邏輯PCA9422 DCDC1VCC_1V81.8V存儲芯片、部分傳感器PCA9422 DCDC2VCC_0V90.9V大功耗 FPGA 內核實際項目中PCA9422 DCDC3VCC_3V3_SENSOR3.3V可關斷氣體傳感器、運放PCA9422 LDO1VCC_REF2.5VADC 基準源PCA9422 LDO2VBAT3.0~4.2V電池直供 RTC、備份域電池輸入旁路MCU 本體是 3.3V 單電源供電內部 LDO 會自己降出 1.2V 核心電壓所以 TM4C1299 不需要單獨的 0.9V。但板子上如果有移動通信模組或者大規(guī)模邏輯器件PCA9422 的多路輸出能力就體現出價值了——它一個芯片最多可以提供好幾路獨立調壓輸出還支持 DVS動態(tài)電壓調整這是分立方案很難做到的。2. 硬件核心PCA9422 的電源資源與接線細節(jié)2.1 電源通道和可配置范圍PCA9422 是一顆高度集成的電源管理 IC內部主要包含以下資源三路高效率降壓轉換器DCDC1/2/3單路最大輸出電流通常在 600mA 左右輸出電壓可通過寄存器調節(jié)范圍大約從 0.6V 到 3.3V 以上兩路低壓差線性穩(wěn)壓器LDO1/2輸出電流相對小一些適合對紋波敏感的模擬電路鋰電池充電管理單元支持單節(jié)鋰離子/鋰聚合物電池恒流恒壓充電充電電流可配置電源路徑管理在適配器和電池之間自動切換系統沒電池時也能直接上電工作內部 ADC可測量輸入電壓、電池電壓、多路輸出電壓和芯片溫度I2C 接口、中斷輸出、多個 MODE 引腳實際項目中哪些用 DCDC、哪些用 LDO需要按負載類型來區(qū)分。數字核心、通信模組這種大電流且對紋波不敏感的負載放 DCDC 上模擬前端、基準源這種對噪聲敏感的負載放 LDO 上。PCA9422 的 DCDC 頻率內部固定但外圍電感取值要和它匹配通常選 2.2uH 到 4.7uH飽和電流按最大負載電流的 1.5 倍以上留裕量。電容方面每路輸出建議至少一顆 22uF 陶瓷電容并聯一顆 0.1uF 高頻旁路布局時先經過電感、再進電容、最后才到負載器件順序不能反。2.2 關鍵引腳與主控的物理連接TM4C1299KCZAD 和 PCA9422 之間最核心的連接只有四條線加若干控制線我做成了這樣的引腳分配功能PCA9422 引腳TM4C1299KCZAD 引腳說明I2C 時鐘SCLI2C0SCLPB21MHz Fast ModeI2C 數據SDAI2C0SDAPB3同上中斷輸出INTGPIOPH0下降沿觸發(fā)PMIC 事件通知模式引腳MODE0/MODE1GPIO 或硬件撥碼上電默認配置選擇這里有一個非常容易被忽略的點MODE 引腳決定了 PCA9422 在上電瞬間使用哪一套默認配置而 MCU 此時往往還沒初始化 I2C。如果板子設計時把 MODE 引腳接到 MCU 的 GPIO 上那么這個 GPIO 必須有默認上拉或下拉確保 MCU 復位期間 MODE 引腳的電平是確定的。我實際遇到過 GPIO 懸空、默認狀態(tài)不定導致 PMIC 上電就跑進錯誤配置的情況整板電流直接多出幾十毫安排查了很久。PCA9422 的 I2C 地址在手冊里有明確說明通常是 7 位地址具體值以實際絲印和手冊為準。I2C 總線上記得加 2.2kΩ 到 4.7kΩ 的上拉電阻如果 PCB 走線比較長2.2kΩ 優(yōu)先。TM4C1299 的 I2C 模塊支持 100kHz 到 3.4MHz為了在噪聲環(huán)境下穩(wěn)定我當時鎖定了 400kHz漏極開路加上拉效果很好。2.3 上電時序與復位策略PCA9422 上電后處于其 OTP出廠預配置狀態(tài)這個狀態(tài)是原廠燒錄或者通過寄存器配置后保存的。上電瞬間它就會按照默認配置輸出各路電壓。因此硬件上電時很長一段時間里MCU 和所有負載都是在 PCA9422 默認配置下工作的。設計時必須把這一事實嵌入到整個系統的上電時序邏輯中系統接入適配器或電池PCA9422 上電按 OTP 默認配置輸出各路電壓如果默認配置中 3.3V 輸出是開啟的MCU 開始復位、啟動MCU 運行 bootloader 期間I2C 初始化然后讀取 PCA9422 寄存器確認當前電源狀態(tài)MCU 寫入實際所需配置覆蓋默認配置如調整 DCDC2 電壓、關閉用不到的 LDO確認配置完成后系統進入正常 RUN 模式這個流程意味著 PCA9422 的 OTP 默認配置必須保證“裸機也能跑 MCU”所以 OTP 里的 3.3V 通道通常要預設開啟。如果默認配置把關鍵通道關了MCU 根本起不來調試就無法進行。PCA9422 通常會有一個硬件復位引腳有些 PMIC 叫 RSTB、有些叫 nRESET。這個引腳的用途是當 MCU 通過 I2C 對 PMIC 的狀態(tài)控制失效時用硬件方式把 PMIC 拉回默認狀態(tài)。不要把該引腳直接接地最好通過一個 GPIO 控制這樣軟件里可以執(zhí)行“軟復位 PMIC”的操作。我在調試階段頻繁切換模式偶爾會把 PMIC 弄到異常狀態(tài)這個硬件復位引腳成了救命稻草。3. 主控側資源分析與低功耗配合3.1 TM4C1299KCZAD 上具體用到哪些模塊TM4C1299KCZAD 外設很豐富但電源管理方案里真正用到的模塊并不多反而越精簡越穩(wěn)定。我用到了以下資源I2C0它運行在 400kHz承擔所有 PMIC 寄存器讀寫GPIO 中斷PCA9422 的 INT 引腳接到 PH0配置為下降沿觸發(fā)的中斷輸入ADC0用來采樣輸入電壓、電池分壓電壓和外部電流檢測放大器輸出Hibernate 模塊系統深度休眠時保留 RTC也可以設置喚醒源RTC 定時器或 GPIO 喚醒TM4C1299 的 ADC 是 12 位的如果直接測量鋰電池電壓4.2V 超出了 ADC 量程需要先用電阻分壓再進 ADC。分壓電阻要選高阻值比如 100kΩ 200kΩ減少電池側漏電同時在 ADC 引腳并聯一個 100nF 電容做濾波。我用的分壓比是 1/3這樣 4.2V 變成 1.4V落在 3.3V 量程內還有余量。另外測量充電電流時要用低側電流檢測方案在電池負端與地之間串聯一個 50mΩ 采樣電阻電流信號通過運放放大后接 ADC。TM4C1299 內部有運放資源本項目中用到了內部集成運放用內部運放可以減少一顆外部芯片。這里的放大倍數要算好充電電流最大 1A50mΩ 上壓降 50mV放大 20 倍正好 1VADC 采樣值就在一個比較舒服的范圍內。3.2 系統狀態(tài)與 PMIC 供電檔位的配合電源管理最核心的就是把“系統運行狀態(tài)”和“電源芯片輸出狀態(tài)”對應起來。我們定了四個系統狀態(tài)系統狀態(tài)MCU 自身狀態(tài)PCA9422 輸出狀態(tài)適用場景RUNRun 模式 120MHz所有通道全開DCDC1 3.3V、DCDC2 1.8V、DCDC3 0.9V、LDO1/2 開啟正常采集、通信IDLESleep 模式DCDC2/3 和 LDO 關閉DCDC1 保持 3.3V短時等待、數據暫存HIBERNATEHibernate 模式只保留一路 3.3V 給 MCU RTC 和備份域其余全部關閉長時間待機SHUTDOWN完全斷電PMIC 關閉輸出全部通道關閉PMIC 自身進入低功耗待機產品關機但電池不拔這里有一個經驗不要試圖把 MCU 狀態(tài)切到 Hibernate 之后再通過 I2C 去關 PMIC因為 MCU 進入 Hibernate 后 I2C 已經停了。正確的順序是MCU 處于 RUN 模式先通過 I2C 關閉 PCA9422 上所有非關鍵輸出通道等待 PMIC 輸出電壓穩(wěn)定讀取狀態(tài)寄存器確認再執(zhí)行 TM4C1299 的 Hibernate 指令讓 MCU 自身進入低功耗喚醒時 MCU 先恢復執(zhí)行再通過 I2C 打開 PCA9422 上被關閉的通道這個順序問題值得特別注意我在初期驗證時直接先讓 MCU 進了 Hibernate結果 PMIC 把所有外設電都斷了但 MCU 自己的 3.3V 還在一覺醒來之后 I2C 通信完全正常不過外設重新上電需要額外的延時啟動邏輯就多了一堆狀態(tài)判斷。后來把 PMIC 關電放在 MCU 待機前整個流程干凈很多。4. 軟件實現從 I2C 驅動到電源狀態(tài)機4.1 PMIC 寄存器讀寫驅動PCA9422 的寄存器操作是標準的 I2C 從設備通信。我基于 TivaWare 庫寫了下面這套讀寫函數直接可以作為項目底子#define PCA9422_I2C_ADDR 0x10 // 具體地址以實際手冊為準 uint8_t pmic_read_reg(uint8_t reg, uint8_t *value) { uint8_t tx_data reg; uint8_t rx_data 0; uint32_t err_code 0; // 先發(fā)送寄存器地址 err_code I2C0_Transfer(g_pmic_i2c, PCA9422_I2C_ADDR, I2C_MASTER_CMD_SINGLE_SEND, tx_data, 1, 0, 0, 0); if (err_code) return err_code; // 再讀取數據 err_code I2C0_Transfer(g_pmic_i2c, PCA9422_I2C_ADDR, I2C_MASTER_CMD_SINGLE_RECEIVE, rx_data, 1, 0, 0, 0); if (err_code) return err_code; *value rx_data; return 0; } uint8_t pmic_write_reg(uint8_t reg, uint8_t value) { uint8_t tx_buf[2] { reg, value }; uint32_t err_code 0; err_code I2C0_Transfer(g_pmic_i2c, PCA9422_I2C_ADDR, I2C_MASTER_CMD_SINGLE_SEND, tx_buf, 2, 0, 0, 0); return err_code; }I2C 驅動的核心就這兩個函數所有上層功能都建立在它們之上。有一點要提醒I2C 讀寫失敗時絕不能直接忽略錯誤繼續(xù)執(zhí)行否則后續(xù)幾十個寄存器參數可能是寫到空氣里的。我在工程代碼里加了錯誤重試機制連續(xù)讀寫失敗 3 次就觸發(fā) PMIC 硬件復位復位后再重新初始化。這個機制救過我好幾次特別是現場環(huán)境差、電源波動大的時候。4.2 上電初始化從默認配置覆蓋到實際運行配置MCU 啟動后執(zhí)行完外設時鐘和 GPIO 初始化緊接著就是 PMIC 初始化。初始化順序非常講究大體上分為三步先讀 PCA9422 的 DEVICE ID 寄存器確認 I2C 通信正常。如果讀不到任何有效數據大概率是總線被拉死或 PMIC 不在所期望的地址上這時候要先查硬件別急著寫驅動。然后配置所有通道的輸出電壓寄存器但此時先不打開通道使能。先調電壓再使能是原則否則在調整過程中輸出電壓瞬態(tài)掉到負載器件的最低工作電壓以下系統會直接復位。最后打開通道使能。使能順序也要按照負載依賴關系來先開 MCU 所在通路3.3V再開需要 3.3V 作為參考的 1.8V最后開大電流負載所在通路。PCA9422 本身有上電時序控制能力但 MCU 接管后最好自己再控制一遍流程。void pmic_init(void) { uint8_t id 0; // 第一步確認通信 if (pmic_read_reg(REG_DEVICE_ID, id) ! 0) { // 觸發(fā)硬件復位后重試 pmic_hw_reset(); delay_ms(10); pmic_read_reg(REG_DEVICE_ID, id); } // 第二步配置所有輸出電壓先不使能 pmic_write_reg(REG_DCDC1_VSEL, 0x1E); // 3.3V pmic_write_reg(REG_DCDC2_VSEL, 0x1D); // 1.8V pmic_write_reg(REG_DCDC3_VSEL, 0x09); // 0.9V pmic_write_reg(REG_LDO1_VSEL, 0x1E); // 3.3V pmic_write_reg(REG_LDO2_VSEL, 0x1A); // 2.5V // 第三步按順序使能輸出通道 pmic_write_reg(REG_DCDC1_EN, 0x01); delay_ms(1); pmic_write_reg(REG_DCDC2_EN, 0x01); pmic_write_reg(REG_DCDC3_EN, 0x01); delay_ms(1); pmic_write_reg(REG_LDO1_EN, 0x01); pmic_write_reg(REG_LDO2_EN, 0x01); // 第四步使能 PMIC 中斷上報 pmic_write_reg(REG_INT_MASK, 0x00); // 不屏蔽任何中斷 }實際寄存器地址和數值映射以手冊為準思想就是“先電壓、后使能、按順序、有確認”。初始化完成后再看一遍關于充電的寄存器如果電池電壓低于閾值且適配器在位就使能充電。4.3 電源狀態(tài)機的實現細節(jié)系統運行時電源狀態(tài)之間的切換集中在下面這個函數里。我把它設計成同步阻塞式的每一次狀態(tài)切換都會等待 PMIC 寄存器回讀確認確保切完了才往下走。void pm_set_state(pm_state_t target_state) { // 通知應用層準備離開當前狀態(tài) pm_pre_change_callback(current_state, target_state); switch (target_state) { case PM_STATE_ACTIVE: // 打開所有輸出通道 pmic_write_reg(REG_DCDC1_VSEL, 0x1E); pmic_write_reg(REG_DCDC2_EN, 0x01); pmic_write_reg(REG_DCDC3_EN, 0x01); pmic_write_reg(REG_LDO1_EN, 0x01); pmic_write_reg(REG_LDO2_EN, 0x01); // 等待輸出穩(wěn)定 delay_ms(2); break; case PM_STATE_IDLE: // 關閉外設供電保留 MCU 通道 pmic_write_reg(REG_LDO1_EN, 0x00); pmic_write_reg(REG_LDO2_EN, 0x00); pmic_write_reg(REG_DCDC3_EN, 0x00); pmic_write_reg(REG_DCDC2_EN, 0x00); break; case PM_STATE_HIBERNATE: // 只保留一路給 MCU RTC pmic_write_reg(REG_DCDC3_EN, 0x00); pmic_write_reg(REG_DCDC2_EN, 0x00); pmic_write_reg(REG_LDO1_EN, 0x00); pmic_write_reg(REG_LDO2_EN, 0x00); break; case PM_STATE_SHUTDOWN: // 關閉全部輸出通道進入低功耗待機 pmic_write_reg(REG_DCDC1_EN, 0x00); pmic_write_reg(REG_DCDC2_EN, 0x00); pmic_write_reg(REG_DCDC3_EN, 0x00); pmic_write_reg(REG_LDO1_EN, 0x00); pmic_write_reg(REG_LDO2_EN, 0x00); pmic_write_reg(REG_SYS_CTRL, 0x00); // PMIC 進入待機模式 break; } current_state target_state; // 通知應用層已進入新狀態(tài) pm_post_change_callback(current_state, target_state); }這里必須說明一點如果 PM_STATE_SHUTDOWN 要關閉的通道里包含 MCU 自己的 3.3V 供電那么 MCU 在執(zhí)行這一句之后會立刻掉電后續(xù)代碼根本不會運行。所以實際項目中 SHUTDOWN 狀態(tài)有兩種含義一種是整機關機這種操作通常由 MCU 發(fā)出一條指令寫入 PMIC 寄存器然后 PMIC 會把自身的電源輸出全部關閉MCU 是被斷電的一方根本走不到回調函數另一種是 MCU 還活著但系統外設全關那其實等價于 IDLE 狀態(tài)。為了保險我通常在執(zhí)行關機命令前先把關鍵數據寫入非易失存儲再延時幾十毫秒最后才發(fā)關機寄存器命令。延時是為了讓最后的數據寫入完成。4.4 中斷處理PMIC 主動通知 MCUPCA9422 的 INT 引腳是低電平有效的中斷輸出。當發(fā)生過壓、欠壓、過溫、充電完成、按鈕事件等狀態(tài)變化時PMIC 會把 INT 引腳拉低TM4C1299 的 PH0 檢測到下降沿后進入中斷服務函數。中斷服務函數里不要做太多事正確做法是進入 ISR 后清除中斷標志通過 I2C 讀取 PMIC 的中斷狀態(tài)寄存器判斷具體是哪類事件如果是低電壓告警設置一個全局事件標志回到主循環(huán)再處理如果是過溫告警立即降低負載關閉非關鍵通道然后再通知應用層void GPIOH_IRQHandler(void) { uint8_t int_status 0; // 清除 GPIO 中斷標志 GPIOIntClear(GPIO_PORTF_BASE, GPIO_PIN_0); pmic_read_reg(REG_INT_STATUS, int_status); if (int_status INT_LOWBAT) { g_pm_events | PM_EVENT_LOW_BATTERY; } if (int_status INT_OVERTEMP) { // 直接降低負載不進主循環(huán) pmic_write_reg(REG_LDO1_EN, 0x00); pmic_write_reg(REG_LDO2_EN, 0x00); g_pm_events | PM_EVENT_OVERTEMP; } }在 I2C 中斷服務函數里直接調用阻塞式 I2C 通信理論上可行但速度太慢。我實際測試下來TivaWare 的 I2C 傳輸是阻塞式輪詢單次傳輸大約幾十微秒在中斷里執(zhí)行也問題不大前提是中斷頻率不能太高。如果 PMIC 在異常狀態(tài)下頻繁上報中斷ISR 可能會被 I2C 阻塞占滿正常任務全部餓死。應對辦法是在 ISR 里只讀一次中斷狀態(tài)寄存器然后立刻返回后續(xù)處理全部丟給主循環(huán)事件表。5. 實測數據與故障排查實錄5.1 四種狀態(tài)模式下的功耗參考調試完成之后用高精度萬用表對整個系統供電鏈路做了功耗測量。以下數據是針對我們這款帶以太網接口、若干傳感器和通信模組的網關整機不代表所有 TM4C1299 PCA9422 組合都能達到同樣水平但可以作為參考系統狀態(tài)整機電流3.7V 電池端主要耗電來源RUN 正常采集 以太網通信86mAMCU 約 40mA、以太網 PHY 約 30mA、傳感器約 10mA、PMIC 靜態(tài)約 1mAIDLE 等待外設關斷MCU Sleep8.2mAMCU 內部 LDO 和 RAM 保持HIBERNATE外設全關MCU Hibernate38uAMCU Hibernate 約 2uA、PMIC 待機約 20uA、電源鏈路泄漏SHUTDOWNPMIC 全關電池在線15uAPMIC 自身待機電流 電池保護板靜態(tài)電流這里 HIBERNATE 狀態(tài)整機 38uA 是我們花了大力氣才做到的。最初測量時是 1.6mA排查后發(fā)現問題不在 MCU也不在 PMIC而在以太網 PHY 的供電鏈路上PHY 芯片的 3.3V 電源雖然被 LDO1 關斷了但 PHY 的復位引腳還通過一個上拉電阻掛在 3.3V 電源軌上這個電阻在系統休眠時把 PHY 的電源引腳反向灌了一部分電流。把上拉改到 MCU 的 GPIO 上、由 MCU 控制復位腳電平后待機電流立刻降下來了。這個案例給所有做低功耗的人提個醒斷電時電流不從斷電的那一路走而是從所有相連的 GPIO、信號線、上拉電阻上悄悄漏掉。5.2 踩過的三個典型坑說幾個調試過程中遇到的實際問題每一個都在現場消耗了半天以上時間。第一個是 I2C 總線掛死。現象是 MCU 讀取 PMIC 寄存器時偶爾返回超時而且一旦發(fā)生就持續(xù)無法恢復必須按復位鍵。排查過程很曲折最后發(fā)現是 PMIC 的中斷引腳和 I2C 數據線在 PCB 上相距太近中斷腳頻繁翻轉時對 SDA 產生耦合干擾。解決辦法是在 PCB 改版。臨時方案則是在 I2C 驅動里增加軟件復位連續(xù)超時兩次就通過 GPIO 把 PMIC 的硬件復位腳拉低再釋放強制 PMIC 重新上電初始化。如果大家是已經畫完板的情況建議先把 I2C 速率降到 100kHz 試試很多時候能緩解但不能根治。第二個是低負載電流下 DCDC 輸出紋波變大。系統在 IDLE 狀態(tài)下外設全部關閉后DCDC1 負載只有 MCU 的幾毫安這時 DCDC 會進入輕載模式表現為間歇性開關輸出紋波峰值接近 30mV能夠干擾到模擬傳感器。解決方法是關閉 PMIC 的輕載省電模式如果有相關寄存器讓 DCDC 保持連續(xù)導通模式CCM紋波可以降到 10mV 以下。代價是輕載時靜態(tài)電流稍微增大在 IDLE 這種只有幾毫安的場景下完全可以接受。第三個是充電管理使能后電池發(fā)熱。這是硬件參數問題。PCA9422 有可配置的充電電流和截止電壓我一開始把充電電流直接設到了 1A結果 800mAh 的小電池被 1A 電流猛灌開會 30 分鐘就明顯燙手。正確做法是按電池容量 0.5C 計算充電電流800mAh 電池限制在 400mA同時配置截止電壓 4.2V ± 1%在溫度超過 45°C 時通過 PMIC 的充電溫度保護自動降流。5.3 調試過程的一手經驗最后分享幾條寫進團隊內部文檔的經驗都是實際敲過釘子之后總結出來的。第一PMIC 寄存器初始化完成之后最好回讀一遍全部寫入的寄存器確認寫入值與預期一致。這個回讀動作如果放在 MCU 進入正式運行流程之前可以篩掉絕大部分 I2C 偶發(fā)錯誤導致的“假運行”問題。第二切換 DCDC 輸出電壓時一定要在空載或輕載狀態(tài)下進行。比如從 3.3V 切到 1.8V 時如果負載已經占了滿額 80% 以上電壓下降過程中會有一段區(qū)間輸出電壓低于負載最低工作電壓直接觸發(fā)系統看門狗復位。具體操作上我都是先讓外設進入休眠、斷開大電流負載再切電壓切完確認輸出穩(wěn)定后再恢復負載。第三系統級的電源狀態(tài)切換必須加延時。PMIC 寄存器寫入后輸出電壓不會立刻穩(wěn)定內部補償環(huán)路需要一個過程。我實測通常在寫入使能寄存器后等待 1ms 到 2ms輸出電壓的瞬態(tài)過沖和跌落才會收斂到目標值以內。如果等待時間不足后級負載的供電電壓會出現一個“深坑”或者“尖峰”對整個系統都有威脅。第四PCA9422 的 MODE 引腳在量產板上建議用電阻固定到確定的電平而不是裸奔接 GND 或 VCC。固定電平的腳也要加上下拉電阻方便測試時飛線修改。調試階段我通過 MODE 引腳的組合快速切換過好幾套預配置省下了反復燒錄 OTP 的時間量產階段鎖死為上電默認 ACTIVE 狀態(tài)穩(wěn)定性有保證。6. 這套方案還能怎么擴展目前這套 PCA9422 TM4C1299KCZAD 的電源管理框架不僅是針對特定產品做的絕大多數結構都是可復用資產。換一顆 MCU、換一個 PMIC 型號只要把驅動層寄存器配置替換掉上層狀態(tài)機幾乎可以原樣搬走。一些值得往下做的擴展方向電池電量估算是下一個可以集成的模塊。PCA9422 有電池電壓和電流 ADCTM4C1299 跑一個簡單的開路電壓法加庫侖積分法復合估算精度大約能做到 5% 以內。這比外掛電量計芯片省一顆料代價是算法標定工作。動態(tài)電壓調節(jié)也可以做深一步。當前是固定檔位切換如果外設對供電電壓要求比較寬可以根據負載狀態(tài)實時調節(jié) PCA9422 DCDC 的輸出電壓低負載時降低電壓省功耗高負載時提電壓保性能。PCA9422 的 DCDC 輸出寄存器本來就能實時改寫軟件只需要保證切換時機準確。多 PMIC 級聯也不是不行。如果系統里有一塊主電源板和多塊子板每塊子板各放一顆 PCA9422主控 TM4C1299 掛一條 I2C 總線管理多顆 PMIC每顆 PMIC 用不同地址區(qū)分。這樣整個系統的每個電源域都能統一拉電、統一監(jiān)測比每塊板子各自為政要可靠得多。回到電源管理本身我的感受是PMIC 這顆芯片把硬件上的雜亂電源方案收攏了但真正決定整機功耗和穩(wěn)定性的仍然是軟件統籌。MCU 和 PMIC 之間只有四條線跑在上面的卻是一整套狀態(tài)機、中斷事件和異常處理邏輯?;〞r間把狀態(tài)機設計清楚比調一天 DCDC 的反饋環(huán)路更有價值。這套方案從畫板到實測經歷了幾輪迭代整體達到預期的低功耗目標也希望這篇記錄能給做電源管理的人省下一些排查時間。