最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

如何在 MCSDK 5.x 中增加絕對位置編碼器

2019-10-28 12:27 作者:電堂科技  | 我要投稿

在“AI電堂”微信公眾號回復(fù)“SPI”,獲得示例代碼下載鏈接


當(dāng)前MC SDK5.x中支持的關(guān)于編碼器(Encoder)為增量編碼器,即有A,B,Z信號的編碼器,主要為光編碼器;在市場中有些應(yīng)用(比如無人機云臺,伺服,醫(yī)療)已經(jīng)在廣泛使用磁編碼器,輸出的是絕對位置,而想取得位置信息,或者通過取樣絕對位置傳感的PWM脈寬,或者需要通過通訊方式進(jìn)行獲取,比如SPI,I2C,UART等等;當(dāng)前MC SDK5.x還未對這個部分直接支持,需要通過修改程序?qū)崿F(xiàn)絕對位置編碼器的應(yīng)用,本文使用STM32F303RE-Nucleo控制說明。


絕對位置編碼器使用簡介


當(dāng)導(dǎo)體通電后放入磁場中,由于磁場的作用導(dǎo)體上流動的電荷就會因為受到由磁場感應(yīng)產(chǎn)生的洛倫茲力而發(fā)生流通路徑的偏移,這樣在垂直于電流方向上如果去測量的Y1,Y2點電壓,將產(chǎn)生電勢差,這個就是所說的霍爾效應(yīng);如果使用ADC對Y1,Y2點進(jìn)行測量標(biāo)定即可以反推磁場變化;


打開有絕對位置編碼器的電機可以看到轉(zhuǎn)子上有一個同步旋轉(zhuǎn)的磁石,同時有檢測芯片用于絕對角度輸出,絕對位置編碼器芯片輸出PWM波或者內(nèi)部做通訊輸出,單片機可以讀取相關(guān)信息得到到當(dāng)前轉(zhuǎn)子的角度。


1. 準(zhǔn)備工作


為了方便調(diào)試,首先使用無傳感控制(Sensor-less)將電機閉環(huán)運行起來,如果電機合適,并且使用的是ST的電機Demo板,可以使用ST的Motor Profiler(30KHzPWM)進(jìn)行無傳感電機參數(shù)以及轉(zhuǎn)動參數(shù)識別,可以很快將電機無傳感轉(zhuǎn)動起來;


如果使用客戶自制板子,則按照ST的操作說明,使用MCWorkbench將電機閉環(huán)無傳感轉(zhuǎn)動起來,電機閉環(huán)轉(zhuǎn)動過程可以確保硬件軟件的完備性;注意這邊生成的CubeMx工程文件*.ioc文件,后面我們添加程序會使用到;


為了便于調(diào)試可增加兩路DAC,比如使用STM32F303則直接使用兩路輸出的DAC,如果該芯片上沒有DAC模塊,可以使用TIMER+RC濾波電路模擬輸出DAC;下圖為使用DAC配置,需要配置為Userdefined DAC1/2。


絕對編碼器芯片角度信息讀取


絕對編碼器的輸出可以為PWM波形輸出,也可以為通訊端口輸出,比如UART,SPI,I2C等等,本文以SPI輸出以及PWM輸出為例做說明


2. 角度以及速度標(biāo)定

2.1 電角度標(biāo)定


因為我們讀取的角度為機械角度,在控制過程中我們用到的是電角度,因此還要做一下變換,將機械角度數(shù)據(jù)變?yōu)殡娊嵌葦?shù) 據(jù);使用公式為:

在程序中需要量化為Q16格式后得到電角度范圍[?180°~180°];即[-32768~32767]

2.2 速度計算

3. 編碼器SPI輸出模式

3.1 CubeMx配置


打開MCWorkbench生成的*.ioc文件,配置SPI模塊,這邊我們使用SPI3接收,配置參數(shù)需要參考編碼器芯片的說明,這 邊以AS5048A為例,如下配置,配置PB10作為片選信號CS輸出



3.2 重新生成代碼



3.3 編寫SPI讀取代碼


根據(jù)編碼器芯片的數(shù)據(jù)手冊編寫SPI讀取代碼,調(diào)試代碼以便讀取到角度信息,因為是外設(shè)配置,本文對此部分不做具體說明;可以參考spi_pwm_encoder.c文件,得到角度信息后進(jìn)行機械角度轉(zhuǎn)變?yōu)殡娊嵌鹊挠嬎悖?/p>

#define ENCODER_SPI_MAX 16384?

#define POLES 11?

/*?

* Calculate electrical angle based on motor, data in Q16 format?

* 16384 stand for 360degree(65536)*motor poles?

*/?

SPI_EIAngle = (int16_t)((65536*SPI_Angle_Digital*POLES)/ENCODER_SPI_MAX)%65536;


SPI_Angle_Digital為通過SPI讀取的電角度數(shù)字量,ENCODER_SPI_MAX為最大數(shù)字量輸出,比如14-bit精度的輸出,這個數(shù)據(jù)為16384。


3.4 創(chuàng)建絕對值編碼器的結(jié)構(gòu)體


創(chuàng)建結(jié)構(gòu)體,包含SpeednPosFdbk_Handle_t的通用組件,并且定義私有成員變量,用于絕對位置編碼器的控制以及參量計算,在abs_encoder_pos_fdbk.c中進(jìn)行初始化動作。

/** ?

?* @brief Abs encoder component parameters definition ?

?*/ ?

?typedef struct


{ ? ? ??

? ? ? SpeednPosFdbk_Handle_t _Super; ? ? ?

? ? ? int16_t Encoder_EIAngle; /* Encoder final electrical angle */? ? ? ? ? ? ? int16_t Encoder_MecAngle; /* Encoder final mechanical angle */? ? ? ? ? ? ? int16_t Encoder_AngleD_Pre; /* Encoder previous digital angle */? ? ? ? ? ? int16_t Encoder_AngleD_Now; /* Encoder present/now digital angle */? ? ? ? ? int16_t Encoder_Speed_RPM; /* Speed uint in RPM */ ? ? ??

? ? ? int16_t Encoder_Average_Speed_RPM; /* Average speed unit in RPM*/ ? ? ? ? ? bool SensorIsReliable; ? ? ?

? ? ? uint8_t mode; ? ? ? ? ? ??

? ? ? int32_t Circle_Counter; /* Count the circle for motro run */? ? ? ? ? ? ? bool Middle_Flag; /* Middle flag, 1--arrived pass middle*/ ? ? ??

} Abs_Encoder_Handle_t;


3.5 絕對值編碼器函數(shù)編寫


參照encoder_speed_pos_fdbk.c文件編寫對應(yīng)的絕對值編碼器的代碼,接口函數(shù)對應(yīng)起來,這樣可以有效的集成擴展, 分別定義:

1) 初始化函數(shù)Abs_Encoder_Init

2) 清除函數(shù)Abs_Encoder_Clear

3) 絕對值編碼器讀取電角度函數(shù)Abs_Encoder_GetElAngle

4) 讀取機械角度函數(shù)Abs_Encoder_GetMecAngle

5) 得到電機平均機械速度函數(shù) Abs_Encoder_GetAvrgMecSpeed01Hz

6) 計算電機平均機械速度函數(shù) Abs_Encoder_CalcAvrgMecSpeed01Hz


3.6 添加絕對位置編碼器代碼

3.6.1 絕對位置編碼器速度計算


參照2.2公式進(jìn)行速度計算

/* Speed_RPM = Deta(angle)*60*f/65536 */?

pHandle->Encoder_Speed_RPM = (int16_t)((int32_t)(pHandle->Encoder_AngleD_Now - pHandle- >Encoder_AngleD_Pre * 60 * SPEED_LOOP_FREQUENCY_HZ/65536);


3.6.2 添加編碼器初始化代碼


在mc_task.c文件的MCboot()函數(shù)中增加初始化代碼

Abs_Encoder_Init(&Abs_Encoder_M1); // Initial absolute encoder sensor Abs_Encoder_M1.mode = SENSOR_SPI;


3.6.3 角度以及速度的代碼添加


中頻任務(wù)TSK_MediumFrequencyTaskM1中加入絕對編碼器的角度以及速度計算函數(shù)

Abs_Encoder_CalcAvrgMecSpeed01Hz(&Abs_Encoder_M1, &wAux );


3.7 判斷絕對位置編碼器角度準(zhǔn)確性


使用DAC對角度進(jìn)行判讀,在mc_task.c中TSK_HighFrequencyTask()函數(shù)中增加UserDAC數(shù)據(jù)更新,一個DAC輸出無 傳感觀測器輸出的電角度,另外一路輸出絕對值編碼器計算出的電角度。

/* DAC output*/?

extern UI_Handle_t * pDAC;?

static int16_t temp1;?

static int16_t temp2;?

temp1 = FOCVars[M1].hElAngle;?

temp2 = Abs_Encoder_M1.Encoder_EIAngle;?

DAC_SetUserChannelValue(pDAC, DAC_USER1, temp1);?

DAC_SetUserChannelValue(pDAC, DAC_USER2, temp2);

程序修改完成后編譯下載,讓電機工作在無傳感閉環(huán)模式,示波器連接DAC兩路輸出。

如果出現(xiàn)下面波形,則需要交換其中任意兩條電機線,或者在程序中加入負(fù)號即可;


下面的圖為正確的DAC輸出波形,可以看到黃色為無傳感器觀測器輸出電角度,藍(lán)色為計算得到的絕對位置編碼器輸出計算結(jié)果,兩者基本重合,如果出現(xiàn)吻合度非常差,波形錯開很多情況下,有兩種措施,要么和電機廠商溝通做準(zhǔn)確的零點校準(zhǔn), 要么自行增加角度補償。



3.8 絕對位置角度閉環(huán)程序修改

3.8.1 修改電角度賦值


修改mc_task.c中TSK_MediumFrequencyTaskM1()函數(shù),由無傳感方式獲得電角度改為絕對位置編碼器的轉(zhuǎn)換完成的電角度,并且返回對應(yīng)的速度值;

#if defined(ABS_ENCODER_MODE)? ? ? ? ? ? ? ? ? ? ? ? ?Abs_Encoder_CalcAvrgMecSpeed01Hz(&Abs_Encoder_M1, &wAux ); ? ? ?IsSpeedReliable = 1;

#else ? ? ?

?Abs_Encoder_CalcAvrgMecSpeed01Hz(&Abs_Encoder_M1, &wAux ); ? ? ?IsSpeedReliable = STO_PLL_CalcAvrgMecSpeedUnit( &STO_PLL_M1, &wAux );?

#endif


3.8.2 屏蔽無傳感電角度計算


修改 mc_task.c 中 TSK_HighFrequencyTask() 函數(shù),只保留MC_FOC_DURATION這個判斷,其他都可以屏蔽掉。

hFOCreturn = FOC_CurrController(M1);?

if(hFOCreturn == MC_FOC_DURATION)?

{ ??

? ?STM_FaultProcessing(&STM[M1], MC_FOC_DURATION, 0);?

}


3.8.3 修改速度傳感器為絕對編碼傳感器


修改 mc_task.c 中 TSK_MediumFrequencyTaskM1()函數(shù),傳感器設(shè)定修改為絕對編碼器。

case CLEAR: ?

? FOCVars[M1].bDriveInput = INTERNAL; ?

? STC_SetSpeedSensor( pSTC[M1], &Abs_Encoder_M1._Super ); ?

? if ( STM_NextState( &STM[M1], START ) == true ) ?

? { ? ?

? ?FOC_Clear( M1 ); ? ?

? ?R3_2_SwitchOnPWM( pwmcHandle[M1] ); ??

? ?} ?

? ?break;


3.8.4 修改狀態(tài)跳轉(zhuǎn)


因為開始就直接是閉環(huán)運行,因此需要修改mc_task.c中TSK_MediumFrequencyTaskM1()函數(shù),狀態(tài)START下,只需要一條跳轉(zhuǎn)語句,其他刪除或者屏蔽掉。

case START: ? ??

? ?STM_NextState( &STM[M1], START_RUN );

break ;

同樣在狀態(tài)START_RUN下,也只需要一條跳轉(zhuǎn)語句。

case START_RUN: ? ?

? ?STM_NextState( &STM[M1], RUN );?

break ;


3.9 絕對編碼器力


以上修改完成后,重新編譯下載后就可以直接運行電機了,電機需要工作在力矩模式,如果使用GUI進(jìn)行控制,則切換到Torque模式,同時設(shè)定Iqref數(shù)據(jù),500這個數(shù)據(jù)計算來自于電機最大支持電流數(shù)字量(比如5000)的10%,可以逐漸增加這個數(shù)據(jù),直到電機能夠運轉(zhuǎn)起來。



如果程序控制電機運行則可以寫為下面代碼

MC_ProgramTorqueRampMotor1(500,1000);?

MC_StartMotor1();

3.10 絕對編碼器速度閉環(huán)運行電機


速度輸出已經(jīng)在上面的中頻任務(wù)中計算得到,可以在無傳感模式下對編碼器速度輸出做調(diào)試,看輸出速度是否和無傳感匹配,如果匹配后可以轉(zhuǎn)入絕對編碼器的速度閉環(huán)控制


如果程序控制電機運行則可以寫為下面代碼:

MC_ProgramSpeedRampMotor1 (600/6,1000); // 600RPM?

MC_StartMotor1();


3.11 使用絕對編碼器做位置環(huán)

3.11.1 框架說明


以表貼電機為例,一般的FOC電機控制是兩環(huán)控制,速度環(huán)+電流環(huán)的控制方式,速度環(huán)為外環(huán),電流環(huán)為內(nèi)環(huán),Idref = 0(d軸電流參考為0)的控制為常見控制;參考速度環(huán)輸出參考轉(zhuǎn)矩后供后端電流環(huán)路;


如果增加位置環(huán)最簡單和直接的方式即為將速度環(huán)換為位置環(huán),即變?yōu)槲恢铆h(huán)+電流環(huán)的方式:


3.11.2 計算說明


為了方便控制,以及考慮精度問題,角度單位為rad*10000,比如電機轉(zhuǎn)動10圈,也就是10圈后的位置,則該位置的設(shè)定角度為:

? ? ? ? ? ?θset=10?2???10000≈628320

位置環(huán)采用的是線性系數(shù)乘以系數(shù)直接輸出到速度的參考:

? ? ? ? ? ??re??=?????(?????????)

? ? ? ? ? ??????位置環(huán)系數(shù)

? ? ? ? ? ????? ?設(shè)定的位置

? ? ? ? ? ??????當(dāng)前的位置

當(dāng)前位置的角度數(shù)字量計算如下:

? ? ? ? ? ????=???????2??????10000+????

? ? ? ? ??????? –絕對值編碼器轉(zhuǎn)過的整圈數(shù)

? ? ? ? ??????當(dāng)前的機械角度的數(shù)字量

? ? ? ? ????? ?取值3.1416


3.11.3 位置控制改進(jìn)


在三環(huán)控制中,不可避免的會涉及到加速度的計算,正??刂七^程為:加速、勻速、減速、定位過程。


那么會涉及到加速度以及定位階段的控制,這邊我們可以按照加速度與速度差成反比,而定位階段可以直接設(shè)定速度為0,但是實際使用過程中我們會發(fā)現(xiàn)直接直接的速度模式在定位階段力量有限。


方法一:PID 需要特別設(shè)定,更能夠定位到給定位置;

方法二:拋開速度環(huán),直接力矩控制;


3.11.4 增加以下變量或函數(shù)用于位置環(huán)控制


1) 位置環(huán)PID 結(jié)構(gòu)體PID_Handle_t PIDAngleHandle_M1

2) 位置控制的結(jié)構(gòu)體Position_Handle_t

3) 位置角度誤差Position_GetErrorAngle

4) 位置環(huán)速度參考輸出計算Position_CalcSpeedReferrence

5) 位置環(huán)力矩參考輸出計算Position_CalcTorqueReferrence


3.11.5 增加位置控制程序


在mc_task.c的中頻任務(wù)函數(shù)TSK_MediumFrequencyTaskM1中增加位置環(huán)差值數(shù)據(jù)計算,根據(jù)差值計算,當(dāng)差值在閾值之上的話進(jìn)行速度控制,在RUN下調(diào)用下面函數(shù):

/* Get error position/Angle, unit in rad*10000 */ Position_GetErrorAngle(&Abs_Encoder_M1,Target_Angle);?

……?

Position_CalcSpeedReferrence()

如果差值縮小到一定范圍內(nèi),則進(jìn)行力矩控制,在函數(shù)FOC_CalcCurrRef中進(jìn)行調(diào)用。

__weak void FOC_CalcCurrRef(uint8_t bMotor)?

{ ? ? ??

? ? ? if(FOCVars[bMotor].bDriveInput == INTERNAL) ? ? ??

? ? ? { ? ? ??

? ? ? #if defined(POSITION_CONTROL) ? ? ? ? ? ??

? ? ? ? ?/* If in position torque mode, Iqref come from Angle PID*/? ? ? ? ? ? ? ? if(Position_M1.Mode_Flag == P_TORQUE_MODE) ? ? ? ? ? ??

? ? ? ? ?{ ? ? ? ? ? ? ? ? ??

? ? ? ? ? ? ?FOCVars[bMotor].hTeref = Position_CalcTorqueReferrence(); ? ? ? ? ? ? ? ?FOCVars[bMotor].Iqdref.q = FOCVars[bMotor].hTeref;? ? ? ? ? ? ? ? ? } ? ? ? ? ? ??

? ? ? ? ?else ? ? ??

? ? ? #endif ? ? ? ? ? ??

? ? ? ? ?{ ? ? ? ? ? ? ? ? ?

? ? ? ? ? ? FOCVars[bMotor].hTeref=STC_CalcTorqueReference(pSTC[bMotor]);? ? ? ? ? ? ? FOCVars[bMotor].Iqdref.q = FOCVars[bMotor].hTeref;? ? ? ? ? ? ? ? ? ? } ? ? ? ?

? ? ? ?}?

}


3.11.6 實際運行效果


位置偏差較大時,電機加速到最大速度,偏差小時將進(jìn)入力矩控制模式,直到目標(biāo)位置,在目標(biāo)位置直接力矩鎖定。


設(shè)定位置角度值在0<- ->15708000(電機轉(zhuǎn)動250圈) 實際速度與參考速度曲線。



3.12 測試說明


spi_pwm_encoder.h中提供了測試宏定義

A,無傳感運行,用于測試絕對值編碼器,如下宏定義

//#define ABS_ENCODER_MODE?

//#define POSITION_CONTROL?

#define ENCODER_SPI_MODE?

//#define ENCODER_PWM_MODE


B,絕對值編碼器,SPI輸出模式的閉環(huán)運行

#define ABS_ENCODER_MODE?

//#define POSITION_CONTROL?

#define ENCODER_SPI_MODE?

//#define ENCODER_PWM_MODE


C,加入位置環(huán)后的三環(huán)運行

#define ABS_ENCODER_MODE?

#define POSITION_CONTROL?

?#define ENCODER_SPI_MODE?

//#define ENCODER_PWM_MODE


4. 編碼器PWM輸出模式


一般編碼器的PWM都是以固定頻率輸出,占空比代表角度,Duty的范圍為0—T,也就是0—360度(機械角度);



4.1 CubeMx配置


編碼器的PWM輸出可以直接使用ST芯片的TIMER PWM捕獲功能獲取PWM波的頻率(用于計算電角度)和占空比(機械角度信息);這邊我們使用TIM2;打開MC workbench生成的*.ioc文件,修改TIM2為PWM捕獲輸入:


將TIM2捕獲輸入通道1配置為Rising Edge,通道2為間接捕獲輸入(實際是TIM2_CH1的內(nèi)部輸出),配置為Falling Edge,同時我們看到PA15(TIM2_CH1)已經(jīng)被配置;通道1為頻率捕獲,通道2為占空比捕獲;



使能TIM2中斷



編輯中斷優(yōu)先級


因為TIM2中斷不能妨礙電機運行,因此需要修改中斷優(yōu)先級為搶占等級為3


4.2 重新生成代碼


在生成代碼的main.c中增加通道使能代碼,TIM2(32-bit)工作在72MHz,如果默認(rèn)編碼器1K PWM,CCR1計數(shù)數(shù)值為 72MHz/1KHz = 72000

/* In PWM mode, use Tim2 PWM capture mode to get frequency and duty cycle,?

* CCR1 value is the frequency of PWM, can be used as calibration value.?

* CCR2 value is for digital angle?

* In this demo, TIM2 work under 72MHz?

*/?

HAL_TIM_Base_Start(&htim2);

HAL_TIM_IC_Start(&htim2,TIM_CHANNEL_1);?

HAL_TIM_IC_Start_IT(&htim2,TIM_CHANNEL_2);


4.3 編寫電角度轉(zhuǎn)換讀取代碼


void PWM_Encoder_EIangle(uint32_t data)?

{ ? ? ?

? ? ?PWM_Angle_Digital = data; ? ? ?

? ? ?if(PWM_Angle_Digital > ENCODER_PWM_MAX)? ? ? ? ? ??

? ? ? ? ? PWM_Angle_Digital = ENCODER_PWM_MAX; ? ? ?

? ?PWM_EIAngle= (int16_t((65536*PWM_Angle_Digital*POLES)/ENCODER_PWM_MAX)%65536; }

在TIM2的中斷服務(wù)中讀取CCR2寄存器內(nèi)容,為防止誤動作,這邊CCR1數(shù)據(jù)標(biāo)定為ENCODER_PWM_MAX,可以仿真條件下讀取這個數(shù)據(jù),如果編碼器準(zhǔn)確1KHz PWM輸出這個數(shù)據(jù)為72000,如果為其他數(shù)據(jù)可以進(jìn)行對應(yīng)修改;

#define ENCODER_PWM_MAX 67039 //72000?

void TIM2_IRQHandler(void)?

{ ? ?

? ? PWM_Encoder_EIangle(TIM2->CCR2); ? ?

? ? Encoder_EIAngle = PWM_EIAngle; ? ?

? ? Encoder_MecAngle = (int16_t)(PWM_Angle_Digital*65536/ENCODER_PWM_MAX);?

}


4.4 判斷絕對位置編碼器角度準(zhǔn)確性

同3.7所描述


4.5 絕對位置角度閉環(huán)程序修改

同3.8,3.9,3.10的描述


4.6使用絕對編碼器做位置環(huán)

參照 3.11 中的具體操作


如何在 MCSDK 5.x 中增加絕對位置編碼器的評論 (共 條)

分享到微博請遵守國家法律
冷水江市| 泸西县| 淮南市| 石河子市| 清水河县| 汶上县| 平远县| 莲花县| 延津县| 麻栗坡县| 刚察县| 漯河市| 望江县| 新郑市| 灵璧县| 舞钢市| 广德县| 洛南县| 赫章县| 长春市| 读书| 庆阳市| 永仁县| 治县。| 依安县| 嘉义市| 灌阳县| 富锦市| 宁强县| 沂南县| 广西| 余姚市| 南雄市| 岑巩县| 察哈| 竹山县| 津南区| 汉川市| 棋牌| 上饶市| 昌宁县|