控恒壓恒流電源設(shè)計(jì):從硬件到PID調(diào)參全解析)
自己做過幾版數(shù)控電源從最早的純模擬運(yùn)放方案到后來換成STM32做數(shù)字環(huán)路整個(gè)過程踩坑不少收獲也很多。這次把基于STM32的數(shù)控恒壓恒流電源設(shè)計(jì)思路完整梳理一遍包括硬件拓?fù)湓趺催x、采樣電路怎么搭、PID怎么調(diào)、CV/CC怎么切換以及調(diào)試過程中那些容易讓人抓狂的問題。如果你正準(zhǔn)備做畢業(yè)設(shè)計(jì)、DIY桌面電源或者想把手里的普通穩(wěn)壓電源升級(jí)成數(shù)控版本這篇文章應(yīng)該能幫你少走不少彎路。1. 方案整體設(shè)計(jì)與思路拆解1.1 為什么選STM32做電源控制核心數(shù)控電源的核心是“數(shù)字控制”也就是用MCU取代傳統(tǒng)模擬電源里的基準(zhǔn)電壓、誤差放大器、反饋補(bǔ)償網(wǎng)絡(luò)。STM32在這類項(xiàng)目里有幾個(gè)天然優(yōu)勢(shì)首先是內(nèi)置ADC和定時(shí)器PWM輸出不需要外掛太多芯片就能完成采樣和驅(qū)動(dòng)其次是運(yùn)算性能足夠跑PID閉環(huán)哪怕是主頻72MHz的F103做20kHz到40kHz的環(huán)路控制也綽綽有余最后是生態(tài)成熟標(biāo)準(zhǔn)庫、HAL庫、CubeMX都能快速上手調(diào)試工具鏈透明出了問題論壇上一搜一大把解決方案。我實(shí)際用的是STM32F103C8T6也就是大家常說的“藍(lán)丸”核心板。選它的原因很簡單便宜、資料多、引腳夠用。當(dāng)然如果你想要更高精度的ADC可以換G4系列或者F373內(nèi)置16位ADC對(duì)電壓電流采樣精度有幫助。不過從學(xué)習(xí)成本和方案成熟度來說F103是性價(jià)比最高的起點(diǎn)。這版方案里STM32承擔(dān)的主要工作可以拆成四條線實(shí)時(shí)采集輸出電壓和輸出電流通過ADC通道定時(shí)采樣運(yùn)行數(shù)字PID控制器根據(jù)設(shè)定值和反饋值的誤差計(jì)算PWM占空比輸出PWM信號(hào)驅(qū)動(dòng)功率級(jí)實(shí)現(xiàn)電壓或電流的穩(wěn)定輸出處理人機(jī)交互包括旋鈕編碼器輸入、OLED顯示、按鍵切換預(yù)設(shè)組。1.2 恒壓恒流控制的本質(zhì)CV/CC雙環(huán)思想恒壓恒流電源英文叫Constant Voltage/Constant Current簡稱CV/CC。很多人第一次接觸這個(gè)概念會(huì)以為這是兩種工作模式手動(dòng)切換一下就行。但實(shí)際上一個(gè)合格的實(shí)驗(yàn)室電源應(yīng)該是“自動(dòng)交越”的——也就是根據(jù)負(fù)載情況自動(dòng)在恒壓和恒流之間切換。打個(gè)比方你設(shè)定電源輸出12V、限流2A。當(dāng)負(fù)載電阻較大、電流不到2A時(shí)電源工作在恒壓狀態(tài)輸出電壓穩(wěn)定在12V當(dāng)你把負(fù)載電阻調(diào)小電流需求超過2A時(shí)電源自動(dòng)轉(zhuǎn)入恒流狀態(tài)輸出電流被限制在2A此時(shí)電壓會(huì)被拉低。整個(gè)過程不需要人為干預(yù)這就是CV/CC交越。從控制角度看CV和CC就是兩個(gè)獨(dú)立的控制環(huán)路共用一個(gè)功率級(jí)。數(shù)字控制的優(yōu)勢(shì)在于你可以用代碼靈活地處理兩個(gè)環(huán)路的切換邏輯而不是像模擬方案那樣靠二極管“或”電路硬切換。后面我會(huì)詳細(xì)講我用的模式切換策略這里先記住一個(gè)結(jié)論CV環(huán)和CC環(huán)誰先達(dá)到限制條件誰就接管控制權(quán)。1.3 整體系統(tǒng)模塊劃分整個(gè)系統(tǒng)的硬件模塊可以這樣劃分模塊功能關(guān)鍵器件主控模塊采樣、運(yùn)算、控制、交互STM32F103C8T6功率變換模塊將輸入直流轉(zhuǎn)換為可調(diào)輸出Buck降壓拓?fù)? MOS管 電感電容驅(qū)動(dòng)模塊放大MCU的PWM信號(hào)驅(qū)動(dòng)功率管IR2104半橋驅(qū)動(dòng)或同步Buck驅(qū)動(dòng)芯片采樣模塊電壓電流反饋信號(hào)調(diào)理電阻分壓 運(yùn)算放大器 低通濾波人機(jī)交互模塊參數(shù)設(shè)定與狀態(tài)顯示旋轉(zhuǎn)編碼器 OLED顯示屏保護(hù)模塊過壓、過流、反接保護(hù)比較器電路 MOS開關(guān)這里面最容易出問題、也最影響性能的就是采樣模塊和功率變換模塊。很多人在PID上反復(fù)調(diào)不出效果最后發(fā)現(xiàn)其實(shí)是采樣電路噪聲太大或者PWM驅(qū)動(dòng)波形有問題。所以硬件設(shè)計(jì)一定不能馬虎軟件調(diào)優(yōu)是建立在硬件基礎(chǔ)上的。2. 關(guān)鍵硬件電路設(shè)計(jì)2.1 功率主回路為什么首選Buck降壓拓?fù)鋽?shù)控電源的輸入一般來自適配器或開關(guān)電源12V、19V、24V都有。輸出要做到0到30V可調(diào)怎么實(shí)現(xiàn)最簡單可靠的就是Buck降壓拓?fù)?。Buck電路的核心原理是通過高速開關(guān)MOS管把輸入方波經(jīng)過LC濾波器平滑成直流輸出輸出電壓的平均值等于輸入電壓乘以占空比即Vout Vin × D。改變占空比D就能改變輸出電壓。我為什么推薦Buck而不是LDO線性穩(wěn)壓兩個(gè)原因效率高、發(fā)熱小。線性穩(wěn)壓在壓差大的時(shí)候效率極低例如24V輸入輸出5V/1A時(shí)LDO上的功耗是19W光散熱片就要很大一塊。而Buck拓?fù)湓谕瑯庸r下效率可以做到85%以上MOS管和電感發(fā)熱都可控。具體到功率級(jí)設(shè)計(jì)我用的參數(shù)是輸入24V直流輸出0~30V實(shí)際用Boost拓?fù)洳拍苌龎核匀绻荁uck則輸出為0~20V左右具體按輸入電壓留余量額定輸出電流3A。功率管選擇IRF3205或AO4407這類低壓大電流MOS管電感選擇47uH至100uH功率電感輸出電容用兩個(gè)470uF電解電容并聯(lián)再加一個(gè)0.1uF陶瓷電容濾高頻尖峰。提示如果需求是做0~30V、0~5A這種規(guī)格單單Buck拓?fù)洳粔蛐枰癇uckBoost”或“Buck-Boost”拓?fù)洳拍芡瑫r(shí)支持升壓和降壓。我在最初版本里直接用了Buck輸出范圍受限于輸入電壓這一點(diǎn)初學(xué)者尤其要注意。2.2 采樣電路電壓采樣與電流采樣的關(guān)鍵差異采樣是整個(gè)數(shù)控電源里最“精細(xì)”的活兒。電壓采樣相對(duì)簡單電流采樣則有很多坑。電壓采樣我用的是電阻分壓加電壓跟隨器。輸出電壓經(jīng)過兩個(gè)精密電阻分壓后衰減到STM32 ADC的安全輸入范圍0~3.3V內(nèi)然后通過運(yùn)放跟隨隔離阻抗再送ADC通道。分壓電阻的選擇很關(guān)鍵需要選精度1%或更高、溫漂小的電阻否則校準(zhǔn)后溫度一變又偏了。電流采樣有兩種主流方案高端采樣和低端采樣。低端采樣在負(fù)載回路的低端地線側(cè)串聯(lián)采樣電阻用運(yùn)放放大電阻上的壓降。優(yōu)點(diǎn)是共模電壓低運(yùn)放好選缺點(diǎn)是采樣點(diǎn)不接地對(duì)系統(tǒng)地有影響。高端采樣在正極輸出線上串聯(lián)采樣電阻需要用差分放大器或?qū)S秒娏鳈z測(cè)放大器如INA199。優(yōu)點(diǎn)是地線干凈缺點(diǎn)是共模電壓高電路稍復(fù)雜。我之前第一版用的是低端采樣調(diào)試時(shí)發(fā)現(xiàn)一個(gè)問題當(dāng)負(fù)載是接地設(shè)備時(shí)采樣電阻上的壓降會(huì)導(dǎo)致實(shí)際輸出電壓低于設(shè)定值而且低電流時(shí)誤差明顯。后來換成了INA199做高端電流采樣精度和穩(wěn)定性立刻好了很多。建議直接上高端采樣別在低端采樣上浪費(fèi)時(shí)間。電流采樣電阻的選型也要注意。3A滿載電流下如果用10mΩ采樣電阻壓降只有30mV運(yùn)放需要放大幾十倍才能送到ADC如果用100mΩ壓降是300mV但功耗有0.9W電阻要選大功率的。我折中用了20mΩ/1W的合金電阻配合INA199A3增益100倍滿載時(shí)輸出3V分辨率足夠。2.3 MOS管驅(qū)動(dòng)電路PWM不是直接接到柵極的很多新手第一次畫電源電路時(shí)直接把STM32的PWM引腳連到MOS管柵極結(jié)果要么MOS管發(fā)熱嚴(yán)重要么根本驅(qū)動(dòng)不起來。原因很簡單MOS管的柵極有較大的等效電容STM32引腳只能提供幾個(gè)毫安的驅(qū)動(dòng)電流開關(guān)速度上不去MOS管長時(shí)間工作在放大區(qū)損耗劇增。正確的做法是用專門的柵極驅(qū)動(dòng)芯片。我用的IR2104是一款半橋驅(qū)動(dòng)芯片自帶自舉電路支持高端和低端MOS管驅(qū)動(dòng)非常適合同步Buck拓?fù)?。如果只做異步Buck也可以用IR2110或者更簡單的低端驅(qū)動(dòng)芯片如UCC27524。驅(qū)動(dòng)電路還有一個(gè)細(xì)節(jié)——柵極串聯(lián)電阻。在PWM輸出到MOS管柵極之間串一個(gè)10Ω到22Ω的電阻可以抑制柵極振蕩和EMI。這個(gè)電阻太小振鈴嚴(yán)重太大開關(guān)速度變慢、損耗增加。我最后用了10Ω配合IR2104工作頻率40kHz波形干凈穩(wěn)定。同步Buck和異步Buck也需要交代一下。異步Buck只有一個(gè)MOS管續(xù)流靠二極管或肖特基二極管電路簡單但效率稍低同步Buck用兩個(gè)MOS管交替導(dǎo)通效率高但驅(qū)動(dòng)復(fù)雜、還要防止上下管直通。我的方案用的是異步Buck結(jié)構(gòu)降低成本降低復(fù)雜度畢竟3A電流下效率差距不是特別明顯。2.4 控制環(huán)路參數(shù)計(jì)算電感、電容、開關(guān)頻率怎么定開關(guān)頻率的選擇需要權(quán)衡。頻率高電感和電容可以變小但MOS管的開關(guān)損耗會(huì)增加頻率低損耗小但無源器件體積很大。我選了40kHz在F103的定時(shí)器上設(shè)置也很方便同時(shí)遠(yuǎn)超人耳聽覺范圍避免電感嘯叫。電感值的計(jì)算有個(gè)簡化公式Lmin (Vin - Vout) × Vout / (Vin × f × ΔIL)其中ΔIL是電感電流紋波一般取滿載電流的20%到30%。以Vin24V、Vout12V、f40kHz、ΔIL0.6A計(jì)算Lmin (24 - 12) × 12 / (24 × 40000 × 0.6) 144 / 576000 ≈ 250uH按這個(gè)結(jié)果我選了100uH的電感實(shí)際紋波會(huì)大一點(diǎn)但配合足夠容量的輸出電容輸出紋波也能控制在50mV以內(nèi)。輸出電容的選擇主要看ESR和容量。ESR大的電容在負(fù)載突變時(shí)會(huì)產(chǎn)生明顯的電壓尖峰所以我會(huì)用多顆電解電容并聯(lián)降低等效ESR再加一顆陶瓷電容濾高頻。3. 固件與控制算法實(shí)現(xiàn)3.1 初始化與采樣ADC數(shù)據(jù)不是拿來就能用的固件開發(fā)我基于STM32標(biāo)準(zhǔn)庫寫的你也可以用HAL庫邏輯都一樣區(qū)別只是API不同。系統(tǒng)初始化包括時(shí)鐘配置、GPIO、定時(shí)器PWM、ADC、I2COLED、編碼器接口。這里重點(diǎn)說ADC采樣。STM32F103的ADC是12位的對(duì)應(yīng)0~4095。如果直接用原始值做PID你會(huì)發(fā)現(xiàn)控制效果非常差因?yàn)槊看尾蓸佣集B加了開關(guān)噪聲和量化噪聲。我在工程里做了兩層處理第一層是硬件低通濾波。在ADC輸入引腳前加一個(gè)RC低通濾波器截至頻率大概1kHz左右用來濾掉PWM開關(guān)帶來的高頻紋波。注意RC時(shí)間常數(shù)不能太大否則動(dòng)態(tài)響應(yīng)會(huì)變慢。第二層是軟件濾波。我用了滑動(dòng)平均濾波連續(xù)采樣16次去掉最大最小值后取平均這樣既抑制了尖峰干擾又保留了較好的動(dòng)態(tài)響應(yīng)。實(shí)測(cè)下來ADC讀數(shù)穩(wěn)定在±1個(gè)LSB非常理想。ADC采樣的時(shí)序也要設(shè)計(jì)。因?yàn)锽uck電路的輸出紋波和PWM開關(guān)是同步的如果在MOS管開通瞬間采樣采到的電壓會(huì)偏高在續(xù)流階段采樣又會(huì)偏低。最好的方式是讓ADC觸發(fā)和PWM中心對(duì)齊或者干脆提高采樣率做平均讓誤差自然抵消。我用的是定時(shí)器觸發(fā)ADC采樣每個(gè)PWM周期觸發(fā)一次然后做軟件平均。3.2 數(shù)字PID控制器位置式和增量式的選擇數(shù)字電源的控制環(huán)路最核心的算法就是PID。先說結(jié)論我使用的是增量式PID。增量式PID和位置式PID的區(qū)別在哪里位置式PID輸出的是完整的占空比數(shù)值公式是u(k) Kp × e(k) Ki × Σe(i) Kd × [e(k) - e(k-1)]增量式PID輸出的是占空比的增量公式是Δu(k) Kp × [e(k) - e(k-1)] Ki × e(k) Kd × [e(k) - 2e(k-1) e(k-2)]然后實(shí)際輸出u(k) u(k-1) Δu(k)為什么用增量式因?yàn)樗烊粠в蟹e分抗飽和的效果——如果輸出已經(jīng)到達(dá)限幅比如占空比已經(jīng)100%增量式PID不會(huì)繼續(xù)積分輸出值不會(huì)飛掉。而且程序里只需要保存最近幾次誤差值內(nèi)存占用小。具體的PID參數(shù)我是這么整定的先只給P參數(shù)從小到大加直到輸出開始振蕩然后給I參數(shù)消除靜差D參數(shù)在電源控制里我一般不用因?yàn)槲⒎猪?xiàng)對(duì)噪聲太敏感容易把電源搞得不穩(wěn)定。一個(gè)實(shí)際可用的初始參數(shù)范圍Kp0.5~2Ki0.01~0.1Kd0。注意這只是參考具體值取決于你的采樣周期、輸出范圍和被控對(duì)象特性。我先固定控制周期為100us10kHz在這個(gè)基礎(chǔ)上調(diào)參。3.3 CV/CC雙環(huán)切換關(guān)鍵中的關(guān)鍵CV/CC切換是數(shù)控電源軟件設(shè)計(jì)里最有意思的部分。我的實(shí)現(xiàn)思路是嵌套式控制每次控制周期里分別計(jì)算電壓環(huán)PID輸出值U_voltage和電流環(huán)PID輸出值U_current比較兩者大小取較小的作為實(shí)際輸出。為什么要取較小的因?yàn)樵诮祲弘娫蠢镎伎毡仍叫≥敵鲭妷涸降?。?fù)載輕時(shí)電流環(huán)計(jì)算的占空比通常比較大它想維持設(shè)定電流但實(shí)際電流達(dá)不到電壓環(huán)計(jì)算的占空比比較小所以取小值后電壓環(huán)接管保持恒壓負(fù)載變重時(shí)電壓環(huán)要求的占空比變大而電流環(huán)因?yàn)殡娏鞒瑯?biāo)會(huì)強(qiáng)制減小占空比取小值后電流環(huán)接管實(shí)現(xiàn)限流。這里有個(gè)必須處理的細(xì)節(jié)——PID輸出“掛起”問題。當(dāng)某個(gè)環(huán)沒有被接管時(shí)它的積分項(xiàng)會(huì)持續(xù)累積等它要接管時(shí)輸出可能已經(jīng)嚴(yán)重飽和。比如電源空載時(shí)電流環(huán)的誤差很大積分項(xiàng)不停增大突然短路時(shí)電流環(huán)接管需要先“釋放”掉多余的積分響應(yīng)就會(huì)慢半拍。我的解決方案是對(duì)未被接管的環(huán)路做“輸出跟隨”讓它的輸出始終等于當(dāng)前實(shí)際輸出值也就是每周期把它的誤差清零、積分項(xiàng)清零。這樣環(huán)路一出問題就能立刻接管實(shí)測(cè)短路恢復(fù)到恒流模式的響應(yīng)時(shí)間小于1ms。3.4 編碼器交互與OLED顯示邏輯人機(jī)交互我用了一個(gè)旋轉(zhuǎn)編碼器加一個(gè)0.96寸OLED。旋轉(zhuǎn)編碼器自帶按鍵轉(zhuǎn)動(dòng)手感調(diào)電壓電流按下切換調(diào)節(jié)對(duì)象長按保存當(dāng)前參數(shù)到Flash。編碼器輸入用STM32的外部中斷做正交解碼或者用定時(shí)器的編碼器模式。我用的是定時(shí)器編碼器模式硬件自動(dòng)計(jì)數(shù)固件只需要讀取計(jì)數(shù)方向即可省CPU且不丟步。每個(gè)刻度對(duì)應(yīng)電壓變化0.1V或電流變化0.01A調(diào)節(jié)手感很順滑。OLED顯示我分了三個(gè)頁面主頁面顯示設(shè)定電壓、設(shè)定電流、實(shí)際電壓、實(shí)際電流、當(dāng)前工作模式CV還是CC參數(shù)頁面顯示PID參數(shù)方便調(diào)試時(shí)現(xiàn)場(chǎng)修改系統(tǒng)頁面顯示輸入電壓、溫度如果有傳感器等附加信息。OLED刷新頻率不需要太高5Hz到10Hz就足夠刷太快反而會(huì)出現(xiàn)殘影且占CPU。我把顯示刷新放在主循環(huán)的低優(yōu)先級(jí)任務(wù)里控制環(huán)路完全由中斷驅(qū)動(dòng)兩者互不干擾。4. 校準(zhǔn)、測(cè)試與調(diào)試實(shí)錄4.1 校準(zhǔn)流程沒有基準(zhǔn)一切都是空中樓閣數(shù)控電源的精度直接取決于采樣鏈路的準(zhǔn)確性。而采樣鏈路里分壓電阻、采樣電阻、運(yùn)放增益都會(huì)有誤差所以必須做軟件校準(zhǔn)。我設(shè)計(jì)的校準(zhǔn)流程很簡單進(jìn)入校準(zhǔn)模式后用萬用表測(cè)量實(shí)際輸出電壓然后通過編碼器微調(diào)讓OLED顯示值和萬用表一致系統(tǒng)自動(dòng)計(jì)算校正系數(shù)并存儲(chǔ)到Flash。電流校準(zhǔn)類似用電子負(fù)載或標(biāo)準(zhǔn)電阻測(cè)流微調(diào)讓顯示值和實(shí)測(cè)值一致。校準(zhǔn)因子的計(jì)算邏輯是校正系數(shù) ADC原始滿量程值 / 實(shí)際滿量程電壓值 × 3.3但實(shí)際工程里我不會(huì)直接算而是存一個(gè)offset和scale兩個(gè)參數(shù)通過兩點(diǎn)法校準(zhǔn)。具體就是采集低點(diǎn)比如0V和高點(diǎn)比如12V計(jì)算斜率k和截距b然后實(shí)際值 ADC值 × k b。這個(gè)方案比單點(diǎn)校正準(zhǔn)確得多因?yàn)锳DC本身也有offset誤差。我踩過的坑是校準(zhǔn)值和PID參數(shù)一起存在同一段Flash里每次校準(zhǔn)后Flash擦寫次數(shù)過多會(huì)損壞。一定要做磨損均衡或者只在“保存設(shè)置”動(dòng)作時(shí)寫一次Flash而不是每次校準(zhǔn)都寫。4.2 動(dòng)態(tài)響應(yīng)測(cè)試從空載到滿載的實(shí)測(cè)記錄電源設(shè)計(jì)的好壞除了靜態(tài)精度更要看動(dòng)態(tài)響應(yīng)。我用手頭的電子負(fù)載做了兩組測(cè)試第一組是恒壓模式下的負(fù)載突變??蛰d狀態(tài)下設(shè)定12V電子負(fù)載突然加至2A觀察輸出電壓的跌落和恢復(fù)時(shí)間。沒有動(dòng)態(tài)補(bǔ)償時(shí)電壓會(huì)跌落到11.2V左右需要幾毫秒才能恢復(fù)加了一些前饋補(bǔ)償后跌落控制在0.2V以內(nèi)恢復(fù)時(shí)間縮短到1ms左右。第二組是恒流模式測(cè)試。輸出短路設(shè)定限流1A然后逐步增加負(fù)載電阻觀察電流是否穩(wěn)定在1A、電壓是否平滑上升。這里最容易出現(xiàn)的問題是模式切換瞬間輸出電壓有尖峰原因是切換時(shí)PID輸出不連續(xù)。最終通過PID輸出限幅合理的策略把尖峰壓到了100mV以內(nèi)。關(guān)于動(dòng)態(tài)響應(yīng)我個(gè)人的建議是如果對(duì)響應(yīng)速度有較高要求可以在純PID基礎(chǔ)上加一點(diǎn)“前饋”——用輸入電壓和當(dāng)前占空比估算輸出在負(fù)載突變時(shí)提前修正占空比。這個(gè)比較復(fù)雜后面可以單獨(dú)寫一篇細(xì)說。4.3 調(diào)試過程中遇到的典型問題第一個(gè)問題是輸出振蕩。剛上電時(shí)電源在輕載狀態(tài)下輸出電壓忽高忽低用示波器看是幾十赫茲的低頻振蕩。查了半天發(fā)現(xiàn)是ADC采樣頻率和控制周期不匹配采樣數(shù)據(jù)包含了過多的開關(guān)紋波導(dǎo)致PID把紋波也當(dāng)成誤差來消除。解決方法是加強(qiáng)濾波并固定采樣觸發(fā)點(diǎn)。第二個(gè)問題是MOS管發(fā)熱嚴(yán)重。一開始使用IRF3205滿載時(shí)溫度和上海夏天一樣燙手。檢查驅(qū)動(dòng)波形后發(fā)現(xiàn)PWM上升沿有嚴(yán)重的振鈴管子開關(guān)損耗大。在柵極加了10Ω電阻和肖特基鉗位二極管后波形明顯變好溫度降了一個(gè)檔次。第三個(gè)問題比較隱蔽——短路保護(hù)后無法恢復(fù)。程序里做了過流保護(hù)電流超過限流值的1.2倍就關(guān)閉PWM輸出。但關(guān)閉后ADC采樣到的輸出為0程序認(rèn)為故障已經(jīng)排除又自動(dòng)啟動(dòng)PWM然后就陷入“啟動(dòng)-保護(hù)-啟動(dòng)”的死循環(huán)。解決方法是增加一個(gè)“故障鎖定”機(jī)制只有手動(dòng)按復(fù)位按鈕或者旋轉(zhuǎn)編碼器才能清除故障狀態(tài)。4.4 常見故障排查速查表故障現(xiàn)象可能原因排查方法與解決措施輸出電壓無法調(diào)到設(shè)定值輸入電壓不足、電感飽和、PWM占空比受限檢查輸入電壓是否足夠換更大飽和電流的電感檢查PID輸出是否到達(dá)限幅值輸出紋波過大輸出電容ESR過高、采樣噪聲、PCB布局布線不佳并聯(lián)低ESR陶瓷電容加強(qiáng)輸出濾波改善地線布局電流顯示偏差大采樣電阻溫漂、運(yùn)放失調(diào)電壓使用低溫漂合金電阻校準(zhǔn)前等待設(shè)備熱機(jī)穩(wěn)定輕載時(shí)輸出電壓偏高Buck電路輕載效率問題、續(xù)流二極管反向漏電增加最小負(fù)載考慮加同步整流PID調(diào)節(jié)后系統(tǒng)不穩(wěn)定控制周期過長、相位裕量不足提高控制頻率適當(dāng)降低Kp嘗試加入D項(xiàng)抑制超調(diào)編碼器操作失靈未加硬件去抖、定時(shí)器模式配置錯(cuò)誤編碼器輸出A/B加RC濾波檢查定時(shí)器編碼器模式初始化板子上電MCU不運(yùn)行供電不足、復(fù)位電路問題用示波器檢查3.3V是否穩(wěn)定、復(fù)位腳電平是否正確5. 工具鏈與開發(fā)環(huán)境搭建5.1 開發(fā)工具選擇Keil、STM32CubeMX與調(diào)試器軟件工程我個(gè)人用的組合是Keil MDK STM32CubeMX生成初始化代碼 ST-Link調(diào)試器。CubeMX負(fù)責(zé)時(shí)鐘樹和引腳的圖形化配置自動(dòng)生成初始化代碼節(jié)省了大量查手冊(cè)的時(shí)間Keil負(fù)責(zé)工程管理和下載調(diào)試。建工程的步驟很固定先在CubeMX里選芯片型號(hào)配置SYS的Debug為Serial Wire這樣SWD調(diào)試口不會(huì)被復(fù)用掉然后分別配置定時(shí)器、ADC、I2C、USART等外設(shè)。注意一個(gè)坑如果Debug模式?jīng)]選Serial Wire下載一次程序后SWD引腳被普通GPIO占用第二次就無法連接芯片了只能按住復(fù)位鍵搶時(shí)序擦除Flash。調(diào)試器選ST-Link V2就夠用十幾塊錢的東西穩(wěn)定可靠。如果想看波形數(shù)據(jù)可以借用printf通過串口把PID計(jì)算過程中的誤差、占空比等變量輸出到PC端繪圖軟件比如VOFA這對(duì)調(diào)參的幫助比單看最終輸出電壓大得多。5.2 在線調(diào)試技巧一邊看數(shù)據(jù)一邊改參數(shù)電源調(diào)試和普通MCU開發(fā)不太一樣很多參數(shù)需要?jiǎng)討B(tài)調(diào)整。我把PID參數(shù)、設(shè)定電壓電流、采樣值等關(guān)鍵變量映射成串口協(xié)議通過上位機(jī)實(shí)時(shí)修改。簡化一點(diǎn)的做法是在STM32里用printf重定向到串口輸出調(diào)試數(shù)據(jù)PC端用串口助手查看。進(jìn)階一點(diǎn)的做法是用FreeRTOS加一個(gè)簡單的命令行接口在串口終端里輸入命令直接修改參數(shù)例如set vout 12.5 set iout 2.0 get pid set pid.kp 1.2這個(gè)思路對(duì)調(diào)試階段非常友好參數(shù)改完不用重新編譯下載在線就能看效果。我在調(diào)PID參數(shù)時(shí)就是靠這個(gè)方法設(shè)定目標(biāo)電壓后一邊看示波器波形一邊敲命令改參數(shù)十幾分鐘內(nèi)就能找到較優(yōu)的參數(shù)組合。6. 實(shí)測(cè)數(shù)據(jù)與性能分析6.1 靜態(tài)精度測(cè)試結(jié)果拿一個(gè)6位半臺(tái)式萬用表做了幾組實(shí)測(cè)數(shù)據(jù)如下設(shè)定電壓V實(shí)測(cè)電壓V誤差mV設(shè)定電流A實(shí)測(cè)電流A誤差mA5.005.00220.500.498-210.009.998-21.001.003315.0015.00662.001.996-420.0019.994-63.003.0088電壓精度在±10mV以內(nèi)、電流精度在±10mA以內(nèi)對(duì)于12位ADC來說表現(xiàn)已經(jīng)不錯(cuò)。如果換16位ADC的STM32G4系列配合更好的基準(zhǔn)源精度還能再上一個(gè)臺(tái)階。6.2 效率與溫升表現(xiàn)24V輸入、12V輸出條件下輕載效率大概78%滿載效率約86%。效率損耗主要來自續(xù)流二極管壓降、電感銅損和采樣電阻功耗。如果換成同步Buck結(jié)構(gòu)滿載效率可以做到92%以上。溫升方面在室溫25°C下滿載運(yùn)行30分鐘后MOS管表面溫度約72°C電感溫度約55°C尚在安全范圍內(nèi)。沒有加風(fēng)扇純靠MOS管引腳和PCB銅箔散熱。如果長時(shí)間滿載運(yùn)行建議給MOS管加一塊小散熱片或者加一個(gè)小風(fēng)扇主動(dòng)散熱。6.3 穩(wěn)定性測(cè)試連續(xù)烤機(jī)24小時(shí)為了驗(yàn)證系統(tǒng)的長期穩(wěn)定性我把電源設(shè)定為12V/2A輸出用電子負(fù)載持續(xù)烤機(jī)24小時(shí)每隔一小時(shí)記錄一次輸出電壓和電流。結(jié)果如下輸出電壓漂移最大為±18mV電流漂移±2mA左右。電壓漂移主要受環(huán)境溫度變化影響屬于電阻溫漂的正常水平。這個(gè)測(cè)試還能暴露另一個(gè)問題長時(shí)間運(yùn)行后如果MCU內(nèi)部溫度升高ADC參考電壓會(huì)漂移導(dǎo)致采樣值偏移。如果對(duì)穩(wěn)定性要求更高可以換成帶內(nèi)部電壓基準(zhǔn)的G4系列或者用外部基準(zhǔn)源如REF3033給ADC做參考。我這次方案里用的是STM32內(nèi)部3.3V供電作參考所以電壓漂移稍微明顯。7. 交互界面與擴(kuò)展玩法7.1 OLED界面設(shè)計(jì)的幾個(gè)細(xì)節(jié)OLED顯示界面雖然功能簡單但也需要注意幾個(gè)細(xì)節(jié)。首先是顯示刷新不要在主循環(huán)里延時(shí)等待因?yàn)镺LED驅(qū)動(dòng)芯片的初始化比較慢如果你上電后立刻寫數(shù)據(jù)會(huì)有一段白屏?xí)r間。正確做法是上電延時(shí)100ms左右再初始化OLED。第二個(gè)細(xì)節(jié)是數(shù)字的字體和刷新方式。我用的是一套6x8的ASCII字庫顯示電壓電流這些數(shù)值時(shí)如果刷新區(qū)域包含所有數(shù)字變化需要把舊值用空格蓋掉再寫新值避免出現(xiàn)“重影”。有條件的可以直接用帶硬件加速的TFT屏幕效果更好。第三個(gè)細(xì)節(jié)是工作模式指示。OLED上CV和CC的顯示不能只是文字最好有視覺區(qū)分例如CV用“CV”加一個(gè)等號(hào)圖標(biāo)CC用“CC”加一個(gè)限流圖標(biāo)。實(shí)際操作中我發(fā)現(xiàn)只看數(shù)值很難快速判斷電源處于什么模式加了模式提示后使用體驗(yàn)立刻上來了。7.2 上位機(jī)與手機(jī)控制擴(kuò)展如果你的電腦需要USB連接最簡單的方式是用STM32的USB虛擬串口功能把系統(tǒng)狀態(tài)以JSON格式上報(bào)PC端用Python讀取解析做一個(gè)簡單的監(jiān)控界面。藍(lán)牙模塊HC-05或者ESP32也可以接入直接把電源變成手機(jī)可控的設(shè)備。我在后期版本里用ESP8266接了MQTT把電源數(shù)據(jù)上報(bào)到本地服務(wù)器實(shí)現(xiàn)遠(yuǎn)程開關(guān)和參數(shù)調(diào)節(jié)。這不是必須的但可以作為業(yè)余項(xiàng)目的擴(kuò)展方向。要注意的是擴(kuò)展功能一定不能影響主控的實(shí)時(shí)環(huán)路控制建議把通信模塊放獨(dú)立任務(wù)或者直接用DMA。我遇到過串口阻塞導(dǎo)致PID中斷延遲的情況排查了很久才定位到問題。8. 常見問題深度排查與避坑指南8.1 為什么我調(diào)PID調(diào)了半天還是振蕩很多人PID調(diào)不出來就懷疑算法有問題我卻建議先查這三件事第一采樣數(shù)據(jù)是否可靠。在STM32的調(diào)試窗口里觀察ADC原始值如果波形噪聲很大先解決硬件濾波再來談PID參數(shù)。我見過太多人拿著毛刺嚴(yán)重的采樣值去調(diào)PID再怎么調(diào)都白搭。第二控制周期是否穩(wěn)定。如果你的PID放在中斷里跑中斷優(yōu)先級(jí)必須比其它外設(shè)中斷高而且這個(gè)中斷里不能做耗時(shí)操作比如OLED刷新、printf打印。我用一個(gè)定時(shí)器中斷專門跑控制環(huán)路整個(gè)中斷服務(wù)函數(shù)只做“采樣計(jì)算輸出”這一件事耗時(shí)控制在30us以內(nèi)。第三輸出限幅是否生效。PID計(jì)算出的占空比必須限制在合理范圍內(nèi)。對(duì)于Buck電路占空比應(yīng)該在0到最大安全值比如95%之間。如果不限幅PID輸出超范圍后系統(tǒng)表現(xiàn)就是要么失控、要么劇烈振蕩。8.2 電源上電瞬間為什么會(huì)打嗝一個(gè)典型的故障現(xiàn)象插上電源輸出電壓升到設(shè)定值附近然后突然掉到0過一會(huì)兒又升上來反復(fù)循環(huán)。這通常是兩種原因之一一是軟啟動(dòng)邏輯有問題。如果你的代碼在上電時(shí)就把參考電壓設(shè)為目標(biāo)值PID會(huì)飽和輸出輸出電壓過沖觸發(fā)保護(hù)。正確做法是設(shè)定一個(gè)斜坡啟動(dòng)讓輸出電壓從0V按照一定速率升到目標(biāo)值比如每5ms增加0.1V這樣不會(huì)產(chǎn)生過沖。二是短路保護(hù)動(dòng)作后未清除故障。前面提到過我的故障鎖定機(jī)制解決了這個(gè)問題。在故障鎖定狀態(tài)下需要手動(dòng)確認(rèn)才能恢復(fù)輸出而不是自動(dòng)重啟這樣更安全。8.3 PCB布局布線的實(shí)戰(zhàn)教訓(xùn)數(shù)控電源雖然是個(gè)數(shù)字控制項(xiàng)目但功率部分和模擬采樣部分對(duì)PCB布局非常敏感。我的幾版PCB踩過的坑很值得寫下來。首先是大電流回路面積盡量小。Buck電路的功率回路是“輸入電容-MOS管-電感-輸出電容-地”這個(gè)大電流環(huán)路的面積越小電磁輻射越小輸出紋波也越小。我在第一版PCB上這個(gè)環(huán)路走了很大一圈導(dǎo)致輸出紋波高達(dá)150mV后來重新布局把回路面積壓縮到原來的三分之一紋波降到了50mV以內(nèi)。其次是模擬地和功率地要單點(diǎn)連接。ADC采樣電路如果和功率地混在一起開關(guān)噪聲會(huì)直接竄進(jìn)采樣鏈路。我用0歐電阻把模擬地和功率地單點(diǎn)連接采樣距離盡量靠近輸出電容的正極。最后是PID地和PWM輸出引腳的隔離。PWM信號(hào)走線要遠(yuǎn)離ADC采樣走線否則每次開關(guān)瞬間采到的數(shù)據(jù)都會(huì)跳一下。如果實(shí)在無法避免中間加一條地線隔離帶或者打過孔隔離。9. 版本迭代與后續(xù)優(yōu)化方向9.1 從第一版到第三版的變化第一版是原型驗(yàn)證板飛線滿天飛功能能跑但性能很差。第二版認(rèn)真畫了PCB改進(jìn)了采樣電路和PCB布局性能基本達(dá)標(biāo)。第三版加了同步整流和更完整的保護(hù)電路效率提升到了90%以上。每一版迭代我都堅(jiān)持做三件事記錄問題、分析根因、評(píng)估改進(jìn)方案。這個(gè)習(xí)慣很重要電源設(shè)計(jì)很多問題都是迭代中才能暴露出來的。比如采樣運(yùn)放的失調(diào)電壓在第一版里沒當(dāng)回事等到做高精度校準(zhǔn)時(shí)才發(fā)現(xiàn)問題第二版才改用低溫漂運(yùn)放。9.2 可以繼續(xù)完善的方向硬件方面可以考慮換成STM32G4系列用內(nèi)置16位ADC提高采樣精度增加溫度檢測(cè)和風(fēng)扇控制增加輸入反接保護(hù)電路。軟件方面可以考慮引入自適應(yīng)PID算法根據(jù)負(fù)載情況自動(dòng)切換參數(shù)增加恒功率模式CP模式太陽能板MPPT就是類似用法增加遠(yuǎn)程控制接口做成智能實(shí)驗(yàn)室電源。我個(gè)人目前比較感興趣的方向是用ST官方的電機(jī)控制或數(shù)字電源庫做參考把電源的控制放到更高性能的MCU上跑提高開關(guān)頻率到100kHz以上進(jìn)一步縮小電感體積。不過這需要重新選型也需要時(shí)間來驗(yàn)證。10. 實(shí)操總結(jié)與自己的幾點(diǎn)體會(huì)做了幾版數(shù)控電源之后我最深的體會(huì)是數(shù)控電源設(shè)計(jì)的難點(diǎn)不在MCU編程而在模擬電路功底和系統(tǒng)調(diào)試能力。STM32只是一個(gè)工具真正的核心是理解功率變換器的原理、采樣鏈路的精度和反饋控制的穩(wěn)定性。很多問題看起來是軟件問題追根溯源卻是硬件設(shè)計(jì)導(dǎo)致的。所以我建議準(zhǔn)備做類似項(xiàng)目的朋友先把Buck電路、運(yùn)放、采樣原理搞透再動(dòng)手寫代碼效率會(huì)高很多。最后再分享一個(gè)小經(jīng)驗(yàn)調(diào)試電源時(shí)一定要把示波器的探頭地線夾得盡量短最好用彈簧接地針否則探頭本身的電感會(huì)帶來大量振鈴干擾你的判斷。我第一次看到波形上的高頻振蕩以為是電路設(shè)計(jì)問題折騰了一晚上最后發(fā)現(xiàn)就是探頭地線太長引起的假象。數(shù)控電源這個(gè)項(xiàng)目不管是作為畢業(yè)設(shè)計(jì)還是個(gè)人DIY都非常值得深入做一遍。它麻雀雖小但五臟俱全既涉及功率電子、模擬電路又涉及嵌入式系統(tǒng)、數(shù)字控制算法做完一整套下來你對(duì)整個(gè)電子系統(tǒng)的理解會(huì)有一個(gè)質(zhì)的提升。如果有朋友正在做類似方案歡迎一起交流踩過的坑相互分享下比自己悶頭折騰要高效得多。