計(jì)與調(diào)試)
1. 從一顆MCU和一顆PMIC說起這套電源管理方案到底在解決什么問題如果你手頭有一個(gè)中等復(fù)雜度的嵌入式設(shè)備比如帶LCD屏的便攜儀器、多傳感器數(shù)據(jù)采集終端或者需要多路電壓域供電的工業(yè)控制器你大概率會(huì)遇到一個(gè)很現(xiàn)實(shí)的問題主控芯片、傳感器、顯示屏、通信模塊各自需要的電壓不一樣上電時(shí)序還有講究如果時(shí)序搞錯(cuò)了輕則外設(shè)不工作重則芯片閂鎖甚至燒毀。傳統(tǒng)的做法是用一堆分立LDO和DC-DC芯片拼出來每路電壓?jiǎn)为?dú)控制PCB上占一大片面積BOM成本也不低而且上電順序靠RC延時(shí)或者GPIO手動(dòng)控制可靠性完全看設(shè)計(jì)者的經(jīng)驗(yàn)。PCA9422就是為解決這類問題而生的。它是一顆高度集成的電源管理IC內(nèi)部集成了多路降壓轉(zhuǎn)換器和LDO支持通過I2C接口動(dòng)態(tài)配置輸出電壓和上電時(shí)序還帶電池充電管理功能。而PIC18F45K80是一顆經(jīng)典的8位MCU自帶I2C外設(shè)、豐富的GPIO和定時(shí)器資源用來做電源管理的“大腦”非常合適——它不需要跑操作系統(tǒng)裸機(jī)就能把PCA9422的寄存器配置得明明白白。這套組合的核心思路是PIC18F45K80通過I2C總線對(duì)PCA9422進(jìn)行初始化配置設(shè)定各路輸出電壓、上電時(shí)序、充電參數(shù)等然后在運(yùn)行過程中根據(jù)系統(tǒng)狀態(tài)動(dòng)態(tài)調(diào)整電源模式比如進(jìn)入低功耗時(shí)關(guān)閉某些電壓域。整個(gè)方案的好處是集成度高、配置靈活、軟件可控而且PIC18F45K80的資源對(duì)于這個(gè)任務(wù)來說綽綽有余成本也控制得住。這篇文章適合誰看如果你正在做嵌入式硬件設(shè)計(jì)需要管理多路電源或者你已經(jīng)在用PCA9422但還沒把它用透又或者你在選型階段想評(píng)估“MCUPMIC”這套方案是否靠譜那接下來的內(nèi)容應(yīng)該能幫你少走不少?gòu)澛?。我?huì)從硬件連接、I2C通信底層、寄存器配置邏輯、上電時(shí)序設(shè)計(jì)、低功耗模式切換、以及實(shí)際調(diào)試中踩過的坑這幾個(gè)維度把整套方案拆開講清楚。2. 硬件層PIC18F45K80與PCA9422的I2C連接與外圍電路設(shè)計(jì)2.1 I2C總線的物理連接與上拉電阻選型PIC18F45K80的I2C外設(shè)使用的是MSSP模塊支持主模式和從模式。在這個(gè)方案里PIC18F45K80作為I2C主機(jī)PCA9422作為從機(jī)。PCA9422的I2C地址由硬件引腳決定通常有幾種可選地址具體要看數(shù)據(jù)手冊(cè)的地址配置表。連接上PIC18F45K80的SDA和SCL分別接到PCA9422的SDA和SCL兩根線都需要加上拉電阻到邏輯電平電壓。上拉電阻的選型是個(gè)容易被忽視但很關(guān)鍵的細(xì)節(jié)。阻值太大上升沿變緩高速通信時(shí)波形會(huì)塌阻值太小灌電流太大增加功耗甚至超出IO的驅(qū)動(dòng)能力。經(jīng)驗(yàn)值是標(biāo)準(zhǔn)模式100kHz下用4.7kΩ到10kΩ快速模式400kHz下用2.2kΩ到4.7kΩ。但實(shí)際選型還要看總線電容——走線越長(zhǎng)、掛的設(shè)備越多電容越大上拉電阻就要相應(yīng)減小。我一般會(huì)在PCB上預(yù)留兩個(gè)上拉電阻位置調(diào)試時(shí)根據(jù)示波器看到的波形決定焊哪個(gè)阻值。另外要注意的是PCA9422的I2C電平閾值和PIC18F45K80的IO電平要匹配。如果PIC18F45K80跑在3.3VPCA9422的I2C也是3.3V邏輯那直接連就行。如果電壓不一致需要加電平轉(zhuǎn)換電路否則可能出現(xiàn)通信失敗或者長(zhǎng)期可靠性問題。2.2 電源輸入與輸出路徑的布局要點(diǎn)PCA9422的輸入通常來自鋰電池或者適配器輸出有多路比如一路給MCU供電3.3V或1.8V一路給傳感器供電2.8V一路給顯示屏背光供電5V或12V取決于屏幕。每路輸出的電流能力不同布局時(shí)要注意幾點(diǎn)。第一輸入電容和輸出電容要盡量靠近PCA9422的引腳特別是輸入電容它負(fù)責(zé)吸收輸入端的瞬態(tài)電流。如果放遠(yuǎn)了走線電感會(huì)導(dǎo)致電壓振鈴嚴(yán)重時(shí)可能觸發(fā)芯片的過壓保護(hù)。第二電感的選型要匹配PCA9422的開關(guān)頻率和電流能力電感飽和電流要留至少30%的余量。第三反饋引腳的分壓電阻要靠近芯片走線要短且遠(yuǎn)離電感的開關(guān)節(jié)點(diǎn)否則會(huì)引入噪聲導(dǎo)致輸出電壓不穩(wěn)。PIC18F45K80本身的供電也要注意。如果它由PCA9422的某一路輸出供電那這一路的上電時(shí)序必須保證在PCA9422自身初始化完成之后才輸出否則MCU還沒啟動(dòng)I2C通信就無從談起。這個(gè)邏輯后面講上電時(shí)序時(shí)會(huì)詳細(xì)展開。2.3 中斷與狀態(tài)引腳的利用PCA9422通常會(huì)有中斷輸出引腳用于向MCU報(bào)告事件比如充電完成、輸入電壓異常、溫度過高等。PIC18F45K80的RB0或RB1可以配置為外部中斷輸入接PCA9422的INT引腳。這樣MCU不需要一直輪詢PCA9422的狀態(tài)寄存器只在事件發(fā)生時(shí)響應(yīng)節(jié)省CPU資源。還有一個(gè)常被忽略的引腳是PCA9422的復(fù)位輸出或者電源就緒信號(hào)。如果PCA9422有PGPower Good信號(hào)可以接到PIC18F45K80的MCLR或者某個(gè)普通IO上讓MCU知道電源系統(tǒng)已經(jīng)穩(wěn)定可以開始執(zhí)行高功耗任務(wù)。這個(gè)信號(hào)在調(diào)試階段特別有用可以用示波器同時(shí)抓PG和I2C波形確認(rèn)上電時(shí)序是否符合預(yù)期。3. 軟件層用PIC18F45K80的MSSP模塊驅(qū)動(dòng)PCA9422的完整流程3.1 I2C底層驅(qū)動(dòng)的初始化與速率配置PIC18F45K80的MSSP模塊配置成I2C主模式需要設(shè)置幾個(gè)關(guān)鍵寄存器SSPCON1、SSPCON2、SSPADD、SSPSTAT。SSPADD寄存器用來設(shè)置I2C的時(shí)鐘速率計(jì)算公式是SSPADD (Fosc / (4 * Fscl)) - 1。假設(shè)PIC18F45K80跑在16MHz想要400kHz的I2C速率那SSPADD (16000000 / (4 * 400000)) - 1 9。實(shí)際寫入SSPADD的值就是9。初始化流程大致是先設(shè)置TRIS寄存器把SDA和SCL配置為輸入I2C模式下由外設(shè)控制方向然后配置SSPCON1為I2C主模式SSPCON2清零SSPSTAT根據(jù)需要設(shè)置擺率控制位。最后把SSPEN置1使能MSSP模塊。這些步驟看起來簡(jiǎn)單但順序不能亂特別是SSPEN的使能要在其他配置完成之后。注意PIC18F45K80的I2C引腳是復(fù)用引腳必須確保對(duì)應(yīng)的TRIS位和模擬功能選擇寄存器ANSEL配置正確。如果引腳被配置為模擬輸入數(shù)字功能會(huì)失效I2C通信直接不工作。這個(gè)坑我在第一次用PIC18F45K80時(shí)踩過排查了半天才發(fā)現(xiàn)是ANSEL沒清。3.2 寫一個(gè)可靠的I2C字節(jié)讀寫函數(shù)PIC18F45K80的MSSP模塊硬件處理了起始位、停止位、ACK/NACK的時(shí)序但軟件需要按順序操作寄存器。一個(gè)典型的寫字節(jié)流程是把數(shù)據(jù)寫入SSPBUF等待SSPIF標(biāo)志置位然后讀SSPCON2的ACKDT和ACKSTAT判斷從機(jī)是否應(yīng)答。讀字節(jié)流程類似但需要先發(fā)送讀地址然后設(shè)置ACKDT為0發(fā)送ACK或1發(fā)送NACK最后讀SSPBUF。這里有個(gè)細(xì)節(jié)在等待SSPIF標(biāo)志時(shí)一定要用超時(shí)機(jī)制不能死等。如果PCA9422因?yàn)槟撤N原因沒有應(yīng)答死等會(huì)導(dǎo)致整個(gè)系統(tǒng)卡死。我通常會(huì)用定時(shí)器做一個(gè)毫秒級(jí)的超時(shí)超時(shí)后返回錯(cuò)誤碼上層決定是重試還是報(bào)錯(cuò)。另一個(gè)細(xì)節(jié)是總線仲裁和時(shí)鐘拉伸。PCA9422在某些操作比如寄存器寫入生效時(shí)可能會(huì)拉伸SCL時(shí)鐘PIC18F45K80的MSSP模塊硬件支持時(shí)鐘拉伸但軟件上要確保在SCL被拉低時(shí)不會(huì)誤判為總線錯(cuò)誤。實(shí)際調(diào)試時(shí)如果發(fā)現(xiàn)通信偶爾失敗用示波器看SCL波形確認(rèn)是否有異常的時(shí)鐘拉伸。3.3 PCA9422寄存器寫入的封裝與校驗(yàn)PCA9422的寄存器是8位地址、8位數(shù)據(jù)的結(jié)構(gòu)但有些配置可能需要連續(xù)寫多個(gè)寄存器。我一般會(huì)封裝三個(gè)函數(shù)PCA9422_WriteReg(addr, data)、PCA9422_ReadReg(addr)、PCA9422_WriteMulti(addr, buf, len)。寫完之后立刻讀回來校驗(yàn)確認(rèn)寫入的值和讀回的值一致。這個(gè)校驗(yàn)步驟在調(diào)試階段非常有用可以快速定位是通信問題還是配置邏輯問題。對(duì)于關(guān)鍵的配置寄存器比如輸出電壓設(shè)置、上電時(shí)序控制我還會(huì)在寫入后加一個(gè)短延時(shí)比如1ms再讀回校驗(yàn)。因?yàn)镻CA9422內(nèi)部可能有時(shí)序要求寫入后需要一定時(shí)間才能生效。這個(gè)延時(shí)不是隨便定的要查數(shù)據(jù)手冊(cè)的時(shí)序表確認(rèn)寄存器寫入的建立時(shí)間。3.4 通信異常時(shí)的重試與恢復(fù)策略I2C通信在復(fù)雜電磁環(huán)境中偶爾出錯(cuò)是正常的關(guān)鍵是要有恢復(fù)機(jī)制。我的做法是每次寫操作失敗后重試最多3次每次重試之間加1ms延時(shí)。如果3次都失敗就執(zhí)行一次總線恢復(fù)流程——發(fā)送9個(gè)時(shí)鐘脈沖然后發(fā)送停止位強(qiáng)制釋放總線。這個(gè)恢復(fù)流程可以解決大部分因?yàn)閺臋C(jī)狀態(tài)機(jī)卡死導(dǎo)致的通信故障。如果總線恢復(fù)后仍然失敗那就需要檢查硬件了上拉電阻是否焊接、電源是否正常、PCA9422是否處于復(fù)位狀態(tài)。在軟件里可以設(shè)置一個(gè)錯(cuò)誤計(jì)數(shù)器連續(xù)失敗超過閾值就點(diǎn)亮一個(gè)錯(cuò)誤指示燈或者記錄到EEPROM里方便現(xiàn)場(chǎng)排查。4. 核心配置PCA9422各路輸出、上電時(shí)序與充電參數(shù)的設(shè)定邏輯4.1 輸出電壓的設(shè)定與分壓電阻計(jì)算PCA9422的每路輸出Buck和LDO都有對(duì)應(yīng)的電壓設(shè)置寄存器。以Buck輸出為例輸出電壓通常由內(nèi)部反饋網(wǎng)絡(luò)和外部電阻分壓共同決定或者通過寄存器直接選擇預(yù)設(shè)電壓檔位。具體要看PCA9422的型號(hào)版本。如果是寄存器直接設(shè)定那只需要算出目標(biāo)電壓對(duì)應(yīng)的寄存器值寫入即可。如果是外部電阻分壓那公式一般是Vout Vref * (1 R1/R2)其中Vref是內(nèi)部參考電壓通常是0.6V或0.8V。我建議在原理圖設(shè)計(jì)階段就把每路輸出的電壓確定下來然后算出分壓電阻的值盡量選用標(biāo)準(zhǔn)阻值。如果PCA9422支持寄存器微調(diào)那可以在標(biāo)準(zhǔn)阻值的基礎(chǔ)上做小范圍調(diào)整這樣既保證了精度又保留了靈活性。實(shí)際調(diào)試時(shí)用萬用表測(cè)量每路輸出確認(rèn)和設(shè)計(jì)值一致偏差超過3%就要檢查分壓電阻的精度或者反饋?zhàn)呔€是否受到干擾。4.2 上電時(shí)序的寄存器配置與驗(yàn)證方法上電時(shí)序是這套方案里最核心也最容易出問題的部分。PCA9422通常支持通過寄存器配置每路輸出的上電延時(shí)和上電順序。比如先讓3.3V的MCU供電輸出延時(shí)10ms后讓2.8V的傳感器供電輸出再延時(shí)5ms讓5V的顯示屏供電輸出。這些延時(shí)值通過寄存器設(shè)定單位通常是毫秒或者時(shí)鐘周期數(shù)。配置的邏輯是先確定系統(tǒng)里各個(gè)外設(shè)對(duì)上電順序的要求。一般來說MCU要先上電因?yàn)樗强刂坪诵娜缓笫峭ㄐ拍K最后是大功率外設(shè)比如顯示屏背光。每路之間的延時(shí)不能太短要給前一路的輸出電容充電留足時(shí)間否則前一路還沒穩(wěn)定后一路就啟動(dòng)可能導(dǎo)致輸入電壓跌落觸發(fā)欠壓保護(hù)。驗(yàn)證上電時(shí)序的方法很簡(jiǎn)單用示波器同時(shí)抓多路輸出的電壓波形看它們的上升沿是否按照設(shè)定的順序和延時(shí)出現(xiàn)。如果順序不對(duì)檢查寄存器配置如果延時(shí)不對(duì)檢查延時(shí)值的計(jì)算是否正確。我一般會(huì)在調(diào)試階段把示波器的觸發(fā)設(shè)在第一路輸出的上升沿然后依次觀察后續(xù)各路。4.3 電池充電參數(shù)的設(shè)定與溫度補(bǔ)償如果系統(tǒng)使用鋰電池供電PCA9422的充電管理功能就派上用場(chǎng)了。充電參數(shù)包括充電電流、充電截止電壓、涓流充電閾值、充電超時(shí)時(shí)間等。充電電流的設(shè)定要根據(jù)電池容量來一般取0.5C到1C比如2000mAh的電池充電電流設(shè)在1A到2A之間。截止電壓通常是4.2V但有些高壓電池是4.35V或4.4V這個(gè)必須和電池規(guī)格書一致設(shè)錯(cuò)了可能充不滿或者過充。溫度補(bǔ)償是充電管理里容易被忽略的部分。鋰電池在低溫下充電會(huì)加速老化高溫下充電有安全風(fēng)險(xiǎn)。PCA9422通常支持外接熱敏電阻根據(jù)溫度調(diào)整充電電流或者暫停充電。熱敏電阻的選型要和PCA9422的推薦值匹配一般是10kΩ的NTC。在軟件里可以通過讀取PCA9422的溫度狀態(tài)寄存器判斷當(dāng)前是否在允許充電的溫度范圍內(nèi)。4.4 低功耗模式下的電源域管理很多便攜設(shè)備需要低功耗模式比如待機(jī)時(shí)關(guān)閉傳感器和顯示屏的供電只保留MCU和實(shí)時(shí)時(shí)鐘的供電。PCA9422支持通過I2C命令單獨(dú)關(guān)閉某路輸出或者進(jìn)入全局低功耗模式。PIC18F45K80在進(jìn)入低功耗之前先通過I2C告訴PCA9422關(guān)閉不需要的電壓域然后自己進(jìn)入Sleep模式。喚醒時(shí)PCA9422的中斷引腳會(huì)拉低觸發(fā)PIC18F45K80的外部中斷MCU喚醒后重新配置PCA9422恢復(fù)各路輸出。這里有個(gè)順序問題關(guān)閉電壓域時(shí)要先關(guān)大功率外設(shè)再關(guān)小功率外設(shè)最后關(guān)MCU自己的供電域如果MCU由PCA9422供電的話。喚醒時(shí)順序相反。這個(gè)順序如果搞反了可能出現(xiàn)外設(shè)還沒關(guān)完MCU就斷電了導(dǎo)致外設(shè)處于不確定狀態(tài)。我在實(shí)際項(xiàng)目中就遇到過因?yàn)殛P(guān)閉順序不對(duì)導(dǎo)致傳感器在下次上電時(shí)無法初始化的問題后來調(diào)整了關(guān)閉順序才解決。5. 調(diào)試實(shí)錄I2C通信失敗、上電時(shí)序錯(cuò)亂與充電異常的排查過程5.1 I2C完全無應(yīng)答從硬件到軟件的逐層排查第一次把板子焊好上電PIC18F45K80跑起來后I2C通信完全沒反應(yīng)PCA9422沒有任何應(yīng)答。排查過程是這樣的先用示波器看SCL和SDA波形發(fā)現(xiàn)SCL有正常的時(shí)鐘脈沖但SDA一直高電平?jīng)]有起始位后的地址數(shù)據(jù)。這說明PIC18F45K80在發(fā)送起始位后SDA沒有被拉低問題出在MCU側(cè)。檢查PIC18F45K80的配置發(fā)現(xiàn)TRISB的SDA和SCL位沒有正確設(shè)置為輸入。在I2C主模式下SDA和SCL的方向由MSSP模塊自動(dòng)控制但TRIS位必須設(shè)置為1輸入否則模塊無法控制引腳。改過來之后SDA有了數(shù)據(jù)波形但PCA9422仍然不應(yīng)答。接著檢查PCA9422的供電和使能引腳。發(fā)現(xiàn)PCA9422的EN引腳沒有拉高芯片處于關(guān)斷狀態(tài)。把EN引腳接到PIC18F45K80的一個(gè)GPIO上軟件里先拉高EN延時(shí)10ms再開始I2C通信問題解決。這個(gè)經(jīng)歷告訴我PMIC的使能引腳一定要在軟件初始化流程里明確控制不能靠硬件默認(rèn)上拉。5.2 上電時(shí)序錯(cuò)亂寄存器配置值與實(shí)際波形不符I2C通信正常后開始配置上電時(shí)序。按照設(shè)計(jì)應(yīng)該是3.3V先出延時(shí)20ms后2.8V出再延時(shí)10ms后5V出。但示波器抓到的波形是三路幾乎同時(shí)上升延時(shí)幾乎為零。檢查寄存器配置發(fā)現(xiàn)延時(shí)值寫入了但讀回來是0。懷疑是寫入的寄存器地址不對(duì)查數(shù)據(jù)手冊(cè)發(fā)現(xiàn)延時(shí)寄存器是16位的分兩個(gè)8位寄存器存儲(chǔ)我只寫了低8位高8位沒寫導(dǎo)致實(shí)際延時(shí)值被截?cái)?。把?位也寫入后重新測(cè)試延時(shí)出現(xiàn)了但順序不對(duì)——5V先出了。檢查順序控制寄存器發(fā)現(xiàn)順序配置的位域理解錯(cuò)了把順序編號(hào)搞反了。PCA9422的順序寄存器里值越小優(yōu)先級(jí)越高我誤以為值越大越先出。改正后三路輸出的順序和延時(shí)都符合設(shè)計(jì)預(yù)期。5.3 充電電流偏小檢流電阻與寄存器值的匹配問題電池充電功能調(diào)試時(shí)發(fā)現(xiàn)實(shí)際充電電流只有設(shè)定值的一半。用電流表測(cè)量充電回路確認(rèn)電流確實(shí)偏小。檢查檢流電阻的阻值發(fā)現(xiàn)原理圖上標(biāo)的是0.1Ω但實(shí)際焊接的是0.05Ω。PCA9422的充電電流計(jì)算公式里檢流電阻的阻值是分母電阻減半電流應(yīng)該翻倍才對(duì)但實(shí)際電流反而小了說明問題不在檢流電阻。繼續(xù)查寄存器發(fā)現(xiàn)充電電流設(shè)置寄存器的值寫錯(cuò)了。PCA9422的充電電流寄存器不是直接寫電流值而是寫一個(gè)比例系數(shù)實(shí)際電流 系數(shù) × 基準(zhǔn)電流?;鶞?zhǔn)電流由檢流電阻決定。我把系數(shù)算錯(cuò)了導(dǎo)致實(shí)際電流偏小。重新計(jì)算系數(shù)并寫入后充電電流恢復(fù)正常。這個(gè)案例說明PMIC的寄存器往往不是直觀的物理量一定要仔細(xì)看數(shù)據(jù)手冊(cè)的計(jì)算公式。5.4 低功耗喚醒后外設(shè)不工作電源域恢復(fù)順序的坑低功耗模式調(diào)試時(shí)進(jìn)入Sleep后喚醒發(fā)現(xiàn)傳感器不工作了。測(cè)量傳感器的供電發(fā)現(xiàn)電壓只有0.5V明顯不對(duì)。檢查PCA9422的寄存器發(fā)現(xiàn)傳感器那路輸出的使能位沒有被重新置1。原因是喚醒后的初始化流程里我只恢復(fù)了MCU自己的供電域忘了恢復(fù)傳感器供電域。更隱蔽的問題是即使使能位重新置1傳感器供電電壓上升很慢因?yàn)檩敵鲭娙菰诘凸钠陂g沒有完全放電重新上電時(shí)充電電流被限流了。解決辦法是在關(guān)閉電壓域時(shí)把輸出電容主動(dòng)放電PCA9422通常支持快速放電功能或者在喚醒后加一個(gè)更長(zhǎng)的延時(shí)等電壓穩(wěn)定后再初始化傳感器。我選擇了前者在關(guān)閉時(shí)使能快速放電喚醒后延時(shí)5ms再初始化傳感器問題徹底解決。6. 從能跑到跑得穩(wěn)這套電源管理方案的優(yōu)化經(jīng)驗(yàn)與擴(kuò)展思路6.1 寄存器配置的版本管理與回滾機(jī)制PCA9422的寄存器數(shù)量不少調(diào)試過程中會(huì)反復(fù)修改配置值。如果沒有版本管理很容易出現(xiàn)“改好了A弄壞了B”的情況。我的做法是把所有寄存器配置整理成一個(gè)結(jié)構(gòu)體數(shù)組每個(gè)元素包含寄存器地址、值、掩碼和注釋。初始化時(shí)遍歷這個(gè)數(shù)組依次寫入。這樣配置一目了然也方便對(duì)比不同版本的差異。更進(jìn)一步我會(huì)在EEPROM里保存一份“已知良好”的配置備份。如果現(xiàn)場(chǎng)設(shè)備出現(xiàn)電源異常可以通過某個(gè)GPIO組合或者通信命令觸發(fā)恢復(fù)流程從EEPROM重新加載配置。這個(gè)機(jī)制在批量生產(chǎn)中特別有用萬一某臺(tái)設(shè)備的PCA9422配置被意外修改可以快速恢復(fù)。6.2 用狀態(tài)機(jī)管理電源模式切換電源管理不是簡(jiǎn)單的“初始化一次就完事”系統(tǒng)運(yùn)行過程中可能需要多次切換電源模式。比如從正常工作模式切到低功耗模式再切到充電模式再切回來。如果這些切換邏輯散落在各個(gè)函數(shù)里很容易出現(xiàn)狀態(tài)不一致。我建議用一個(gè)狀態(tài)機(jī)來管理電源模式每個(gè)狀態(tài)定義好進(jìn)入和退出時(shí)的PCA9422配置操作狀態(tài)之間的遷移條件明確。這樣代碼結(jié)構(gòu)清晰調(diào)試時(shí)也容易追蹤當(dāng)前處于哪個(gè)狀態(tài)。狀態(tài)機(jī)的實(shí)現(xiàn)可以用簡(jiǎn)單的switch-case也可以用函數(shù)指針數(shù)組。對(duì)于PIC18F45K80這種資源有限的MCUswitch-case更省空間。狀態(tài)遷移時(shí)先執(zhí)行當(dāng)前狀態(tài)的退出操作比如關(guān)閉某些電壓域再執(zhí)行目標(biāo)狀態(tài)的進(jìn)入操作比如使能某些電壓域并設(shè)置輸出電壓中間加適當(dāng)?shù)难訒r(shí)。6.3 電源異常的事件記錄與上報(bào)在實(shí)際部署中電源異常往往不是持續(xù)性的而是偶發(fā)的。比如輸入電壓瞬間跌落導(dǎo)致某路輸出重啟如果沒記錄下來事后很難排查。PCA9422通常有狀態(tài)寄存器可以讀取異常事件標(biāo)志比如過壓、欠壓、過溫、短路等。PIC18F45K80可以定期讀取這些標(biāo)志一旦發(fā)現(xiàn)異常把事件類型和時(shí)間戳記錄到EEPROM里。如果系統(tǒng)有通信接口還可以把異常事件上報(bào)給上位機(jī)。記錄的內(nèi)容不需要很復(fù)雜一個(gè)字節(jié)的事件類型加一個(gè)兩字節(jié)的時(shí)間戳就夠了。時(shí)間戳可以用PIC18F45K80的定時(shí)器計(jì)數(shù)或者外接RTC芯片。關(guān)鍵是事件記錄要有循環(huán)覆蓋機(jī)制避免EEPROM寫滿。我一般會(huì)分配一個(gè)固定大小的區(qū)域用環(huán)形緩沖區(qū)的方式寫入這樣既能保留最近的事件又不會(huì)耗盡EEPROM壽命。6.4 這套方案的適用邊界與替代思路PCA9422加PIC18F45K80這套方案適合的是中等復(fù)雜度、對(duì)成本敏感、不需要操作系統(tǒng)、電源路數(shù)在4到6路之間的嵌入式設(shè)備。如果電源路數(shù)更多比如10路以上PCA9422可能不夠用需要考慮更大規(guī)模的PMIC或者多顆PMIC級(jí)聯(lián)。如果系統(tǒng)需要復(fù)雜的電源管理策略比如動(dòng)態(tài)電壓頻率調(diào)節(jié)DVFS那可能需要更高級(jí)的MCU或者帶電源管理協(xié)處理器的方案。另外如果系統(tǒng)對(duì)電源效率要求極高比如電池供電的便攜設(shè)備要求待機(jī)電流在微安級(jí)別那要仔細(xì)評(píng)估PCA9422在低功耗模式下的靜態(tài)電流以及PIC18F45K80在Sleep模式下的功耗。兩者加起來如果超過系統(tǒng)預(yù)算可能需要換用更低功耗的MCU或者更專業(yè)的低功耗PMIC。我個(gè)人在實(shí)際操作中的體會(huì)是這套方案最大的價(jià)值在于“可控性”——每一路電壓、每一個(gè)延時(shí)、每一個(gè)充電參數(shù)都在軟件掌控之中調(diào)試時(shí)可以用示波器和I2C分析儀把整個(gè)上電過程看得清清楚楚。這種透明性在排查電源相關(guān)問題時(shí)非常寶貴。當(dāng)然前提是你愿意花時(shí)間把數(shù)據(jù)手冊(cè)讀透把寄存器配置邏輯理清楚。一旦跑通后續(xù)的維護(hù)和擴(kuò)展都會(huì)很順手。