動(dòng)三相無刷電機(jī):六步換相與PI調(diào)速實(shí)戰(zhàn))
簡(jiǎn)介基于STM32G431的三相無刷電機(jī)驅(qū)動(dòng)與比例積分PI調(diào)速完整工程源碼面向嵌入式電機(jī)控制方向的學(xué)習(xí)者與開發(fā)者用于掌握無刷電機(jī)換相邏輯、脈寬調(diào)制驅(qū)動(dòng)以及閉環(huán)調(diào)速的實(shí)現(xiàn)方法。工程基于硬件抽象層HAL庫和官方數(shù)字信號(hào)處理庫搭建核心代碼涵蓋高分辨率定時(shí)器配置、三相逆變橋驅(qū)動(dòng)、電流與速度采樣、比例積分調(diào)節(jié)器以及相應(yīng)控制邏輯可作為無刷電機(jī)控制項(xiàng)目的移植參考或二次開發(fā)基礎(chǔ)。工程中保留了完整的構(gòu)建中間文件和鏈接腳本便于理解嵌入式工程的組織方式。資源共1524個(gè)文件以C語言源碼和頭文件為主輔以匯編程序、鏈接腳本、編譯工程配置、圖形化配置工程以及編譯生成的燒錄文件便于對(duì)照完整工程結(jié)構(gòu)進(jìn)行重新編譯和驗(yàn)證目錄結(jié)構(gòu)清晰從啟動(dòng)文件、硬件抽象層到底層驅(qū)動(dòng)和上層算法均有對(duì)應(yīng)代碼。壓縮包整體約43.48兆字節(jié)累計(jì)已有2063人下載學(xué)習(xí)適合具備一定單片機(jī)基礎(chǔ)、希望深入電機(jī)控制底層實(shí)現(xiàn)與調(diào)參實(shí)踐的讀者。1. 為什么stm32G431驅(qū)動(dòng)三相無刷電機(jī)默認(rèn)先做PI調(diào)速而不是一上來就上FOC拿STM32G431驅(qū)動(dòng)三相無刷電機(jī)很多人的第一反應(yīng)是直接上FOC。但實(shí)際量產(chǎn)項(xiàng)目里大量方案用的是六步換相加PI調(diào)速原因很直接代碼量小一個(gè)量級(jí)調(diào)試周期從幾周縮到一兩天而且在中低速、大扭矩的應(yīng)用場(chǎng)景下?lián)Q相邏輯清晰轉(zhuǎn)速閉環(huán)同樣穩(wěn)定。G431這顆芯片自帶170MHz主頻、HRTIM、模擬比較器和高速ADC做六步換相屬于資源溢出根本不需要?jiǎng)佑肍OC那種復(fù)雜架構(gòu)。這篇文章就按一線工程師最常用的路線走一遍用霍爾傳感器做轉(zhuǎn)子位置反饋TIM1輸出三路PWM驅(qū)動(dòng)三相全橋PI調(diào)速閉環(huán)控制轉(zhuǎn)速。從換相表怎么建、PWM怎么配、轉(zhuǎn)速怎么算、PI參數(shù)怎么定到最容易踩的坑全部給出能直接抄的代碼和步驟。2. 六步換相原理與G431外設(shè)選型霍爾方案為什么夠用2.1 三相無刷電機(jī)的六步換相邏輯無刷直流電機(jī)BLDC的反電動(dòng)勢(shì)近似梯形波所以驅(qū)動(dòng)邏輯不必像永磁同步電機(jī)那樣追求正弦電流波形只需要在轉(zhuǎn)子轉(zhuǎn)到特定角度時(shí)以60°電角度為步進(jìn)切換通電相電機(jī)就能持續(xù)輸出轉(zhuǎn)矩。這就是“六步換相”這個(gè)名字的來源。每步只有兩相導(dǎo)通一相進(jìn)電流一相出電流第三相懸空。以常見的內(nèi)轉(zhuǎn)子電機(jī)為例通電順序從AB-開始依次切到AC-、BC-、BA-、CA-、CB-六個(gè)狀態(tài)循環(huán)一圈轉(zhuǎn)子轉(zhuǎn)過360°電角度。極對(duì)數(shù)為p的電機(jī)電角度轉(zhuǎn)一圈對(duì)應(yīng)機(jī)械角度360°/p所以六步換相恰好覆蓋一個(gè)電周期?;魻杺鞲衅靼惭b在定子上三個(gè)霍爾間隔120°電角度輸出三路高低電平組合一共8種狀態(tài)其中6種是有效位置對(duì)應(yīng)轉(zhuǎn)子的6個(gè)扇區(qū)??刂破髯x取霍爾組合后查表得到當(dāng)前扇區(qū)再?zèng)Q定哪兩相通電。這就是霍爾換相的完整閉環(huán)。2.2 霍爾信號(hào)與通電相的映射表換相表是調(diào)試的第一道坎因?yàn)榛魻柊惭b方向、電機(jī)繞組接法不同同一張表在不同電機(jī)上表現(xiàn)完全不一樣。以下是一張最常用的默認(rèn)表以霍爾輸出HA、HB、HC的順序拼成3位二進(jìn)制數(shù)0代表A相、1代表B相、2代表C相?;魻柦M合H3:H2:H1上橋PWM相下橋?qū)ㄏ鄬?shí)際通電狀態(tài)0b000/0b111無無無效狀態(tài)停止輸出0b001ACAC-0b010ABAB-0b011BCBC-0b100BABA-0b101CACA-0b110CBCB-注意這張表只是起點(diǎn)。如果電機(jī)通電后抖動(dòng)不轉(zhuǎn)或者反轉(zhuǎn)優(yōu)先做兩件事一是把表中6個(gè)有效狀態(tài)整體前移或后移一格相當(dāng)于調(diào)整60°換相角二是任意交換兩路霍爾輸入線霍爾組合的編碼順序會(huì)整體重排。實(shí)際操作時(shí)我一般會(huì)在代碼里預(yù)留一個(gè)數(shù)組存這張表然后用串口把實(shí)時(shí)霍爾值打出來配合示波器看相電流波形最多10分鐘就能調(diào)對(duì)。2.3 stm32G431驅(qū)動(dòng)三相無刷電機(jī)哪些外設(shè)真正干活ST特意在G431上堆了一組電機(jī)控制外設(shè)但六步換相方案真正用到的其實(shí)只有一小部分。核心是TIM1高級(jí)定時(shí)器它有3個(gè)通道可以輸出PWM且每個(gè)通道帶互補(bǔ)輸出、剎車輸入和死區(qū)插入。對(duì)六步換相來說三路PWM就夠驅(qū)動(dòng)上橋余下的互補(bǔ)通道可以不用把引腳當(dāng)普通GPIO控制下橋。HRTIM高分辨率定時(shí)器在FOC里是主角但在六步換相里反而用不上。它的價(jià)值在于能和比較器、ADC聯(lián)動(dòng)產(chǎn)生精確的PWM中心對(duì)齊觸發(fā)信號(hào)做無感FOC電流采樣非常合適。如果項(xiàng)目下一步要升級(jí)FOCG431的HRTIM一秒切入只做PI調(diào)速TIM1完全夠。G431的另一組好料是內(nèi)置運(yùn)放和比較器不需要外接比較電路就能做無感反電動(dòng)勢(shì)過零檢測(cè)。但霍爾方案本身不需要過零檢測(cè)比較器可以用來做過流保護(hù)。ADC的高速采樣能力同樣用不上全部性能每50μs采一次母線電流就足夠保護(hù)邏輯用了。2.4 PWM調(diào)制方式高側(cè)斬波與同步整流的取舍六步換相的PWM調(diào)制方式有好幾種最常見的是H_PWM-L_ON上橋PWM斬波下橋常通。這種方式控制邏輯簡(jiǎn)單續(xù)流靠下橋MOSFET的體二極管缺點(diǎn)是關(guān)斷時(shí)電流經(jīng)體二極管續(xù)流二極管損耗大大電流工況下發(fā)熱明顯。另一種是互補(bǔ)PWM同步整流上下橋互補(bǔ)輸出關(guān)斷期間電流走下橋MOSFET溝道導(dǎo)通損耗小但代碼里要處理死區(qū)、避免直通換相瞬間的邏輯也更復(fù)雜。G431的TIM1自帶死區(qū)生成器理論上可以直接用但需要時(shí)刻保證同一半橋上下管不能同時(shí)導(dǎo)通對(duì)六步狀態(tài)機(jī)的正確性要求更高。我一般選H_PWM-L_ON起步原因很實(shí)際先用最簡(jiǎn)單的驅(qū)動(dòng)邏輯確認(rèn)換相表、轉(zhuǎn)速測(cè)量和PI調(diào)速跑通再考慮要不要加同步整流優(yōu)化效率。PWM頻率取20kHz以上能避開可聽見的噪聲G431的TIM1時(shí)鐘170MHzARR值取8500就是20kHz占空比分辨率足夠細(xì)膩。3. stm32G431驅(qū)動(dòng)三相無刷電機(jī)的硬件接線與PWM初始化3.1 三相逆變橋與G431的引腳分配硬件上需要三相全橋逆變電路最常見的是6顆N溝道MOSFET加?xùn)艠O驅(qū)動(dòng)芯片比如IR2101、EG2134這類自帶自舉電路的高低壓側(cè)驅(qū)動(dòng)。柵極驅(qū)動(dòng)芯片的輸入側(cè)只需要三路上橋PWM和三路下橋電平信號(hào)正好對(duì)應(yīng)G431的一組TIM1輸出加三個(gè)GPIO。以下是全套接線參考按這個(gè)接法CubeMX里的引腳配置可以直接照抄。功能引腳外設(shè)/復(fù)用說明A相上橋PWMPA8TIM1_CH1接A相柵極驅(qū)動(dòng)高側(cè)輸入B相上橋PWMPA9TIM1_CH2接B相柵極驅(qū)動(dòng)高側(cè)輸入C相上橋PWMPA10TIM1_CH3接C相柵極驅(qū)動(dòng)高側(cè)輸入A相下橋控制PB13GPIO輸出接A相柵極驅(qū)動(dòng)低側(cè)輸入B相下橋控制PB14GPIO輸出接B相柵極驅(qū)動(dòng)低側(cè)輸入C相下橋控制PB15GPIO輸出接C相柵極驅(qū)動(dòng)低側(cè)輸入霍爾HAPC6EXTI6外部中斷輸入上拉霍爾HBPC7EXTI7外部中斷輸入上拉霍爾HCPC8EXTI8外部中斷輸入上拉母線電流采樣PA0ADC1_IN1經(jīng)運(yùn)放放大后進(jìn)ADC要注意PB13、PB14、PB15雖然硬件上同時(shí)連接TIM1的互補(bǔ)通道但只要在CubeMX里配置成GPIO輸出就不會(huì)觸碰TIM1的PWM功能?;魻栆_用外部中斷而不是輸入捕獲是因?yàn)閾Q相動(dòng)作需要在任意一路霍爾變化時(shí)立刻響應(yīng)三路霍爾共用EXTI9_5中斷線在一次中斷里統(tǒng)一讀取三路電平效率更高。3.2 初始化定時(shí)器PWM和IO讓電機(jī)先轉(zhuǎn)起來初始化代碼用HAL庫寫結(jié)構(gòu)清楚也方便CubeMX用戶直接對(duì)齊自己的工程。PWM頻率按20kHz設(shè)置ARM值8500初始占空比0。static void Motor_PWM_Init(void) { GPIO_InitTypeDef gpio {0}; TIM_OC_InitTypeDef oc {0}; __HAL_RCC_TIM1_CLK_ENABLE(); __HAL_RCC_GPIOA_CLK_ENABLE(); __HAL_RCC_GPIOB_CLK_ENABLE(); // PA8/PA9/PA10 復(fù)用為 TIM1 CH1/CH2/CH3接上橋驅(qū)動(dòng) gpio.Pin GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10; gpio.Mode GPIO_MODE_AF_PP; gpio.Pull GPIO_NOPULL; gpio.Speed GPIO_SPEED_FREQ_HIGH; gpio.Alternate GPIO_AF1_TIM1; HAL_GPIO_Init(GPIOA, gpio); // PB13/14/15 做普通GPIO控制下橋 gpio.Pin GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15; gpio.Mode GPIO_MODE_OUTPUT_PP; gpio.Alternate 0; HAL_GPIO_Init(GPIOB, gpio); htim1.Instance TIM1; htim1.Init.Prescaler 0; htim1.Init.CounterMode TIM_COUNTERMODE_UP; htim1.Init.Period 8500 - 1; // 170MHz / 8500 20kHz htim1.Init.ClockDivision TIM_CLOCKDIVISION_DIV1; htim1.Init.RepetitionCounter 0; htim1.Init.AutoReloadPreload TIM_AUTORELOAD_PRELOAD_ENABLE; HAL_TIM_PWM_Init(htim1); oc.OCMode TIM_OCMODE_PWM1; oc.Pulse 0; oc.OCPolarity TIM_OCPOLARITY_HIGH; oc.OCFastMode TIM_OCFAST_DISABLE; HAL_TIM_PWM_ConfigChannel(htim1, oc, TIM_CHANNEL_1); HAL_TIM_PWM_ConfigChannel(htim1, oc, TIM_CHANNEL_2); HAL_TIM_PWM_ConfigChannel(htim1, oc, TIM_CHANNEL_3); HAL_TIM_PWM_Start(htim1, TIM_CHANNEL_1); HAL_TIM_PWM_Start(htim1, TIM_CHANNEL_2); HAL_TIM_PWM_Start(htim1, TIM_CHANNEL_3); }Period取8500減一是因?yàn)橛?jì)數(shù)器從0計(jì)數(shù)到8499正好8500個(gè)計(jì)數(shù)周期。PWM頻率等于定時(shí)器時(shí)鐘除以PeriodG431的TIM1掛在APB2上最高170MHzPrescaler為0時(shí)直接得到170MHz計(jì)數(shù)時(shí)鐘。HAL_TIM_PWM_Start只啟動(dòng)三路主輸出下橋完全由GPIO控制不涉及互補(bǔ)通道死區(qū)問題留給柵極驅(qū)動(dòng)芯片和軟件換相間隙解決。3.3 換相狀態(tài)機(jī)查詢霍爾并切換PWM通道換相函數(shù)是整套驅(qū)動(dòng)的心臟。它根據(jù)霍爾組合查表確定當(dāng)前步進(jìn)應(yīng)該P(yáng)WM哪一相上橋、導(dǎo)通哪一相下橋。為了保證換相瞬間不出現(xiàn)上下橋直通我采用“先關(guān)下橋再恢復(fù)PWM”的序列中間留幾微秒間隔。static uint8_t cur_pwm_ch 0; // 當(dāng)前上橋PWM通道 0/1/2 對(duì)應(yīng)A/B/C static uint8_t cur_low_ph 0; // 當(dāng)前下橋?qū)ㄏ?0/1/2 static uint16_t cur_duty 0; // 當(dāng)前PWM比較值 // 換相表行霍爾組合列[上橋PWM相, 下橋?qū)ㄏ郵 // 0A, 1B, 2C, 0xFF不動(dòng)作 const int8_t step_table[8][2] { {0xFF, 0xFF}, // 0b000 { 0, 2 }, // 0b001 { 0, 1 }, // 0b010 { 1, 2 }, // 0b011 { 1, 0 }, // 0b100 { 2, 0 }, // 0b101 { 2, 1 }, // 0b110 {0xFF, 0xFF}, // 0b111 }; static const uint16_t pwm_ch_map[3] { TIM_CHANNEL_1, TIM_CHANNEL_2, TIM_CHANNEL_3 }; static const uint16_t low_pin[3] { GPIO_PIN_13, GPIO_PIN_14, GPIO_PIN_15 }; void Motor_Set_Step(uint8_t hall) { const int8_t *step step_table[hall]; HAL_GPIO_WritePin(GPIOB, low_pin[0] | low_pin[1] | low_pin[2], GPIO_PIN_RESET); __HAL_TIM_SET_COMPARE(htim1, pwm_ch_map[cur_pwm_ch], 0); if (step[0] 0xFF) { cur_pwm_ch 0xFF; return; } cur_pwm_ch step[0]; cur_low_ph step[1]; HAL_GPIO_WritePin(GPIOB, low_pin[cur_low_ph], GPIO_PIN_SET); __HAL_TIM_SET_COMPARE(htim1, pwm_ch_map[cur_pwm_ch], cur_duty); }這段邏輯里換相第一時(shí)間把舊上橋PWM比較值清零同時(shí)關(guān)閉全部下橋避免新舊兩步之間出現(xiàn)“舊下橋沒關(guān)、新上橋已開”的瞬間。之后設(shè)置新下橋?qū)ㄔ倩謴?fù)新上橋PWM。cur_duty是PI調(diào)速輸出后寫入的全局占空比這樣換相時(shí)能立刻知道當(dāng)前應(yīng)該輸出多大占空比。3.4 霍爾外部中斷與轉(zhuǎn)速時(shí)間戳霍爾信號(hào)變化觸發(fā)EXTI9_5中斷在中斷服務(wù)函數(shù)里讀霍爾組合、調(diào)換相函數(shù)并用DWT計(jì)數(shù)器記錄兩次換相的時(shí)間間隔。DWT-CYCCNT是Cortex-M4內(nèi)核自帶的周期計(jì)數(shù)器適合做微秒級(jí)時(shí)間測(cè)量比SysTick更輕量。volatile uint32_t hall_tick_us 0; volatile uint32_t comm_period_us 0; void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) { uint8_t hall; uint32_t now_us; if ((GPIO_Pin (GPIO_PIN_6 | GPIO_PIN_7 | GPIO_PIN_8)) 0) return; hall (HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_8) 2) | (HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_7) 1) | HAL_GPIO_ReadPin(GPIOC, GPIO_PIN_6); now_us DWT-CYCCNT / 170; comm_period_us now_us - hall_tick_us; hall_tick_us now_us; Motor_Set_Step(hall); }DWT-CYCCNT每周期加1170MHz下每微秒加170。需要在使用前使能DWT計(jì)數(shù)器開啟方式是在main里執(zhí)行CoreDebug-DEMCR | CoreDebug_DEMCR_TRCENA_Msk然后DWT-CTRL | DWT_CTRL_CYCCNTENA_Msk?;魻栔袛嗬镒隽藘杉聹y(cè)量換相周期執(zhí)行換相。速度計(jì)算不在中斷里做除法只在需要時(shí)用comm_period_us算出轉(zhuǎn)速避免中斷里浮點(diǎn)運(yùn)算拖慢響應(yīng)。4. stm32G431的PI調(diào)速實(shí)現(xiàn)從換相周期計(jì)算轉(zhuǎn)速到閉環(huán)修正4.1 轉(zhuǎn)速計(jì)算公式為什么是十萬除以極對(duì)數(shù)乘換相周期霍爾換相周期和轉(zhuǎn)速之間是嚴(yán)格的幾何關(guān)系。每?jī)纱螕Q相之間轉(zhuǎn)子轉(zhuǎn)過60°電角度6次換相完成一個(gè)完整電周期。一個(gè)電周期對(duì)應(yīng)機(jī)械角度為360°/p所以轉(zhuǎn)速和換相周期的關(guān)系如下。轉(zhuǎn)速RPM 60000000 / (6 * p * comm_period_us) 10000000 / (p * comm_period_us)極對(duì)數(shù)p在電機(jī)參數(shù)里通常標(biāo)著比如2812電機(jī)通常是4對(duì)極或7對(duì)極。comm_period_us是霍爾中斷里記錄的相鄰兩次換相間隔。以p4、comm_period1000μs為例轉(zhuǎn)速就是10000000除以4000等于2500RPM。這個(gè)公式不依賴任何傳感器標(biāo)定只要霍爾安裝正確算出來的轉(zhuǎn)速就是準(zhǔn)的。用定時(shí)器固定1ms周期計(jì)算轉(zhuǎn)速并執(zhí)行PI比在換相中斷里直接調(diào)PI更穩(wěn)定。因?yàn)榈退贂r(shí)換相間隔變長PI的執(zhí)行頻率會(huì)跟著降低比例積分參數(shù)沒法固定。固定1ms采樣相當(dāng)于把速度環(huán)采樣時(shí)間定死Kp和Ki的物理意義清晰調(diào)參也更符合直覺。#define MOTOR_POLE_PAIRS 4 volatile uint16_t motor_rpm 0; void Speed_Calc_Update(void) { uint32_t period comm_period_us; uint32_t rpm; if (period 0 || period 100000) { motor_rpm 0; return; } rpm 10000000UL / (MOTOR_POLE_PAIRS * period); motor_rpm (uint16_t)rpm; }period超過100ms說明電機(jī)已經(jīng)接近停轉(zhuǎn)此時(shí)轉(zhuǎn)速記0更合理。如果電機(jī)高速轉(zhuǎn)period很小rpm可能超過uint16_t范圍但這個(gè)場(chǎng)景在常規(guī)電機(jī)驅(qū)動(dòng)里很難出現(xiàn)工程上夠用。4.2 PI控制器結(jié)構(gòu)位置式還是增量式PI調(diào)速輸出的是PWM比較值屬于絕對(duì)占空比所以用位置式PI最直接。位置式PI的公式是u(k)Kpe(k)KiΣe(i)其中誤差積分項(xiàng)需要單獨(dú)累加。增量式PI輸出的是每次調(diào)整量適合步進(jìn)電機(jī)或輸出本身就是增量的執(zhí)行器無刷電機(jī)的占空比是絕對(duì)值用位置式少一次換算限幅和積分飽和處理也更直觀。積分飽和是位置式PI在電機(jī)啟動(dòng)階段最常見的問題。啟動(dòng)時(shí)轉(zhuǎn)速誤差大積分項(xiàng)快速累加等轉(zhuǎn)速接近目標(biāo)時(shí)積分還停留在高位導(dǎo)致超調(diào)甚至振蕩。對(duì)抗辦法是積分分離誤差超過一定范圍時(shí)停止積分進(jìn)入穩(wěn)態(tài)后再讓積分器工作。下面的代碼把積分分離閾值放在±200RPM區(qū)間內(nèi)啟動(dòng)階段積分器不會(huì)瘋狂累加。#define KP_DEFAULT 0.15f #define KI_DEFAULT 0.02f #define DUTY_MIN 0.10f #define DUTY_MAX 0.95f #define INTEGRAL_LIMIT 0.30f #define SPEED_ERR_BAND 200 static float duty_ratio 0.10f; static float integral 0.0f; static uint16_t target_rpm 1500; void PI_Update(void) { float err, out; err (float)target_rpm - (float)motor_rpm; if (err -SPEED_ERR_BAND err SPEED_ERR_BAND) { integral err; if (integral INTEGRAL_LIMIT) integral INTEGRAL_LIMIT; if (integral -INTEGRAL_LIMIT) integral -INTEGRAL_LIMIT; } out KP_DEFAULT * err KI_DEFAULT * integral; if (out DUTY_MAX) out DUTY_MAX; if (out DUTY_MIN) out DUTY_MIN; duty_ratio out; cur_duty (uint16_t)(out * 8500.0f); }積分限幅0.3對(duì)應(yīng)的物理意義是積分項(xiàng)對(duì)占空比的貢獻(xiàn)最多30%比例項(xiàng)在啟動(dòng)階段主導(dǎo)輸出避免積分器單獨(dú)把占空比推到極限。輸出下限10%是因?yàn)镻WM占空比低于10%時(shí)電機(jī)往往無法克服靜摩擦占空比上不去會(huì)導(dǎo)致PI一直在積分實(shí)際表現(xiàn)為電機(jī)嗡嗡響但不轉(zhuǎn)。4.3 1ms定時(shí)器中斷里執(zhí)行速度閉環(huán)PI放在TIM6的1ms周期中斷里。TIM6是基礎(chǔ)定時(shí)器只有中斷功能適合做系統(tǒng)節(jié)拍。在中斷里先計(jì)算最新轉(zhuǎn)速再執(zhí)行PI更新?lián)Q相則始終由霍爾中斷驅(qū)動(dòng)兩者互不干擾。void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { if (htim-Instance TIM6) { Speed_Calc_Update(); PI_Update(); } }這種結(jié)構(gòu)的好處是速度環(huán)和換相環(huán)解耦?;魻栔袛囝l率隨轉(zhuǎn)速變化最高可能到幾千赫茲速度環(huán)頻率固定1kHz穩(wěn)定可設(shè)計(jì)。PI的參數(shù)整定基于1ms采樣周期Kp和Ki的量綱清晰。如果未來要調(diào)成5ms或2ms采樣只需改TIM6的周期再按比例縮Ki即可。4.4 PI參數(shù)整定先P后I的實(shí)操順序參數(shù)表給出起步值和調(diào)節(jié)方向但真正在現(xiàn)場(chǎng)調(diào)參時(shí)順序比數(shù)值更重要。參數(shù)作用起步值調(diào)節(jié)方向Kp比例增益決定響應(yīng)速度0.10~0.15過小響應(yīng)慢過大會(huì)持續(xù)振蕩Ki積分增益消除穩(wěn)態(tài)誤差0.01~0.02過大會(huì)超調(diào)過小有靜差輸出上限限制最大占空比0.95限制最大電流時(shí)可調(diào)低輸出下限最小啟動(dòng)占空比0.10低于該值電機(jī)無法轉(zhuǎn)動(dòng)積分限幅防積分飽和0.30啟動(dòng)無超調(diào)時(shí)可適當(dāng)增大先把Ki設(shè)為0Kp從0.05開始目標(biāo)轉(zhuǎn)速設(shè)到額定轉(zhuǎn)速的一半觀察電機(jī)是否能在1秒內(nèi)接近目標(biāo)并且不振蕩。如果轉(zhuǎn)速在目標(biāo)上下反復(fù)擺動(dòng)Kp減半。如果接近目標(biāo)的弧線很緩、遲遲到不了Kp翻倍。找到一個(gè)“稍有超調(diào)但不持續(xù)振蕩”的Kp后再把Ki從0.005開始緩慢增大觀察穩(wěn)態(tài)誤差是否歸零。這個(gè)階段Ki過大的特征很明顯轉(zhuǎn)速到達(dá)目標(biāo)后出現(xiàn)周期性浪涌聲音粗細(xì)交替這時(shí)Ki立刻減半。5. 調(diào)試技巧開環(huán)驗(yàn)證換相順序再閉環(huán)調(diào)PI參數(shù)5.1 第一階段固定占空比確認(rèn)換相順序不要一上來就閉環(huán)。先把PI輸出的占空比寫死成30%用串口把霍爾值打印出來手動(dòng)緩慢轉(zhuǎn)動(dòng)電機(jī)軸觀察串口打印的霍爾組合是否按步進(jìn)表的順序循環(huán)。如果霍爾組合跳變順序不是循環(huán)的說明霍爾接線或換相表次序不對(duì)交換任意兩路霍爾輸入再試?;魻枲顟B(tài)正常后再上電給定30%占空比電機(jī)應(yīng)該能平滑轉(zhuǎn)起來。如果抖一下停住說明換相表和霍爾組合錯(cuò)位把step_table的6行數(shù)據(jù)整體平移一格。5.2 第二階段用示波器看PWM和相電壓波形確認(rèn)直通風(fēng)險(xiǎn)接好示波器探頭到A相上橋PWM引腳和A相相電壓節(jié)點(diǎn)空載運(yùn)行電機(jī)。正常狀態(tài)是PWM引腳輸出20kHz方波占空比隨負(fù)載變化相電壓在每個(gè)換相點(diǎn)附近呈現(xiàn)梯形波形狀。如果相電壓在換相瞬間出現(xiàn)尖峰或者母線電流明顯增大先檢查軟件換相間隙是否太短。我一般在Motor_Set_Step里加一個(gè)約2μs的延時(shí)再恢復(fù)PWM輸出成本低能有效避免上下橋直通。不要小看這一步很多電機(jī)燒MOSFET都是換相時(shí)序的問題不是過流保護(hù)沒做。5.3 第三階段閉環(huán)微調(diào)PI并記錄階躍響應(yīng)曲線閉環(huán)啟動(dòng)前把目標(biāo)轉(zhuǎn)速設(shè)為200RPM先用極小的Kp跑起來。重點(diǎn)看電機(jī)能不能穩(wěn)定停在目標(biāo)轉(zhuǎn)速附近而不是看它多久到達(dá)。穩(wěn)定后把目標(biāo)轉(zhuǎn)速突變到1500RPM記錄轉(zhuǎn)速從突變到穩(wěn)定的時(shí)間。理想的階躍響應(yīng)是無超調(diào)或單次小超調(diào)穩(wěn)定時(shí)間在200ms以內(nèi)。如果轉(zhuǎn)速在目標(biāo)下方爬升緩慢增加Kp如果出現(xiàn)等幅振蕩先減Kp再觀察是否恢復(fù)。PI調(diào)好后還要驗(yàn)證最低轉(zhuǎn)速和最高轉(zhuǎn)速兩個(gè)極端點(diǎn)。最低轉(zhuǎn)速下?lián)Q相周期長速度環(huán)采樣不會(huì)因?yàn)閾Q相中斷太慢而跳變最高轉(zhuǎn)速下輸出占空比接近上限確認(rèn)PI輸出沒有飽和過頭導(dǎo)致突然失速。調(diào)完參數(shù)后把轉(zhuǎn)速、PI輸出、母線電流三路信號(hào)同時(shí)用串口以1kHz頻率發(fā)出錄一段空載啟動(dòng)到滿載突加的數(shù)據(jù)。保存這組曲線它就是這臺(tái)電機(jī)PI標(biāo)定的最終記錄也是后續(xù)批量接線差異排查的對(duì)照基準(zhǔn)。本文還有配套的精品資源點(diǎn)擊獲取