有偿求指点FOC SVPWM输出旋转的磁场

2019-12-11 18:38发布

现在遇到以下不解的问题求指点。
在看完ST的FOC2.O及AN1078_cn后我想实现输出SVPWM(不管PI部分)
我自认为了看了个大概:
clarke:把三相交流电变换成两项交流电流Ia及Ib。
park变换:把两项Ia及Ib通过旋转电角度(通过测速*时间(这个时间一般是系统时间))的变换得到Id(转子的磁通)及Iq转矩的输出。
PI:把实际的Iq与参考Iq差值比较经过PI得到Vq。实际的Id与参考Id(一般设置为0)差值经过PI得到Vd
逆park:把Vq与Vd转换成两项电压Ua,Ub。
SVPWM:Ua与Ub经过SVPWM算法转换得到PWM三相每项的占空比。而且中间还要根据Ua与Ub判断得到不同的扇区。扇区不同合成力矩所需要的公司不一样。
最终通过通过不听去触发ADC检测(系统周期)同时计算霍尔传感器的速度*时间的电角度得到了选择的磁场这个根据电机选择位置都可以得到。
不知道以上我理解的对不对。
我现在想实现单纯的旋转的SVPWM。但是没有丝毫的头绪。 如果单独执行:
void SVPWM_3ShuntCalcDutyCycles (Volt_Components Stat_Volt_Input)
这个里面的电压要怎么给,旋转的过程中他又会有什么结果
在电机启动的SVPWM的扇区又停留在哪了。(不知道霍尔传感器的位置跟这个扇区之间有什么关系)
希望大虾指点····· 给我个思路怎么得到SVPWM波形,可以示波器测量的。 在线等··· 当然也可以有偿求指点。怎么有偿可以商量的·······
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
83条回答
liguangqang
2019-12-16 10:19
#include "svm.h"
//-------------------------------------------------------------------------------------
//空间矢量区间
#define        VECTOR1                0x0000                        // 0   degrees
#define        VECTOR2                0x2aaa                        // 60  degrees
#define        VECTOR3                0x5555                        // 120 degrees
#define        VECTOR4                0x8000                        // 180 degrees
#define        VECTOR5                0xaaaa                        // 240 degrees
#define        VECTOR6                0xd555                        // 300 degrees
#define        SIXTY_DEG        0x2aaa                       

//最大电压值
#define VOLTS_LIMIT        28300  
         
//正弦波表60度171点
const int sinetable[] =
{
            0,  201,  401,  602,  803, 1003, 1204, 1404, 1605, 1805, 2005, 2206, 2406,
         2606, 2806, 3006, 3205, 3405, 3605, 3804, 4003, 4202, 4401, 4600, 4799, 4997,
         5195, 5393, 5591, 5789, 5986, 6183, 6380, 6577, 6773, 6970, 7166, 7361, 7557,
         7752, 7947, 8141, 8335, 8529, 8723, 8916, 9109, 9302, 9494, 9686, 9877,10068,
        10259,10449,10639,10829,11018,11207,11395,11583,11771,11958,12144,12331,12516,
        12701,12886,13070,13254,13437,13620,13802,13984,14165,14346,14526,14706,14885,
        15063,15241,15419,15595,15772,15947,16122,16297,16470,16643,16816,16988,17159,
        17330,17500,17669,17838,18006,18173,18340,18506,18671,18835,18999,19162,19325,
        19487,19647,19808,19967,20126,20284,20441,20598,20753,20908,21062,21216,21368,
        21520,21671,21821,21970,22119,22266,22413,22559,22704,22848,22992,23134,23276,
        23417,23557,23696,23834,23971,24107,24243,24377,24511,24644,24776,24906,25036,
        25165,25293,25420,25547,25672,25796,25919,26042,26163,26283,26403,26521,26638,
        26755,26870,26984,27098,27210,27321,27431,27541,27649,27756,27862,27967,28071,
        28174,28276,28377
};
//-------------------------------------------------------------------------------------
//描述: SVPWM发生器
//参数: volts:电压向量 angle:角度(0-0xFFFF)
//返回:        无
//-------------------------------------------------------------------------------------
void SVM(int16_t volts, uint16_t angle)
{
        // These variables hold the normalized sector angles used to find
        // t1, t2.
        uint16_t angle1, angle2;

        // These variables hold the space vector times.
        uint16_t half_t0,t1,t2,tpwm;

        // Calculate the total PWM count period, which is twice the value
        // in the PTPER register.
        tpwm = PTPER << 1;

        // Limit volts input to avoid overmodulation.
        if(volts > VOLTS_LIMIT) volts = VOLTS_LIMIT;

        if(angle < VECTOR2)
        {
                angle2 = angle - VECTOR1;                // Reference SVM angle to the current
                                            // sector
                angle1 = SIXTY_DEG - angle2;        // Calculate second angle referenced to
                                            // sector

                t1 = sinetable[(uint8_t)(angle1 >> 6)];        // Look up values from
                                                            // table.
                t2 = sinetable[(uint8_t)(angle2 >> 6)];

                // Scale t1 to by the volts variable.
                t1 = ((int32_t)t1*(int32_t)volts) >> 15;
                // Scale t1 for the duty cycle range.
                t1 = ((int32_t)t1*(int32_t)tpwm) >> 15;
                // Scale t2 time
                t2 = ((int32_t)t2*(int32_t)volts) >> 15;
                t2 = ((int32_t)t2*(int32_t)tpwm) >> 15;

                half_t0 = (tpwm - t1 - t2) >> 1;                // Calculate half_t0 null time from
                                                    // period and t1,t2
       
                // Calculate duty cycles for Sector 1  (0 - 59 degrees)
                PDC1 = t1 + t2 + half_t0;
                PDC2 = t2 + half_t0;
                PDC3 = half_t0;
        }
        else if(angle < VECTOR3)
        {
                angle2 = angle - VECTOR2;                // Reference SVM angle to the current
                                            // sector
                angle1 = SIXTY_DEG - angle2;        // Calculate second angle referenced to
                                             // sector

                t1 = sinetable[(uint8_t)(angle1 >> 6)];        // Look up values from
                                                     // table.
                t2 = sinetable[(uint8_t)(angle2 >> 6)];

                // Scale t1 to by the volts variable.
                t1 = ((int32_t)t1*(int32_t)volts) >> 15;
                // Scale t1 for the duty cycle range.
                t1 = ((int32_t)t1*(int32_t)tpwm) >> 15;
                // Scale t2 time
                t2 = ((int32_t)t2*(int32_t)volts) >> 15;
                t2 = ((int32_t)t2*(int32_t)tpwm) >> 15;

                half_t0 = (tpwm - t1 - t2) >> 1;                // Calculate half_t0 null time from
                                                    // period and t1,t2
       
                // Calculate duty cycles for Sector 2  (60 - 119 degrees)
                PDC1 = t1 + half_t0;
                PDC2 = t1 + t2 + half_t0;
                PDC3 = half_t0;
        }
        else if(angle < VECTOR4)
        {
                angle2 = angle - VECTOR3;                // Reference SVM angle to the current
                                              // sector
                angle1 = SIXTY_DEG - angle2;        // Calculate second angle referenced to
                                             // sector

                t1 = sinetable[(uint8_t)(angle1 >> 6)];        // Look up values from
                                                      // table.
                t2 = sinetable[(uint8_t)(angle2 >> 6)];

                // Scale t1 to by the volts variable.
                t1 = ((int32_t)t1*(int32_t)volts) >> 15;
                // Scale t1 for the duty cycle range.
                t1 = ((int32_t)t1*(int32_t)tpwm) >> 15;
                // Scale t2 time
                t2 = ((int32_t)t2*(int32_t)volts) >> 15;
                t2 = ((int32_t)t2*(int32_t)tpwm) >> 15;

                half_t0 = (tpwm - t1 - t2) >> 1;                // Calculate half_t0 null time from
                                                    // period and t1,t2
       
                // Calculate duty cycles for Sector 3  (120 - 179 degrees)
                PDC1 = half_t0;
                PDC2 = t1 + t2 + half_t0;
                PDC3 = t2 + half_t0;
        }
        else if(angle < VECTOR5)               
        {
                angle2 = angle - VECTOR4;                // Reference SVM angle to the current
                                            // sector
                angle1 = SIXTY_DEG - angle2;        // Calculate second angle referenced to
                                            // sector

                t1 = sinetable[(uint8_t)(angle1 >> 6)];        // Look up values from
                                                       // table.
                t2 = sinetable[(uint8_t)(angle2 >> 6)];
               
                // Scale t1 to by the volts variable.
                t1 = ((int32_t)t1*(int32_t)volts) >> 15;
                // Scale t1 for the duty cycle range.
                t1 = ((int32_t)t1*(int32_t)tpwm) >> 15;
                // Scale t2 time
                t2 = ((int32_t)t2*(int32_t)volts) >> 15;
                t2 = ((int32_t)t2*(int32_t)tpwm) >> 15;

                half_t0 = (tpwm - t1 - t2) >> 1;                // Calculate half_t0 null time from
                                                    // period and t1,t2
       
                // Calculate duty cycles for Sector 4  (180 - 239 degrees)
                PDC1 = half_t0;
                PDC2 = t1 + half_t0;
                PDC3 = t1 + t2 + half_t0;
        }
        else if(angle < VECTOR6)
        {
                angle2 = angle - VECTOR5;                // Reference SVM angle to the current
                                             // sector
                angle1 = SIXTY_DEG - angle2;        // Calculate second angle referenced to
                                             // sector

                t1 = sinetable[(uint8_t)(angle1 >> 6)];        // Look up values from
                                                // table.
                t2 = sinetable[(uint8_t)(angle2 >> 6)];

                // Scale t1 to by the volts variable.
                t1 = ((int32_t)t1*(int32_t)volts) >> 15;
                // Scale t1 for the duty cycle range.
                t1 = ((int32_t)t1*(int32_t)tpwm) >> 15;
                // Scale t2 time
                t2 = ((int32_t)t2*(int32_t)volts) >> 15;
                t2 = ((int32_t)t2*(int32_t)tpwm) >> 15;

                half_t0 = (tpwm - t1 - t2) >> 1;                // Calculate half_t0 null time from
                                                // period and t1,t2
       
                // Calculate duty cycles for Sector 5  (240 - 299 degrees)
                PDC1 = t2 + half_t0;
                PDC2 = half_t0;
                PDC3 = t1 + t2 + half_t0;
        }
        else
        {
                angle2 = angle - VECTOR6;                // Reference SVM angle to the current
                                            // sector
                angle1 = SIXTY_DEG - angle2;        // Calculate second angle referenced to
                                        // sector

                t1 = sinetable[(uint8_t)(angle1 >> 6)];        // Look up values from
                                                    // table.
                t2 = sinetable[(uint8_t)(angle2 >> 6)];

                // Scale t1 to by the volts variable.
                t1 = ((int32_t)t1*(int32_t)volts) >> 15;
                // Scale t1 for the duty cycle range.
                t1 = ((int32_t)t1*(int32_t)tpwm) >> 15;
                // Scale t2 time
                t2 = ((int32_t)t2*(int32_t)volts) >> 15;
                t2 = ((int32_t)t2*(int32_t)tpwm) >> 15;

                half_t0 = (tpwm - t1 - t2) >> 1;                // Calculate half_t0 null time from
                                                // period and t1,t2
       
                // Calculate duty cycles for Sector 6  ( 300 - 359 degrees )
                PDC1 = t1 + t2 + half_t0;
                PDC2 = half_t0;
                PDC3 = t1 + half_t0;
        }
}

一周热门 更多>