輸出實(shí)戰(zhàn))
1. 小功率逆變器方案選型與整體設(shè)計(jì)思路1.1 為什么是STM32F103C8T6這顆芯片做小功率逆變器主控選型基本決定了整個方案的開發(fā)難度、成本上限和后期維護(hù)的便利性。市面上能跑SPWM的MCU不少從8位的STC到32位的GD32、STM32甚至一些專用逆變芯片都能做。但如果你要的是一個資料齊全、社區(qū)活躍、成本可控、性能夠用的方案STM32F103C8T6幾乎是繞不開的選擇。先看幾個硬指標(biāo)。STM32F103C8T6是ARM Cortex-M3內(nèi)核主頻72MHz64KB Flash20KB SRAM自帶3個通用定時器TIM2/3/4和1個高級定時器TIM1。做單相逆變器核心需求就是一路互補(bǔ)PWM帶死區(qū)TIM1的CH1/CH1N、CH2/CH2N、CH3/CH3N正好能輸出三對互補(bǔ)信號硬件上直接滿足H橋四管驅(qū)動加一路備用。死區(qū)時間可以通過BDTR寄存器配置不需要外部死區(qū)電路這一點(diǎn)比用普通定時器軟件模擬死區(qū)要可靠得多。再說成本。這顆芯片在市場上的價格已經(jīng)非常透明最小系統(tǒng)板幾塊錢就能拿到自己畫板的話芯片本體成本更低。對于小功率逆變器這種對成本敏感的產(chǎn)品主控省下來的錢可以加到功率管和磁性元件上整體性能反而更好。還有一個容易被忽略的點(diǎn)生態(tài)。STM32F103的標(biāo)準(zhǔn)庫和HAL庫資料鋪天蓋地從GPIO配置到定時器PWM輸出從ADC采樣到串口通信幾乎每一個外設(shè)都有現(xiàn)成的例程可以參考。做逆變器不是做科研能快速搭出原型、快速調(diào)試、快速迭代才是關(guān)鍵。我試過用某國產(chǎn)替代芯片做同樣的事光是定時器互補(bǔ)輸出這一塊就卡了兩天換回STM32半天就跑通了。1.2 單極性倍頻與雙極性調(diào)制的取舍SPWM調(diào)制方式直接決定了輸出波形的質(zhì)量和開關(guān)損耗。小功率逆變器常見的調(diào)制方式有兩種雙極性調(diào)制和單極性倍頻調(diào)制。雙極性調(diào)制最簡單H橋的對角管同時開關(guān)輸出只有正負(fù)兩種電平。優(yōu)點(diǎn)是控制邏輯簡單只需要一路正弦調(diào)制波和一路三角載波比較。缺點(diǎn)是開關(guān)損耗大因?yàn)槊總€開關(guān)周期內(nèi)四個管子都在動作而且輸出諧波主要集中在開關(guān)頻率附近濾波電感需要選得比較大。單極性倍頻調(diào)制則是把H橋分成兩個橋臂每個橋臂獨(dú)立控制。左橋臂用正弦波和三角波比較右橋臂用反相正弦波和同一個三角波比較。這樣輸出電平有正、負(fù)、零三種狀態(tài)等效開關(guān)頻率翻倍諧波頻率提高一倍濾波電感可以減小一半左右。代價是控制邏輯稍微復(fù)雜一點(diǎn)需要兩路互補(bǔ)的調(diào)制信號。對于小功率逆變器我傾向于單極性倍頻。原因很直接電感體積和成本在逆變器里占比不小能用控制換電感這筆賬劃算。而且STM32的TIM1有足夠的通道和互補(bǔ)輸出能力實(shí)現(xiàn)單極性倍頻并不增加硬件成本。具體實(shí)現(xiàn)上用TIM1的CH1/CH1N驅(qū)動左橋臂CH2/CH2N驅(qū)動右橋臂。CH3可以留著做保護(hù)或者風(fēng)扇控制。正弦調(diào)制波用查表法生成三角載波用定時器自動重裝載值模擬。查表點(diǎn)數(shù)選200點(diǎn)或者256點(diǎn)根據(jù)Flash空間和輸出頻率要求來定。1.3 后級H橋與濾波器的基本架構(gòu)小功率逆變器的后級拓?fù)浠竟潭ㄈ珮蚰孀? LC濾波。四個IGBT或者M(jìn)OSFET組成H橋把前級升壓后的直流電逆變成SPWM波再通過LC濾波器把高頻諧波濾掉得到50Hz正弦波。H橋的管子選擇要看功率等級。如果是幾百瓦的小功率MOSFET就夠用比如IRF540、IRF3205這類導(dǎo)通電阻小開關(guān)速度快。如果是上千瓦IGBT更合適飽和壓降固定大電流下?lián)p耗比MOSFET低。熱詞里提到“用四個IGBT做一個H橋逆變器后級”這個思路是對的IGBT在小功率下雖然開關(guān)損耗略高但勝在皮實(shí)耐造驅(qū)動也簡單。LC濾波器的參數(shù)計(jì)算是重點(diǎn)。截止頻率一般取開關(guān)頻率的1/10到1/20。假設(shè)開關(guān)頻率20kHz截止頻率取1kHz到2kHz。電感值根據(jù)紋波電流要求算電容值根據(jù)輸出電壓紋波要求算。具體公式后面實(shí)操部分會展開。驅(qū)動電路不能省。STM32的IO口輸出3.3V驅(qū)動電流只有幾十毫安直接推MOSFET柵極會燒IO口。必須加驅(qū)動芯片或者圖騰柱電路。IR2110、IR2104這類半橋驅(qū)動芯片是標(biāo)配自帶死區(qū)控制和自舉電路用起來省心。2. SPWM生成的核心細(xì)節(jié)與定時器配置2.1 查表法生成正弦調(diào)制波的參數(shù)計(jì)算SPWM的核心就是拿正弦波和三角波比較輸出占空比按正弦規(guī)律變化的方波。在STM32上實(shí)現(xiàn)最穩(wěn)妥的方法是查表法預(yù)先算好一個正弦周期內(nèi)的N個采樣點(diǎn)存到數(shù)組里定時器中斷里依次讀取更新比較寄存器的值。采樣點(diǎn)數(shù)N的選擇有講究。N太小輸出波形階梯感明顯諧波含量高N太大占用Flash空間多中斷頻率高CPU負(fù)擔(dān)重。對于50Hz輸出如果載波比取200意味著一個正弦周期內(nèi)有200個PWM脈沖每個脈沖對應(yīng)一個采樣點(diǎn)。載波比200時輸出諧波主要集中在200倍基頻附近也就是10kHz左右濾波相對容易。具體計(jì)算過程系統(tǒng)時鐘72MHz定時器預(yù)分頻設(shè)為0自動重裝載值A(chǔ)RR決定PWM頻率。假設(shè)要20kHz的PWM頻率ARR 72MHz / 20kHz - 1 3599。正弦表有200個點(diǎn)每個點(diǎn)對應(yīng)一個正弦值范圍映射到0到ARR之間。正弦值計(jì)算公式sin_val[i] (ARR / 2) * (1 sin(2 * PI * i / N))其中i從0到N-1。這樣算出來的正弦表最小值接近0最大值接近ARR中間值在ARR/2附近。定時器比較寄存器CCR寫入這個值就能得到占空比按正弦規(guī)律變化的PWM波。實(shí)際調(diào)試時ARR不要取滿留一點(diǎn)余量比如用ARR的90%作為正弦表的幅值上限避免占空比到100%時上下管直通。2.2 TIM1互補(bǔ)輸出與死區(qū)時間的配置要點(diǎn)TIM1是STM32F103的高級定時器專門為電機(jī)控制和電源設(shè)計(jì)。配置互補(bǔ)輸出需要設(shè)置幾個關(guān)鍵寄存器CCMR1/CCMR2設(shè)置PWM模式CCER使能互補(bǔ)輸出BDTR設(shè)置死區(qū)時間和主輸出使能。死區(qū)時間的計(jì)算死區(qū)時間 DTG[7:0] × T_dts其中T_dts是定時器時鐘周期。72MHz下T_dts ≈ 13.89ns。如果死區(qū)時間設(shè)1μsDTG值約為72。實(shí)際配置時死區(qū)時間要根據(jù)功率管的開關(guān)特性來定。MOSFET的關(guān)斷時間長死區(qū)要留夠一般500ns到1μs。IGBT關(guān)斷更慢死區(qū)要1μs到2μs。注意BDTR寄存器的MOE位必須置1否則互補(bǔ)輸出不會使能。很多新手調(diào)了半天沒波形就是忘了開MOE。配置代碼大致如下// TIM1初始化PWM頻率20kHz TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; TIM_BDTRInitTypeDef TIM_BDTRInitStructure; TIM_TimeBaseStructure.TIM_Prescaler 0; TIM_TimeBaseStructure.TIM_Period 3599; // 72MHz / 3600 20kHz TIM_TimeBaseStructure.TIM_ClockDivision TIM_CKD_DIV1; TIM_TimeBaseStructure.TIM_CounterMode TIM_CounterMode_Up; TIM_TimeBaseInit(TIM1, TIM_TimeBaseStructure); // 通道1和通道2配置為PWM模式1 TIM_OCInitStructure.TIM_OCMode TIM_OCMode_PWM1; TIM_OCInitStructure.TIM_OutputState TIM_OutputState_Enable; TIM_OCInitStructure.TIM_OutputNState TIM_OutputNState_Enable; TIM_OCInitStructure.TIM_Pulse 0; TIM_OCInitStructure.TIM_OCPolarity TIM_OCPolarity_High; TIM_OCInitStructure.TIM_OCNPolarity TIM_OCNPolarity_High; TIM_OCInitStructure.TIM_OCIdleState TIM_OCIdleState_Reset; TIM_OCInitStructure.TIM_OCNIdleState TIM_OCNIdleState_Reset; TIM_OC1Init(TIM1, TIM_OCInitStructure); TIM_OC2Init(TIM1, TIM_OCInitStructure); // 死區(qū)時間配置約1us TIM_BDTRInitStructure.TIM_OSSRState TIM_OSSRState_Enable; TIM_BDTRInitStructure.TIM_OSSIState TIM_OSSIState_Enable; TIM_BDTRInitStructure.TIM_LOCKLevel TIM_LOCKLevel_1; TIM_BDTRInitStructure.TIM_DeadTime 72; // 72 * 13.89ns ≈ 1us TIM_BDTRInitStructure.TIM_Break TIM_Break_Disable; TIM_BDTRInitStructure.TIM_BreakPolarity TIM_BreakPolarity_High; TIM_BDTRInitStructure.TIM_AutomaticOutput TIM_AutomaticOutput_Enable; TIM_BDTRConfig(TIM1, TIM_BDTRInitStructure); TIM_CtrlPWMOutputs(TIM1, ENABLE); TIM_Cmd(TIM1, ENABLE);這段代碼里TIM_CtrlPWMOutputs(TIM1, ENABLE)就是置MOE位少了這一句互補(bǔ)輸出端不會有任何波形。2.3 中斷服務(wù)函數(shù)與正弦表更新節(jié)奏正弦表的更新在定時器更新中斷里做。每次計(jì)數(shù)器溢出觸發(fā)中斷在中斷里讀取下一個正弦值寫入CCR1和CCR2。注意CCR2要寫反相值因?yàn)閱螛O性倍頻需要兩個橋臂的調(diào)制波反相。中斷頻率就是PWM頻率20kHz。72MHz主頻下每次中斷有3600個時鐘周期可用中斷服務(wù)函數(shù)只要幾十條指令完全跑得過來。但要注意中斷里不要做浮點(diǎn)運(yùn)算不要調(diào)用庫函數(shù)直接查表賦值就行。void TIM1_UP_IRQHandler(void) { if (TIM_GetITStatus(TIM1, TIM_IT_Update) ! RESET) { TIM_ClearITPendingBit(TIM1, TIM_IT_Update); sine_index; if (sine_index SINE_TABLE_SIZE) sine_index 0; // 左橋臂用正弦表 TIM_SetCompare1(TIM1, sine_table[sine_index]); // 右橋臂用反相正弦表 TIM_SetCompare2(TIM1, sine_table[(sine_index SINE_TABLE_SIZE/2) % SINE_TABLE_SIZE]); } }這里用了一個小技巧反相正弦表不需要單獨(dú)存一份直接把索引偏移半個周期就行。這樣Flash占用減半代碼也更簡潔。3. 從零搭建工程的完整實(shí)操流程3.1 標(biāo)準(zhǔn)庫工程模板的建立與關(guān)鍵文件說明雖然現(xiàn)在HAL庫和LL庫越來越流行但做逆變器這類對實(shí)時性要求高的項(xiàng)目標(biāo)準(zhǔn)庫依然是很多老工程師的首選。標(biāo)準(zhǔn)庫直接操作寄存器代碼效率高中斷響應(yīng)快沒有HAL庫那些層層封裝的開銷。新建工程需要準(zhǔn)備幾個東西啟動文件startup_stm32f10x_md.s、鏈接腳本stm32f103c8t6.ld或者Keil里的分散加載文件、標(biāo)準(zhǔn)庫源碼STM32F10x_StdPeriph_Driver、CMSIS核心文件。啟動文件選md后綴的對應(yīng)中等容量產(chǎn)品64KB Flash正好匹配。鏈接腳本里要定義好Flash和RAM的起始地址和大小。STM32F103C8T6的Flash從0x08000000開始大小0x1000064KBRAM從0x20000000開始大小0x500020KB。棧頂?shù)刂吩O(shè)為RAM末尾堆根據(jù)實(shí)際使用情況分配。Keil工程里需要添加的宏定義USE_STDPERIPH_DRIVER和STM32F10X_MD。前者讓標(biāo)準(zhǔn)庫的頭文件包含外設(shè)驅(qū)動后者告訴庫文件當(dāng)前芯片是中容量型號。少了這兩個宏編譯會報(bào)一堆未定義。實(shí)操心得新建工程時先把GPIO點(diǎn)燈跑通確認(rèn)時鐘配置、啟動文件、鏈接腳本都沒問題再往上加定時器和PWM。我見過太多人一上來就寫SPWM結(jié)果燈都不亮根本分不清是時鐘錯了還是PWM配置錯了。3.2 ST-Link調(diào)試器連接與驅(qū)動安裝避坑ST-Link是STM32開發(fā)最常用的調(diào)試器便宜、穩(wěn)定、支持SWD和JTAG。但驅(qū)動安裝經(jīng)常出問題尤其是Win10和Win11系統(tǒng)。常見問題一Keil識別不到ST-Link。先檢查設(shè)備管理器里有沒有“STMicroelectronics STLink dongle”這個設(shè)備。如果沒有說明驅(qū)動沒裝好。去ST官網(wǎng)下載ST-Link驅(qū)動包安裝后重新插拔。如果設(shè)備管理器里顯示黃色感嘆號右鍵更新驅(qū)動手動指向驅(qū)動安裝目錄。常見問題二能識別但下載失敗。檢查SWD接線SWCLK接PA14SWDIO接PA13GND和3.3V必須接。有些最小系統(tǒng)板沒有引出復(fù)位引腳Keil里要把“Reset after Connect”改成“Connect under Reset”否則芯片進(jìn)入低功耗模式后連不上。常見問題三下載一次后第二次連不上。大概率是程序里把SWD引腳復(fù)用了。PA13和PA14默認(rèn)是SWD功能如果代碼里把它們配置成普通GPIO或者復(fù)用成其他外設(shè)調(diào)試器就連不上了。解決辦法是在初始化代碼里加一句GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE)只保留SWD釋放JTAG引腳。但注意不要禁用SWD本身否則下次真的連不上只能用串口ISP或者復(fù)位時按住復(fù)位鍵來救。3.3 串口打印與GBK轉(zhuǎn)UTF8的編碼處理調(diào)試逆變器時串口打印是必不可少的。輸出電壓、電流、頻率、故障碼這些信息通過串口發(fā)到電腦上用串口助手看比點(diǎn)燈直觀得多。STM32的串口配置很簡單USART1接PA9和PA10波特率1152008位數(shù)據(jù)位1位停止位無校驗(yàn)。重定向printf到串口在Keil里勾選“Use MicroLIB”然后實(shí)現(xiàn)fputc函數(shù)就行。int fputc(int ch, FILE *f) { USART_SendData(USART1, (uint8_t)ch); while (USART_GetFlagStatus(USART1, USART_FLAG_TC) RESET); return ch; }編碼問題是個坑。Keil默認(rèn)用GBK編碼保存源文件如果代碼里有中文字符串串口助手用UTF8顯示就是亂碼。解決辦法有兩個一是把Keil的編碼改成UTF8在Edit - Configuration - Editor里設(shè)置二是串口助手切換成GBK顯示。我習(xí)慣用第一種統(tǒng)一UTF8省得以后跨平臺出問題。如果代碼里已經(jīng)有GBK編碼的中文批量轉(zhuǎn)UTF8可以用Notepad或者VS Code。VS Code右下角點(diǎn)擊編碼選“通過編碼重新打開”選GBK然后再“通過編碼保存”選UTF8。批量處理的話用Python腳本跑一遍也行。4. 常見問題排查與實(shí)戰(zhàn)經(jīng)驗(yàn)匯總4.1 PWM無輸出與波形異常的排查路徑PWM調(diào)不出來是新手最常遇到的問題。按以下順序排查基本能覆蓋90%的情況。第一步確認(rèn)時鐘。用示波器測PA8或者PA9看有沒有PWM波形。如果沒有檢查RCC配置里TIM1時鐘是否使能GPIO時鐘是否使能GPIO模式是否配成復(fù)用推挽輸出。第二步確認(rèn)MOE位。TIM1的互補(bǔ)輸出受BDTR寄存器的MOE位控制。如果MOE沒置1CH1N和CH2N不會有輸出??梢栽谡{(diào)試器里直接看BDTR寄存器的值或者加一句TIM_CtrlPWMOutputs(TIM1, ENABLE)。第三步確認(rèn)死區(qū)時間。死區(qū)時間設(shè)得太大比如超過PWM周期的10%輸出占空比會被嚴(yán)重壓縮看起來就像沒輸出。用示波器看互補(bǔ)的兩路波形中間的死區(qū)時間應(yīng)該在幾百納秒到1微秒之間。第四步確認(rèn)比較值。CCR寄存器的值如果大于ARR輸出恒為低或者恒為高。調(diào)試時先把CCR設(shè)成ARR的一半看有沒有50%占空比的方波。有方波了再換成正弦表。波形異常的情況如果輸出波形有毛刺檢查電源濾波和地線布局。如果波形頻率不對檢查ARR和預(yù)分頻的計(jì)算。如果波形幅度不對檢查驅(qū)動電路和功率管。4.2 逆變器帶載后電壓跌落與波形失真空載波形漂亮一帶載就塌這是小功率逆變器的通病。原因通常有三個前級供電不足、濾波電感飽和、死區(qū)補(bǔ)償不夠。前級供電不足最好判斷。用萬用表測母線電壓空載和帶載時對比。如果帶載后母線電壓掉得厲害說明前級電源功率不夠或者線損太大。小功率逆變器前級一般是升壓電路或者直接電池供電電池內(nèi)阻大、線細(xì)、接插件接觸不良都會導(dǎo)致帶載跌落。濾波電感飽和比較隱蔽。電感選型時要看飽和電流如果負(fù)載電流接近或者超過電感的飽和電流電感量急劇下降濾波效果變差波形失真。解決辦法是換更大磁芯或者更大線徑的電感或者提高開關(guān)頻率減小電感需求。死區(qū)補(bǔ)償是進(jìn)階話題。死區(qū)時間會導(dǎo)致輸出電壓損失尤其是在低壓大電流時死區(qū)造成的波形畸變很明顯。可以在正弦表里預(yù)加一個補(bǔ)償量或者根據(jù)電流方向動態(tài)調(diào)整死區(qū)。小功率場合如果死區(qū)設(shè)得不大不補(bǔ)償也能接受。4.3 常見問題速查表現(xiàn)象可能原因排查方法解決措施上電無反應(yīng)供電未接或電壓不足萬用表測3.3V和5V檢查電源接線確認(rèn)電壓ST-Link連不上驅(qū)動未裝或SWD引腳被復(fù)用設(shè)備管理器查看檢查PA13/PA14配置重裝驅(qū)動代碼里保留SWD功能PWM無輸出MOE未使能或時鐘未開示波器測PA8調(diào)試器看BDTR加TIM_CtrlPWMOutputs檢查RCC波形頻率不對ARR或預(yù)分頻計(jì)算錯誤示波器測周期反推頻率重新計(jì)算ARR和預(yù)分頻值帶載電壓跌落前級功率不足或電感飽和測母線電壓摸電感溫度加大前級功率換大磁芯電感串口亂碼編碼不一致串口助手切換GBK/UTF8統(tǒng)一Keil和串口助手編碼死區(qū)時間異常DTG值計(jì)算錯誤示波器看互補(bǔ)波形死區(qū)按公式重新計(jì)算DTG管子發(fā)熱嚴(yán)重死區(qū)不夠或驅(qū)動不足測柵極波形看死區(qū)時間加大死區(qū)換驅(qū)動芯片4.4 幾個容易被忽略的實(shí)操細(xì)節(jié)VBAT引腳處理。STM32F103C8T6的VBAT引腳如果不用直接接3.3V或者懸空都行但不要接錯到5V會燒。如果板子上有紐扣電池座VBAT接電池正極掉電時RTC和備份寄存器能保持。PB0不能做按鍵。熱詞里有人問這個確實(shí)PB0在某些最小系統(tǒng)板上接了LED或者別的外設(shè)做按鍵輸入時要注意上下拉配置。如果PB0外部已經(jīng)有上拉電阻內(nèi)部就不需要再開上拉否則電平?jīng)_突。DMA通道沖突。STM32F103的DMA1有7個通道每個通道對應(yīng)固定的外設(shè)請求。TIM1的更新事件對應(yīng)DMA1通道5TIM2對應(yīng)通道2USART1_TX對應(yīng)通道4。配置DMA時先查參考手冊的請求映射表別配錯了通道否則DMA不觸發(fā)。FreeRTOS下的中斷優(yōu)先級。如果項(xiàng)目里跑了FreeRTOSTIM1中斷的優(yōu)先級要設(shè)得比configMAX_SYSCALL_INTERRUPT_PRIORITY高否則中斷里調(diào)用FreeRTOS的API會觸發(fā)斷言。逆變器的PWM中斷對實(shí)時性要求高優(yōu)先級設(shè)最高中斷里只做查表和賦值不做任何系統(tǒng)調(diào)用。Flash加密。STM32F103支持讀保護(hù)通過選項(xiàng)字節(jié)設(shè)置。量產(chǎn)時開啟讀保護(hù)防止代碼被讀出。但注意開啟讀保護(hù)后調(diào)試器無法再連接除非先解除保護(hù)而解除保護(hù)會擦除整個Flash。調(diào)試階段不要開量產(chǎn)前再開。5. 方案擴(kuò)展與性能優(yōu)化方向5.1 從SPWM到SVPWM的升級路徑SPWM實(shí)現(xiàn)簡單但直流電壓利用率只有86.6%。SVPWM空間矢量PWM能把利用率提高到100%同樣母線電壓下輸出交流電壓更高。對于電池供電的小功率逆變器這意味著可以多輸出15%的功率。SVPWM的核心是判斷扇區(qū)、計(jì)算基本矢量作用時間、生成PWM比較值。在STM32上實(shí)現(xiàn)需要用到一些三角函數(shù)和查表。TIM1依然可以用只是比較值的計(jì)算方式變了。如果SPWM已經(jīng)跑通升級SVPWM主要是改中斷里的計(jì)算邏輯硬件不用動。不過SVPWM的計(jì)算量比SPWM大20kHz中斷下72MHz的M3內(nèi)核要仔細(xì)優(yōu)化代碼。可以用查表加插值的方式減少實(shí)時計(jì)算量或者降低開關(guān)頻率到10kHz給CPU留更多時間。5.2 加入ADC采樣實(shí)現(xiàn)閉環(huán)控制開環(huán)逆變器輸出電壓隨負(fù)載變化帶載后電壓跌落明顯。加入ADC采樣輸出電壓做PID閉環(huán)可以穩(wěn)住輸出。STM32F103的ADC是12位最快1MHz采樣率采50Hz正弦波綽綽有余。采樣時機(jī)很關(guān)鍵。要在PWM周期的特定時刻采樣避開開關(guān)噪聲。一般是在計(jì)數(shù)器溢出中斷里觸發(fā)ADC或者在PWM中點(diǎn)采樣。用DMA把ADC結(jié)果搬到內(nèi)存不占CPU。PID計(jì)算放在慢速循環(huán)里比如每10個PWM周期算一次減輕CPU負(fù)擔(dān)。電壓采樣用電阻分壓加運(yùn)放跟隨電流采樣用霍爾傳感器或者采樣電阻加差分放大。采樣電路的地要和功率地分開單點(diǎn)接地否則開關(guān)噪聲會串進(jìn)ADC導(dǎo)致采樣值跳動。5.3 保護(hù)機(jī)制過流、過溫、欠壓逆變器沒有保護(hù)就是炸彈。最基本的三個保護(hù)過流保護(hù)、過溫保護(hù)、欠壓保護(hù)。過流保護(hù)用比較器實(shí)現(xiàn)最快。采樣電阻上的電壓和基準(zhǔn)比較超過閾值直接觸發(fā)TIM1的剎車輸入BKIN硬件立刻關(guān)斷PWM輸出比軟件響應(yīng)快得多。STM32的TIM1有專門的剎車引腳配置成剎車輸入觸發(fā)后MOE自動清零PWM輸出立刻變高阻。過溫保護(hù)用NTC熱敏電阻接ADC采樣溫度超過閾值降功率或者停機(jī)。欠壓保護(hù)監(jiān)測母線電壓低于閾值時報(bào)警并停機(jī)防止電池過放。保護(hù)閾值要留余量。過流閾值設(shè)成額定電流的1.5倍到2倍過溫閾值設(shè)成管子最大結(jié)溫的80%欠壓閾值根據(jù)電池類型定鉛酸電池單節(jié)1.8V鋰電池單節(jié)3.0V。5.4 代碼優(yōu)化從查表到實(shí)時計(jì)算的權(quán)衡查表法簡單可靠但正弦表占Flash且頻率固定。如果要輸出可變頻率比如45Hz到65Hz可調(diào)查表法就需要動態(tài)調(diào)整索引步進(jìn)或者用多個表切換。實(shí)時計(jì)算正弦值靈活但M3內(nèi)核沒有浮點(diǎn)單元算一次sin要幾百個時鐘周期20kHz中斷下根本來不及。折中方案是用定點(diǎn)數(shù)查表加線性插值或者用CORDIC算法。CORDIC用移位和加法算三角函數(shù)適合沒有FPU的MCU但代碼復(fù)雜度高。對于小功率逆變器輸出頻率通常固定50Hz查表法足夠。如果要做變頻建議用查表加索引步進(jìn)調(diào)整步進(jìn)值根據(jù)目標(biāo)頻率計(jì)算。比如200點(diǎn)正弦表對應(yīng)50Hz步進(jìn)為1對應(yīng)60Hz步進(jìn)為1.2取整處理會有輕微頻率誤差但小功率場合可以接受。6. 寫在最后的一些個人體會這個方案我從頭到尾跑過不止一遍踩過的坑基本都寫在上面了。STM32F103C8T6做小功率逆變器性能綽綽有余關(guān)鍵是把定時器和死區(qū)配置對把保護(hù)機(jī)制做扎實(shí)。很多人一上來就追求SVPWM、閉環(huán)控制結(jié)果連開環(huán)SPWM都沒調(diào)穩(wěn)帶個燈泡都閃。我的建議是先把開環(huán)跑通波形干凈了再加閉環(huán)和保護(hù)一步一步來。還有一點(diǎn)功率部分和數(shù)字部分一定要分開布局。我見過有人把STM32和H橋畫在同一塊板上地線沒處理好ADC采樣全是噪聲PWM波形上全是毛刺。數(shù)字地和功率地單點(diǎn)連接驅(qū)動信號用光耦或者隔離芯片隔開這些問題就少很多。最后調(diào)試逆變器一定要有示波器最好是四通道的??碢WM波形、看死區(qū)、看輸出電壓、看電流四個通道同時抓什么問題都藏不住。沒有示波器用萬用表測平均電壓也能湊合但效率低很多。