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

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

四、手寫STM32 FOC記錄-----FOC + SVPWM

2023-09-02 15:07 作者:茄子土豆地三鮮  | 我要投稿

FOC控制算法框圖:



????????咋一看FOC控制框圖可能會發(fā)現(xiàn)不知道從哪入手,可以回想一下直流有刷電機的學習過程,首先是讓電機轉(zhuǎn)起來,然后進行速度控制,再進一步進行位置控制,同樣我們在FOC學習過程中依然可以這樣做,我們首先將位置環(huán)和速度環(huán)甚至是電流環(huán)去掉,然后就剩下SVPWM,既然只是讓電機轉(zhuǎn)起來那么電流檢測也不需要了,我們就直接給電壓,開環(huán)運行,這時候控制框架就能簡化成下圖所示。

????????逐一實現(xiàn)框圖中的每一個模塊,首先是Park逆變換,將DQ坐標系轉(zhuǎn)換成αβ坐標系,如下:


????????用C語言代碼實現(xiàn)它:

/**********************************************************************************************************

park逆變換,輸入Uq、Ud得到Ualpha、Ubeta

Uα = Ud · cosθ - Uq · sinθ

Uβ = Ud · sinθ + Uq · cosθ

**********************************************************************************************************/

void inverseParkTransform(DQ_Def *dq, AlphaBeta_Def *alphaBeta, float angle)

{

????float cosAngle = cos(angle);

????float sinAngle = sin(angle);

?

????alphaBeta->alpha = dq->d * cosAngle - dq->q * sinAngle;

????alphaBeta->beta = dq->d * sinAngle + dq->q * cosAngle;

}

????????接下來便是FOC控制最復雜也是最難理解的一部分SVPWM,不介紹SVPWM原理,網(wǎng)上關(guān)于SVPWM的資料超級多,需要的時候自行查閱。這里只針對我的理解,結(jié)合我編寫的代碼來說明具體的實現(xiàn)過程。

????????第一步,計算u1、u2、u3。通過park逆變換得到的alpha,beta,計算得出u1、u2和u3,我理解這個其實是克拉克逆變換

????????第二步,扇區(qū)判斷。根據(jù)u1、u2和u3的正負情況確定所處的扇區(qū)。根據(jù)U1,U2,U3的符號計算N=4C+2B+A,再結(jié)合扇區(qū)表判斷所處的扇區(qū),N的取值和所對應的扇區(qū)關(guān)系如下表:


????????第三步,計算基本矢量電壓作用時間(占空比),根據(jù)扇區(qū)確定相鄰兩個基本矢量電壓及其作用時間,然后對作用時間進行等比例縮小處理,使得總的作用時間等于Ts采樣時間,或總的占空比等于1,這樣計算出來的數(shù)據(jù)ta,tb,tc就是占空比,正好與PWM的輸出對應。這部分相對較復雜,這里不做描述,請查閱專業(yè)的資料。推薦一篇博客:https://blog.csdn.net/weixin_42887190/article/details/125464343

????????第四步,6路PWM輸出,根據(jù)a,b,c三項占空比,計算PWM輸出,驅(qū)動電機轉(zhuǎn)動,這個很簡單,就是用占空比乘以PWM周期,編寫set_PWM_value函數(shù)如下:



void set_PWM_value(uint16_t pwm_u,uint16_t pwm_v,uint16_t pwm_w)

{

__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_1, pwm_u); ?

__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_2, pwm_v);

__HAL_TIM_SET_COMPARE(&htim1, TIM_CHANNEL_3, pwm_w);

?

}


至此SVPWM完成,現(xiàn)將完整的SVPWM代碼粘貼進來:

/**********************************************************************************************************

將坐標變換中的反Park變換得到的 Valpha 、Vbeta 轉(zhuǎn)換六路PWM輸出。

?

**********************************************************************************************************/

void SVPWM(AlphaBeta_Def *U_alphaBeta, SVPWM_Def *svpwm)

{

????float sum;

????float k_svpwm;

????

????svpwm->Ts = 1.0f; // SVPWM的采樣周期

?

????svpwm->U_alpha = U_alphaBeta->alpha;

????svpwm->U_beta = U_alphaBeta->beta;

?

??// step1 計算u1、u2和u3

????// 計算SVPWM算法中的三個控制電壓u1、u2和u3

????svpwm->u1 = U_alphaBeta->beta;

????svpwm->u2 = -0.8660254f * U_alphaBeta->alpha - 0.5f * U_alphaBeta->beta; // sqrt(3)/2 ≈ 0.86603

????svpwm->u3 = 0.8660254f * U_alphaBeta->alpha - 0.5f * U_alphaBeta->beta;

?// step2:扇區(qū)判斷

????// 根據(jù)u1、u2和u3的正負情況確定所處的扇區(qū)

????svpwm->sector = (svpwm->u1 > 0.0f) + ((svpwm->u2 > 0.0f) << 1) + ((svpwm->u3 > 0.0f) << 2); // N=4*C+2*B+A


????// step3:計算基本矢量電壓作用時間(占空比)

????// 根據(jù)扇區(qū)的不同,計算對應的t_a、t_b和t_c的值,表示生成的三相電壓的時間

????switch (svpwm->sector)

????{

????case 5:

????????// 扇區(qū)5

????????svpwm->t4 = svpwm->u3;

????????svpwm->t6 = svpwm->u1;

????????sum = svpwm->t4 + svpwm->t6;

????????if (sum > svpwm->Ts)

????????{

????????????k_svpwm = svpwm->Ts / sum; //

????????????svpwm->t4 = k_svpwm * svpwm->t4;

????????????svpwm->t6 = k_svpwm * svpwm->t6;

????????}

????????svpwm->t7 = (svpwm->Ts - svpwm->t4 - svpwm->t6) / 2;

????????svpwm->ta = svpwm->t4 + svpwm->t6 + svpwm->t7;

????????svpwm->tb = svpwm->t6 + svpwm->t7;

????????svpwm->tc = svpwm->t7;

????????break;

??????case 1:

????????// 扇區(qū)1

????????svpwm->t2 = -svpwm->u3;

????????svpwm->t6 = -svpwm->u2;

????????sum = svpwm->t2 + svpwm->t6;

????????if (sum > svpwm->Ts)

????????{

????????????k_svpwm = svpwm->Ts / sum; // 計算縮放系數(shù)

????????????svpwm->t2 = k_svpwm * svpwm->t2;

????????????svpwm->t6 = k_svpwm * svpwm->t6;

????????}

????????svpwm->t7 = (svpwm->Ts - svpwm->t2 - svpwm->t6) / 2;

????????svpwm->ta = svpwm->t6 + svpwm->t7;

????????svpwm->tb = svpwm->t2 + svpwm->t6 + svpwm->t7;

????????svpwm->tc = svpwm->t7;

????????break;

????case 3:

????????// 扇區(qū)3

????????svpwm->t2 = svpwm->u1;

????????svpwm->t3 = svpwm->u2;

????????sum = svpwm->t2 + svpwm->t3;

????????if (sum > svpwm->Ts)

????????{

????????????k_svpwm = svpwm->Ts / sum; //

????????????svpwm->t2 = k_svpwm * svpwm->t2;

????????????svpwm->t3 = k_svpwm * svpwm->t3;

????????}

????????svpwm->t7 = (svpwm->Ts - svpwm->t2 - svpwm->t3) / 2;

????????svpwm->ta = svpwm->t7;

????????svpwm->tb = svpwm->t2 + svpwm->t3 + svpwm->t7;

????????svpwm->tc = svpwm->t3 + svpwm->t7; ???

????????break;

?

????case 2:

????????// 扇區(qū)2

????????svpwm->t1 = -svpwm->u1;

????????svpwm->t3 = -svpwm->u3;

????????sum = svpwm->t1 + svpwm->t3;

????????if (sum > svpwm->Ts)

????????{

????????????k_svpwm = svpwm->Ts / sum; //

????????????svpwm->t1 = k_svpwm * svpwm->t1;

????????????svpwm->t3 = k_svpwm * svpwm->t3;

????????}

????????svpwm->t7 = (svpwm->Ts - svpwm->t1 - svpwm->t3) / 2;

????????svpwm->ta = svpwm->t7;

????????svpwm->tb = svpwm->t3 + svpwm->t7;

????????svpwm->tc = svpwm->t1 + svpwm->t3 + svpwm->t7; ???

????????break;

?

????case 6:

????????// 扇區(qū)6

????????svpwm->t1 = svpwm->u2;

????????svpwm->t5 = svpwm->u3;

????????sum = svpwm->t1 + svpwm->t5;

????????if (sum > svpwm->Ts)

????????{

????????????k_svpwm = svpwm->Ts / sum; //

????????????svpwm->t1 = k_svpwm * svpwm->t1;

????????????svpwm->t5 = k_svpwm * svpwm->t5;

????????}

????????svpwm->t7 = (svpwm->Ts - svpwm->t1 - svpwm->t5) / 2;

????????svpwm->ta = svpwm->t5 + svpwm->t7;

????????svpwm->tb = svpwm->t7;

????????svpwm->tc = svpwm->t1 + svpwm->t5 + svpwm->t7; ???

????????break;

?

????case 4:

????????// 扇區(qū)4

????????svpwm->t4 = -svpwm->u2;

????????svpwm->t5 = -svpwm->u1;

????????sum = svpwm->t4 + svpwm->t5;

????????if (sum > svpwm->Ts)

????????{

????????????k_svpwm = svpwm->Ts / sum; //

????????????svpwm->t4 = k_svpwm * svpwm->t4;

????????????svpwm->t5 = k_svpwm * svpwm->t5;

????????}

????????svpwm->t7 = (svpwm->Ts - svpwm->t4 - svpwm->t5) / 2;

????????svpwm->ta = svpwm->t4 + svpwm->t5 + svpwm->t7;

????????svpwm->tb = svpwm->t7;

????????svpwm->tc = svpwm->t5 + svpwm->t7; ???

????????break;

?

?

????default:

????????break;

????}


// step4:6路PWM輸出

????set_PWM_value(PWM_PERIOD*svpwm->ta,PWM_PERIOD*svpwm->tb,PWM_PERIOD*svpwm->tc);

}


????????第五步,驗證SVPWM輸出是否正確。寫完SVPWM函數(shù),需要做驗證,看看算法是否正確可用。編寫svpwm_test函數(shù),給定d,q值,由于暫時還沒有完成電機編碼器的角度獲取,所以角度theta給以個固定增量,這樣正常情況下,接上電機會轉(zhuǎn)動起來。為了便于觀察將ta,tb,tc三個數(shù)據(jù)擴大100倍放到vofa輸出函數(shù)中,顯示三條曲線。


void svpwm_test(void)

{

????float theta = 0;

????DQ_Def test_dq;

????AlphaBeta_Def test_ab;

????SVPWM_Def svpwm_out;

?

????test_dq.d = 0.0f;

????test_dq.q = 0.2f;

?

????

?

????for (theta = 0; theta < 6.2831853f; theta += 0.275f)

?????{

????????inverseParkTransform(&test_dq,&test_ab,theta);

????????SVPWM(&test_ab,&svpwm_out);

? vofa_JustFloat_output(100.0f*svpwm_out.ta,100.0f*svpwm_out.tb,100.0f*svpwm_out.tc,0.0f);

// ? ?HAL_Delay(1);

????}

}


????????最后主函數(shù)調(diào)用如下:

?

????????接上硬件平臺,編譯下載,打開串口連接vofa+上位機,可以輸出三條相位相差120°的馬鞍波曲線,顯示如下,如此就證明SVPWM成功實現(xiàn)。


?

????????同時,可以接上BLDC的UVW三項,可以看到電機會轉(zhuǎn)動,修改test_dq.d和theta的增量,電機的轉(zhuǎn)動速度會改變。

觀看視頻效果請轉(zhuǎn)至https://www.bilibili.com/video/BV1pu4y1y7jK/?spm_id_from=333.999.0.0&;vd_source=4c57166c6142504cc135c2135bf9844e

????????本文已將重要的代碼貼到文章中了,涉及到的所有源碼可以都開源,需要的小伙伴點贊關(guān)注后可以私信獲取


四、手寫STM32 FOC記錄-----FOC + SVPWM的評論 (共 條)

分享到微博請遵守國家法律
洪洞县| 澎湖县| 类乌齐县| 固原市| 河间市| 临泽县| 河池市| 安图县| 永清县| 三河市| 西藏| 周宁县| 茂名市| 蛟河市| 叙永县| 阳西县| 大冶市| 西宁市| 延津县| 大宁县| 安义县| 广宗县| 阳东县| 冷水江市| 千阳县| 锡林浩特市| 民乐县| 来安县| 紫云| 永福县| 宁南县| 准格尔旗| 敦煌市| 新蔡县| 额济纳旗| 嵩明县| 城口县| 克拉玛依市| 丰台区| 项城市| 兴国县|