User Tools

Site Tools

study:foc-topic:241001-001:index

FOC學習筆記(六)—–SVPWM扇區判斷

一、理論分析

  • 反Park變換一節我們知道,經過反Park變換之後,我們得到Uα和Uβ如下,可能會有人有疑問,有Clark變換,Park變換,反Park變換,怎麼就是沒有反Clark變換呢?其實反Clark變換相當於整合到SVPWM裡面了,接下來我們來分析:
  • Calrk變換是三相到兩相的變換,Ia,Ib,Ic經過Clark變換之後得到Iα和Iβ,所以這裡反Clark變換應該是兩相到三相的變換,Uα和Uβ變換得到Ua,Ub,Uc 。這裡我們反過來看,因為我們知道馬達正常轉動時三相相電壓的情況的,如下:
  • 即為三相互差120度的對稱三相正弦。我們把這個結果帶入到Clark變換的式子中去,因為從後往前推導相當於還是進行Clark變換。
  • 帶入後經過合併計算:
  • 其中Um是三相繞組的相電壓幅值,至於大小為何是sqrt(3)Udc/3,請移步這篇文章看相電壓基波幅值。
  • 到這裡總之我們是得到了一個看起來很簡單的結果
  • 把結果單獨擷取出來如下:
  • 其中的Ωt就是θ,有了θ還不好判斷扇區嗎?那肯定很容易啦,扇區都是按照角度劃分好的:
  • 再推導一步就可以得到θ的公式:
  • 這裡就遇到一點小問題,可以看到要進行計算θ要進行反正切的運算,這對MCU來說是災難,此運算的時間複雜度很高,MCU計算壓力有點大,所以我們能不能找一個退而求其次的方法呢,透過人為的繼續推導一步,來減少MCU的計算壓力,是有的:
  • 我們把Uα和Uβ的波形拉出來分析一下,黃色的是Uα,藍色的是Uβ,我們均勻的依角度劃分為六個扇區:
  • 有沒有一種可能,我們只對Uα和Uβ進行定性分析,只看大於零還是小於零,而不進行反正切的運算就對扇區就行判斷呢,完全是可以的。
  • 接下來我們分析:
  • 第一區:
  • 從波形圖可以看得出來,在第一區內,Uα和Uβ都大於0。另外,第一區的角度範圍是0-60度,所以第一區的角度正切值tan(θ)的範圍是:0<tan(θ)<sqrt(3)。即0<Uβ/Uα<sqrt(3),由於Uα>0,所以不等式兩邊同時乘以Uα,不等式不變號:即sqrt(3)Uα – Uβ > 0,兩邊都乘以1/2,不等式不變號,即:(sqrt(3)Uα – Uβ)/2 > 0。為什麼要乘以1/2?因為這個值很特殊,在向量作用時間的計算中也要用到它,所以我們這裡保持一致,把這個變數保存下來,多次利用,避免重複運算。再計算一個特殊值:(-sqrt(3)Uα – Uβ)/2,因為Uα和Uβ都大於零,這裡前面係數又都為負,所以這個多項式必然小於0。
  • 所以結論是:在第一區:①Uβ > 0,②(sqrt(3)Uα – Uβ)/2 > 0,③(-sqrt(3)Uα – Uβ)/2 < 0。
  • 我們把①記作A,②記作B,③記作C,同理計算出其他五個扇區的A,B,C如下:
  • 如圖右邊三列是最終的定性分析結果,可以看到每個扇區都不一樣,所以我們只需要對A,B,C進行大於小於0的判斷就可以確定扇區。
  • 這裡提供一個公式N = 4C + 2B + A,得到一個N值,其中A的值是:若A>0則A = 1,否則A = 0,B,C同理。可以發現這其實就是8421碼的編碼方式,只不過這裡只有三位編碼而已,我願稱之為421編碼。計算出來一個N值之後,N值就和區號I~VI具有一一對應關係。這裡直接給結論,也可以自己計算。
  • 至此其實從理論上我們已經可以透過Uα和Uβ進行扇形判斷了,接下來就透過Matlab模擬實現扇區判斷:

二、Matlab仿真

  • 創建一個SVPWM子模組,我這裡是已經過了完整的SVPWM模組仿真,我們這裡只看扇區判斷部分就好,這裡看到SVPWM模組會輸出扇區號:
  • 打開SVPWM模組看一下內部程式碼:
     
    function[Tcmp1,Tcmp2,Tcmp3,Sector] = fcn(Ualpha,Ubeta,Udc,Tpwm)
    
    %=============Initial========================
    N = single(0);
    Tcmp1 = single(0);
    Tcmp2 = single(0);
    Tcmp3 = single(0);
    %=============A B C statement================
    A = Ubeta;
    B = (sqrt(3) * Ualpha - Ubeta)/2;
    C = (-sqrt(3) * Ualpha - Ubeta)/2;
    %============Sector Judgment=================
    if(A > 0)
        N = single(1);
    end
    if(B > 0)
        N = N + single(2);
    end
    
    if(C > 0)
        N = N + single(4);
    end
    
    switch(N)
        case 1
            Sector = 2;
        case 2
            Sector = 6;
        case 3
            Sector = 1;
        case 4
            Sector = 4;
        case 5
            Sector = 3;
        otherwise
            Sector = 5;
    end
  • 可以看到內部的計算實際上和我們的理論分析是完全一致的,進行ABC的計算然後進行扇區號的列表對應返回扇區號。
  • 運行之後查看Sector輸出,可以看到磁區號回傳符合我們預期,1-6循環切換。

三、硬體平台實現

  • 函數原始碼:
  • /*根据Ualpha和Ubeta判断当前扇区*/
    SectorJudgement_t getSectorNumber(AlphaBetaCoord_t uAlphaBeta)
    {
        SectorJudgement_t SectorStructure_temp;
        /*扇区判断数据N清零,防止随调用次数不断累加*/
        SectorStructure_temp.mu8_SectorJudgement_N = 0;
        /*计算扇区判断中间变量ABC*/
        SectorStructure_temp.mf_SectorJudgement_A = uAlphaBeta.mf_Beta;
        SectorStructure_temp.mf_SectorJudgement_B = (1.7320508 * uAlphaBeta.mf_Alpha - uAlphaBeta.mf_Beta);
        SectorStructure_temp.mf_SectorJudgement_C = (-1.7320508 * uAlphaBeta.mf_Alpha - uAlphaBeta.mf_Beta);
        /*由中间变量ABC根据公式N=A+2B+4C计算N值*/
        if(SectorStructure_temp.mf_SectorJudgement_A > 0)
        {
            SectorStructure_temp.mu8_SectorJudgement_N += 1;
        }
        if(SectorStructure_temp.mf_SectorJudgement_B > 0)
        {
            SectorStructure_temp.mu8_SectorJudgement_N += 2;
        }
        if(SectorStructure_temp.mf_SectorJudgement_C > 0)
        {
            SectorStructure_temp.mu8_SectorJudgement_N += 4;
        }
        
        /*由N值通过查表法查出扇区号*/
        if(SectorStructure_temp.mu8_SectorJudgement_N > 0 && SectorStructure_temp.mu8_SectorJudgement_N <= SECTOR_NUM)
            SectorStructure_temp.me_Sector = e_SectorIndex[SectorStructure_temp.mu8_SectorJudgement_N];
        /*N值不合法*/
        else
            SectorStructure_temp.me_Sector = SECTOR_ERROR;
        
        return SectorStructure_temp;
    }
  • 資料結構:
  • /*扇区号枚举*/
    typedef enum
    {
      SECTOR_ERROR = 0,
      SECTOR_1,
      SECTOR_2,
      SECTOR_3,
      SECTOR_4,
      SECTOR_5,
      SECTOR_6
    }SectorNum_e;
    
    /*扇区判断相关结构体*/
    typedef struct
    {
      float         mf_SectorJudgement_A;
      float         mf_SectorJudgement_B;
      float         mf_SectorJudgement_C;
      uint8_t       mu8_SectorJudgement_N;
      SectorNum_e   me_Sector;
    }SectorJudgement_t;
    
    typedef struct
    {
      float mf_Alpha;
      float mf_Beta;
    
    }AlphaBetaCoord_t;
  • 運行查看輸出:
  • 輸出結果完美且模擬一致,至此扇區判斷部分完結!
  • 9 person(s) visited this page until now.

Permalink study/foc-topic/241001-001/index.txt · Last modified: 2024/10/01 15:13 by jethro

oeffentlich