? ? ? ?去年11月份一次偶然的機(jī)會,看到面包板論壇提供極海半導(dǎo)體針推出的低壓電機(jī)測試板,此電機(jī)控制板基于專用控制芯片APM32F035基礎(chǔ)上設(shè)計而成。APM32F035是一款基于Arm Cortex-M0+內(nèi)核,集成FOC算法中常用的數(shù)學(xué)運(yùn)算加速器(Cordic,Svpwm,硬件除法器等),并且集成了運(yùn)放、比較器等模擬外設(shè),以及CAN控制器的高性能電機(jī)控制專用MCU。
? ? ? ?評估板拿到手后,第一時間用手頭直流無刷電機(jī)測試了下,檢查KEIL版本是否V5.23以上,安裝DEVICE Package ?Geehy.APM32F035_DFP.1.0.0, 同時檢查編譯器里是否含有C99和GNU,如上都準(zhǔn)備好以后,下載重新編譯的hex文件到DEMO板里,首先直接測試有感矢量控制方案程序。啟動后低速時轉(zhuǎn)動有些輕微抖動,速度起來后,轉(zhuǎn)速正常,抖動消除。
低壓電機(jī)通用評估板介紹:
電氣參數(shù):12-72VDC 寬電壓輸入,最大功率100W
支持電機(jī)類型:BLDC.PMSM
支持編碼器類型:霍爾,光電,磁編碼器
通訊接口:SCI/SPI/I2C/C電流采樣方式:單、雙電阻采樣, 三相反電動勢采樣
評估板圖片:
軟件算法平臺介紹:
具體調(diào)試步驟如下:
1.?? ?準(zhǔn)備工作
首先需要先核對板子的硬件是否正常,首次上電后,先拿示波器或萬用表核對硬件板子上各個電壓端點(diǎn)是否穩(wěn)定(12V、5V、3.3V)等,以及測量IV、IU、IBUS等端點(diǎn)是否為直流偏置電(1.60V) 。?同時準(zhǔn)備好無刷直流電機(jī)和燒錄器。
2.?? ?外設(shè)配置
核對電機(jī)的硬件外設(shè)管腳的配置情況,如M0CP協(xié)處理器、TMR1的PWM波形配置、TMR2的捕獲配置、ADC采樣端口配置、運(yùn)放OPA的端口初始化、比較器COMP的配置以及核心點(diǎn)采用COMP與TMR1的級聯(lián)使用剎車功能(即硬件過流保護(hù)功能,細(xì)節(jié)可查閱原理圖)。如下所示:(注:未具體展開各個細(xì)節(jié),需結(jié)合原理圖及各個外設(shè)配置文件進(jìn)行核對。)
3.?? ?電機(jī)參數(shù)配置
前面兩步驟主要是核對硬件及外設(shè)配置,先確保硬件基礎(chǔ)的穩(wěn)定及準(zhǔn)確,而后才開始電機(jī)部分的調(diào)試。 打開“parameter.h”參數(shù)配置文件,此文件是重中之重,基本大部分的修改都在此文件中進(jìn)行,劃重點(diǎn)啦!首先肯定需要先核對電機(jī)的參數(shù)嘛! 此篇章主要介紹的是有感FOC的開發(fā),因此需要核對電機(jī)的極對數(shù)、額定轉(zhuǎn)速、限制電流(結(jié)合電機(jī)的功率考慮)、定標(biāo)轉(zhuǎn)速(結(jié)合額定轉(zhuǎn)速評估)等。如下圖所示。 (注:此處補(bǔ)充下,有感FOC無需使用到觀測器這塊,因此無需用到電機(jī)的相電阻、相電感等參數(shù),而若是無感FOC基本都是需要知道電機(jī)的相電阻、相電感、甚至是反電動勢常數(shù)等)
4.?? ?電流內(nèi)環(huán)的PI參數(shù)進(jìn)行整定確認(rèn)
在Align狀態(tài)中進(jìn)行調(diào)試,調(diào)節(jié)DQ軸下的電流環(huán)PI參數(shù)(如下圖所示,一般DQ軸采用一樣的PI參數(shù)),類似其中的Q軸,通過給定Iq_cmd(可以直接給到值或者采用斜坡給定的方式設(shè)定一定加速度及數(shù)值),通過觀察Vq的輸出是否能快熟穩(wěn)定、以及Iq_cmd及實(shí)際的Iq波形數(shù)據(jù)是否能跟隨上,判斷當(dāng)前的PI參數(shù)是否合適。案例波形如下圖所示。
5.?? ?HALL角度自檢
當(dāng)電流內(nèi)環(huán)PI參數(shù)已經(jīng)合適時,此時說明可以使用預(yù)定位功能,則開啟HALL相序的自檢功能。還是在“parameter.h”參數(shù)配置文件中,打開“HALL_PHASE_TEST”宏參,進(jìn)行HALL相序的自檢功能,在此先介紹下HALL相序的作用,HALL的相位角度差是60°,即其可以輸出六個角度點(diǎn),類似按照正轉(zhuǎn)CW的方式HALL值輸出如2-6-4-5-1-3。(注:可以先自行測試HALL的相序順序是否與程序中給的一致,可以通過手動讓電機(jī)其轉(zhuǎn)動一圈看看實(shí)際讀到的hall值,確認(rèn)hall正轉(zhuǎn)與反轉(zhuǎn)的順序,并將對應(yīng)的hall相序進(jìn)行核對,類似讀出是6-4-5-1-3-2,與上述設(shè)定順序一致則無需修改,而若出現(xiàn)類似6-4-1-5-2-3這種與程序中的順序不相符的,將該順序填入user_function.c中的u8CW_Hall_Value與u8CCW_Hall_Value數(shù)組列表中,同時也需要對應(yīng)填寫下CW_hall_table與CCW_hall_table數(shù)組列表。?
u8CW_Hall_Value[6]:表示實(shí)際的霍爾序列,注意霍爾序列與角度序列的對應(yīng)關(guān)系;?
CW_hall_table[8]:前一個位置的霍爾值序列,例如程序內(nèi)hall:1的前一個位置是hall:5
CW_hall_table[1] = 5,hall:2的前一個位置是hall:3,CW_hall_table[2] = 3?以此類推:u8CW_Hall_Value[6]={ 1,3,2,6,4,5},對應(yīng)CW_hall_table[8]={ 0,5,3,1,6,4,2,0};?u8CW_Hall_Value[6]={ 2,3,1,6,4,5},對應(yīng)CW_hall_table[8]={ 0,3,5,2,6,4,1,0})。
其次,重點(diǎn)又來了哈!實(shí)際HALL傳感器的安裝位置與電機(jī)對應(yīng)的機(jī)器角度間是會有安裝角度偏差的,即機(jī)器角度偏差角,此時HALL相序的自檢功能就是為了計算出該偏差角,并把HALL值對應(yīng)的實(shí)際角度一一匹配上。如下圖所示,開啟“HALL_PHASE_TEST”宏參后進(jìn)入調(diào)試模式,觀察“stc_align_hall”該結(jié)構(gòu)體的相關(guān)成員變量,配置函數(shù)“Align_HallCal_Phase_Init”與“Align_HallCal_Phase”實(shí)現(xiàn),核心參數(shù)修改主要在于定位時間以及定位Iq電流的設(shè)定,以及偏移角度的設(shè)定(若檢測角度異常可適當(dāng)調(diào)節(jié)該值,常用推薦0“0°”或者5461“30°”的偏移角度)。如“stc_align_hall”中的“u8Dir”表示方向,s16CW_arr_HallPhase_Cal 與 s16CCW_arr_HallPhase_Cal是最終生成計算獲取HALL相序角度表,需將其填入user_function.c中的“s16CW_arr_HallPhase”與“s16CCW_arr_HallPhase”數(shù)組列表中。
6.?? ?速度環(huán)參數(shù)整定
當(dāng)已將HALL相序角度表獲取并填入后,需在“parameter.h”參數(shù)配置文件中,先關(guān)閉下“HALL_PHASE_TEST”宏參,關(guān)閉HALL自檢模式,到了這一步,就準(zhǔn)備嘗試讓電機(jī)開始運(yùn)轉(zhuǎn)測試?yán)玻?調(diào)節(jié)硬件板上的轉(zhuǎn)速旋鈕,正常情況下電機(jī)是可以運(yùn)行起來的,若運(yùn)行不起來,此時需要回頭去核對前面的相應(yīng)步驟按點(diǎn)確認(rèn)異常;若可運(yùn)行但是轉(zhuǎn)速不穩(wěn)定,則此時又到重點(diǎn)啦!開始記筆記!當(dāng)轉(zhuǎn)速不穩(wěn)定時,此時需要進(jìn)一步調(diào)節(jié)速度環(huán)的pi參數(shù)以及需要核對電機(jī)給定的加速度是否合理。PI的調(diào)節(jié)還是跟之前調(diào)電流環(huán)PI的模式類似,先調(diào)節(jié)Kp再加入Ki,數(shù)值從小到大進(jìn)行調(diào)試驗證,通過觀測實(shí)際輸出Iq_CMD的穩(wěn)定趨勢、給定的斜坡轉(zhuǎn)速spd_ramp與實(shí)際轉(zhuǎn)速spd_filt的跟隨曲線進(jìn)行判斷參數(shù)的合理性。如下圖所示。
7.?? ?關(guān)鍵參數(shù)設(shè)置
此系統(tǒng)中所有參數(shù)均在用戶層的parameter.h中進(jìn)行配置,主要分為系統(tǒng)參數(shù)、底板相關(guān)參數(shù)、狀態(tài)機(jī)相關(guān)參數(shù)、電機(jī)相關(guān)參數(shù)等。
8.?? ?定制電機(jī)開發(fā)
自此,無刷直流電機(jī)已經(jīng)成功被你運(yùn)轉(zhuǎn)起來啦,接下來的就是依據(jù)你實(shí)際的開發(fā)需求添加應(yīng)用層邏輯等做定制化開發(fā)自己產(chǎn)品功能啦?。?!
總體評價:
整板設(shè)計思路:
? ? ? ? 整體硬件系統(tǒng)是采用外部 24V 電源供電, 并經(jīng)過相應(yīng)的電源降壓電路轉(zhuǎn)換后輸出穩(wěn)定的12V、5V 、3.3V電壓,?其中12V電壓輸出給到Gate driver IC、3.3V電壓輸出給到APM32F035系列微處理器,而功率開關(guān)管則直接使用 24V電源。同時,該方案采用可變電阻旋鈕調(diào)節(jié) 0~3.3V 的電壓輸入作為速度命令的輸入端, 以此調(diào)節(jié)電機(jī)轉(zhuǎn)速。用戶實(shí)際使用可直接通過轉(zhuǎn)動可變電阻旋鈕以此調(diào)節(jié)輸入電壓,同時當(dāng)輸入電壓值超過起動閾值時,電機(jī)將會啟動運(yùn)行,?而當(dāng)電壓值低于閾值時電機(jī)將會關(guān)閉運(yùn)行。當(dāng)電機(jī)啟動后,通過捕獲HALL信號的跳變情況進(jìn)而確認(rèn)六個換相點(diǎn),進(jìn)行對應(yīng)六種不同的逆變器MOS管驅(qū)動順序?qū)崿F(xiàn)BLDC電機(jī)的六步換相。
程序設(shè)計架構(gòu)主要劃分為4層,用戶層、外設(shè)驅(qū)動層、電機(jī)控制驅(qū)動層以及電機(jī)算法層,具體功能描述如下:
1.?? ?用戶層(USER層)
main.c:主函數(shù)入口,負(fù)責(zé)初始化電機(jī)參數(shù)、底層外設(shè)、中斷優(yōu)先級、while循環(huán)及低速狀態(tài)機(jī)
環(huán)路的切換;?
apm32f035_int.c:所有的中斷處理函數(shù),重點(diǎn)包括捕獲中斷函數(shù)、ADC中斷處理函數(shù);?
user_function.c:包括電機(jī)參數(shù)的初始化配置、參數(shù)復(fù)位等處理函數(shù);?
paramete.h:包括了所有的需要配置參數(shù)信息;
2.?? ?外設(shè)驅(qū)動層(HARDWARE層)
外設(shè)驅(qū)動層主要負(fù)責(zé)APM32F035芯片的外設(shè)驅(qū)動函數(shù)及配置,主要涉略包括GPIO、PWM、ADC、OPA、COMP、M0CP協(xié)處理器等
3.?? ?電機(jī)控制驅(qū)動層(MOTOR_CONTROL層)
電機(jī)控制驅(qū)動層主要負(fù)責(zé)電機(jī)的控制運(yùn)行邏輯及核心處理算法調(diào)用。
4.?? ?電機(jī)算法層(Geehy_MCLIB層)
電機(jī)算法層包含坐標(biāo)變換,矢量控制等相關(guān)函數(shù),數(shù)學(xué)庫,HALL角度估算等庫函數(shù)。
經(jīng)過測試發(fā)現(xiàn),此測試板為黑色油墨,電路簡單實(shí)用,版面設(shè)計簡潔明了,布局合理,能滿足中小功率無刷直流電機(jī)的驅(qū)動要求,在上電啟動后,轉(zhuǎn)速很慢時,明顯有卡頓的情況, 轉(zhuǎn)速起來后,卡頓情況消失,這點(diǎn)可能因電機(jī)個體參數(shù)差異,需要調(diào)整PID參數(shù)優(yōu)化控制過程,至于程序代碼部分采用了主狀態(tài)機(jī)嵌套子狀態(tài)機(jī)的結(jié)構(gòu),同時主狀態(tài)RUN的六個子狀態(tài)輪流切換工作。如需開發(fā)自己的項目功能,需要增加自己的功能函數(shù)模塊。
? ? ? ?另外在調(diào)試仿真過程中,不能夠連續(xù)讀取變量參數(shù),不能設(shè)置斷點(diǎn)連續(xù)運(yùn)行,經(jīng)常停止或死機(jī),由于時間問題,沒有詳細(xì)查找原因,不知是芯片底層驅(qū)動的問題還是KEIL 仿真參數(shù)沒設(shè)置正確, 但是使用STM32的芯片仿真調(diào)試時,沒有出現(xiàn)如上同樣問題。以上是個人測試使用過程中遇到的問題,僅代表個人觀點(diǎn),僅供參考。歡迎各位工程師一起學(xué)習(xí)交流。調(diào)試時,沒有出現(xiàn)如上同樣問題。以上是個人測試使用過程中遇到的問題,僅代表個人觀點(diǎn),僅供參考。歡迎各位工程師一起學(xué)習(xí)交流。
代碼部分:
#ifndef __PARAMETER_H_
#define __PARAMETER_H_
/*System setting*/
#define SYS_REFV ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?3.3f ? ? ? // ?unit:v ? ? ?MCU VCC must be 5.0V or 3.3V ? ? ? ??
#define SYSCLK_HSE_72MHz ? ? ? ? ? ? ? ? ? ? ? ? ? ?72000000 ? // ?unit:Hz
#define PWMFREQ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 16000 ? ? ?// ?unit:Hz
#define PWM_PERIOD ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?(SYSCLK_HSE_72MHz/PWMFREQ/2)
#define DEAD_TIME ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? (1.0f * SYSCLK_HSE_72MHz/1000000) ? ? ?// ?unit:us ?
#define SLOWLOOP_FREQ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 1000 ? ? ? // ?unit:Hz
#define SLOWLOOP_FREQ_KHZ ? ? ? ? ? ? ? ? ? ? ? ? ? 1 ? ? ? ? ?// ?uint:Khz
#define TS_Q21 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?(2097152/PWMFREQ) ? // 8kHz:262
/* ?timer2 parameter ? ?*/
#define TIM2_TCY ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?1 ? ? ? //Time base unit of TIM2(us) ?
#define TIM2_PSC_LOAD ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? (SYSCLK_HSE_72MHz/1000000*TIM2_TCY-1) ?//TIM2 Load Value
#define TIM2_PRIOD ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?99999 ? ? ? //TIM2 Period Value
/*Board parameter setting*/
/*Current Sampling*/
#define ADC_REFV ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?SYS_REFV
#define R_SHUNT ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? (0.02f) ? ?// ?unit:ohm
#define CURRENT_OPA_GAIN ? ? ? ? ? ? ? ? ? ? ? ? ? ?(4.86f) ? ?// ?unit:ohm 使用2K/10K電阻組合,結(jié)合內(nèi)部耦合電阻計算得出
#define I_MAX ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? (16.46f) ? // ?偏置1.6V,I_MAX=1.6/Gain/Rs
t ramp_s16(int16_t s16_Cmd,ramp_para_t *pstc)
{
? ? int32_t s32_RefIn;
? ? int16_t s16_Out;
? ? if(s16_Cmd > pstc->s16_Max)
? ? {
? ? ? ? s32_RefIn = pstc->s16_Max << 5;
? ? } else if(s16_Cmd < pstc->s16_Min)
? ? {
? ? ? ? s32_RefIn = pstc->s16_Min << 5;
? ? } else
? ? {
? ? ? ? s32_RefIn = s16_Cmd << 5;
? ? }
? ? if (s32_RefIn != pstc->s32q20_OutTemp)
? ? {
? ? ? ? if (pstc->s32q20_OutTemp > 0 )
? ? ? ? {
? ? ? ? ? ? if (s32_RefIn > pstc->s32q20_OutTemp)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? // 加速
? ? ? ? ? ? ? ? pstc->s32q20_OutTemp += pstc->s16q20_Inc;
? ? ? ? ? ? ? ??
? ? ? ? ? ? ? ? if ( s32_RefIn < pstc->s32q20_OutTemp )
? ? ? ? ? ? ? ? ? ? pstc->s32q20_OutTemp = s32_RefIn;
? ? ? ? ? ? ? ??
? ? ? ? ? ? }else
? ? ? ? ? ? {
? ? ? ? ? ? ? ? // 減速
? ? ? ? ? ? ? ? pstc->s32q20_OutTemp -= pstc->s16q20_Dec;
? ? ? ? ? ? ? ??
? ? ? ? ? ? ? ? if ( s32_RefIn > pstc->s32q20_OutTemp )
? ? ? ? ? ? ? ? ? ? pstc->s32q20_OutTemp = s32_RefIn;
? ? ? ? ? ? ? ??
? ? ? ? ? ? } ? ? ? ? ? ?
? ? ? ? }else if(pstc->s32q20_OutTemp < 0)
? ? ? ? {
? ? ? ? ? ? if (s32_RefIn < pstc->s32q20_OutTemp){
? ? ? ? ? ? ? ? // 加速
? ? ? ? ? ? ? ? pstc->s32q20_OutTemp -= pstc->s16q20_Inc;
? ? ? ? ? ? ? ? ??
? ? ? ? ? ? ? ? if ( s32_RefIn > pstc->s32q20_OutTemp )
? ? ? ? ? ? ? ? ? ? pstc->s32q20_OutTemp = s32_RefIn;
? ? ? ? ? ? ? ??
? ? ? ? ? ? }else
? ? ? ? ? ? {
? ? ? ? ? ? ? ? // 減速
? ? ? ? ? ? ? ? pstc->s32q20_OutTemp += pstc->s16q20_Dec;
? ? ? ? ? ? ? ??
? ? ? ? ? ? ? ? if ( s32_RefIn < pstc->s32q20_OutTemp )
? ? ? ? ? ? ? ? ? ? pstc->s32q20_OutTemp = s32_RefIn;
? ? ? ? ? ? ? ??
? ? ? ? ? ? } ??
? ? ? ? }else
? ? ? ? {
? ? ? ? ? ? if (s32_RefIn < pstc->s32q20_OutTemp)
? ? ? ? ? ? {
? ? ? ? ? ? ? ? // 加速
? ? ? ? ? ? ? ? pstc->s32q20_OutTemp -= pstc->s16q20_Inc;
? ? ? ? ? ? ? ? if ( s32_RefIn > pstc->s32q20_OutTemp )
? ? ? ? ? ? ? ? ? ? pstc->s32q20_OutTemp = s32_RefIn;
? ? ? ? ? ? }else
? ? ? ? ? ? {
? ? ? ? ? ? ? ? // 加速
? ? ? ? ? ? ? ? pstc->s32q20_OutTemp += pstc->s16q20_Inc;
? ? ? ? ? ? ? ??
? ? ? ? ? ? ? ? if ( s32_RefIn < pstc->s32q20_OutTemp )
? ? ? ? ? ? ? ? ? ? pstc->s32q20_OutTemp = s32_RefIn;
? ? ? ? ? ? ? ??
? ? ? ? ? ? } ?
? ? ? ? }
? ? }
? ? s16_Out = pstc->s32q20_OutTemp >> 5;
? ? return s16_Out;
}
int main(void)
{
? ? __disable_irq(); ? ? ? ? ? ? ? ? ? ? ? ? ??
? ? /* ?config peripherals ?*/
? ? MC_SystemClockInit();
? ? /* ?M0CP ? ?*/
? ? M0CP_Firmware_Init();
? ? RCM_EnableAHBPeriphReset(RCM_AHB_PERIPH_M0CP);
? ? RCM_DisableAHBPeriphReset(RCM_AHB_PERIPH_M0CP);
? ? RCM_EnableAHBPeriphClock(RCM_AHB_PERIPH_M0CP);
? ? M0CP_HardInit();
? ? *(volatile unsigned int*)(0x40024000+0x10) = 0;
? ? /* ?TIMER1 ? ? ?*/
? ? Drv_Pwm_Init(PWM_PERIOD,DEAD_TIME);
? ? PWM_CompareConfig(PWM_PERIOD, PWM_PERIOD, PWM_PERIOD);
? ? /* ?TIMER2 for hall capture ? ? */
? ? timer2_init(TIM2_PRIOD, TIM2_PSC_LOAD); ? ?//100ms
? ? /* ?ADC ? ? ?*/
? ? Drv_Adc_Init();
? ? /* ?OPA ? ? ?*/
? ? OPA_Init();
? ? /* ?COMP ? ? ?*/
? ? COMP_Init();
? ? /* ?GPIO ? ? ?*/
? ? IO_Init();
? ? /* ?SYSTICK ? ? ?*/
? ? Systick_Init(SystemCoreClock / 1000);
? ? /* Initialize ?motor control parameters */
? ? Init_Parameter(&Motor_type);
? ? /* Initialize interrupts */
? ? Interrupt_Init();?
? ? /* Wait until ADC is ready */
? ? while (!ADC_ReadStatusFlag(ADC_FLAG_ADRDY));
? ? ADC_StartConversion();
? ? WWDTInit();
? ? __enable_irq(); ? ? ? ? ? ? ? ? ? ? ? ? ? ? //Enable all interrupts
? ? TMR_EnablePWMOutputs(TMR1);
? ??
? ? while (1)
? ? {
? ? ? ? if(Motor_type.User.bSlowLoopFlag)
? ? ? ? {
? ? ? ? ? ? WWDTFeedDog();
? ? ? ? ? ? /* Slow Loop Statemachine */
? ? ? ? ? ? s_STATE_SLOW[eM1_MainState]();
? ? ? ? ? ? Motor_type.User.bSlowLoopFlag = ?0;
? ? ? ? }
? ? }
}
由于代碼部分較長,不再一一貼出來,如有如要,留言聯(lián)系我,可以提供相關(guān)資料或站內(nèi)其他帖子內(nèi)下載,另外提醒所提供資料僅供學(xué)習(xí)使用。
實(shí)際測試波形:文章來源:http://www.zghlxwxcb.cn/news/detail-777437.html
文章來源地址http://www.zghlxwxcb.cn/news/detail-777437.html
到了這里,關(guān)于極海APM32F035電機(jī)控制專用MCU的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!