打印
[STM32F1]

stm32 foc2.0 svpwm问题求解

[复制链接]
1240|12
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
jiajs|  楼主 | 2021-10-17 23:07 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
stm32 foc lib2.0中针对svpwm求出各个相位动作时间后,没有限制哪三相动作,个人理解,PWM动作时每上下桥臂只能一个动作.
例如在step5时:打开的桥臂是101(即A+,B-,C+),为什么这个函数中没有这个功能的操作呢?

使用特权

评论回复
沙发
wyjie| | 2021-10-17 23:09 | 只看该作者
对SVPWM理解错误

使用特权

评论回复
板凳
jiajs|  楼主 | 2021-10-17 23:13 | 只看该作者


void SVPWM_3ShuntCalcDutyCycles (Volt_Components Stat_Volt_Input)
{
    s32 wX, wY, wZ, wUAlpha, wUBeta;
    u16  hTimePhA = 0, hTimePhB = 0, hTimePhC = 0, hTimePhD = 0;
    u16  hDeltaDuty;

    wUAlpha = Stat_Volt_Input.qV_Component1 * T_SQRT3 ;
    wUBeta = -(Stat_Volt_Input.qV_Component2 * T);

    wX = wUBeta;
    wY = (wUBeta + wUAlpha) / 2;
    wZ = (wUBeta - wUAlpha) / 2;

    // Sector calculation from wX, wY, wZ
    if (wY < 0)
    {
        if (wZ < 0)
        {
            bSector = SECTOR_5;
        }
        else // wZ >= 0
            if (wX <= 0)
            {
                bSector = SECTOR_4;
            }
            else // wX > 0
            {
                bSector = SECTOR_3;
            }
    }
    else // wY > 0
    {
        if (wZ >= 0)
        {
            bSector = SECTOR_2;
        }
        else // wZ < 0
            if (wX <= 0)
            {
                bSector = SECTOR_6;
            }
            else // wX > 0
            {
                bSector = SECTOR_1;
            }
    }

    /* Duty cycles computation */
    PWM4Direction = PWM2_MODE;

    switch(bSector)
    {
    case SECTOR_1:
        hTimePhA = (T / 8) + ((((T + wX) - wZ) / 2) / 131072);
        hTimePhB = hTimePhA + wZ / 131072;
        hTimePhC = hTimePhB - wX / 131072;

        // ADC Syncronization setting value
        if ((u16)(PWM_PERIOD - hTimePhA) > TW_AFTER)
        {
            hTimePhD = PWM_PERIOD - 1;
        }
        else
        {
            hDeltaDuty = (u16)(hTimePhA - hTimePhB);

            // Definition of crossing point
            if (hDeltaDuty > (u16)(PWM_PERIOD - hTimePhA) * 2)
            {
                hTimePhD = hTimePhA - TW_BEFORE; // Ts before Phase A
            }
            else
            {
                hTimePhD = hTimePhA + TW_AFTER; // DT + Tn after Phase A

                if (hTimePhD >= PWM_PERIOD)
                {
                    // Trigger of ADC at Falling Edge PWM4
                    // OCR update

                    //Set Polarity of CC4 Low
                    PWM4Direction = PWM1_MODE;

                    hTimePhD = (2 * PWM_PERIOD) - hTimePhD - 1;
                }
            }
        }

        // ADC_InjectedChannelConfig(ADC1, PHASE_B_CHANNEL,1,
        //                                    SAMPLING_TIME_CK);
        ADC1->JSQR = PHASE_B_MSK + BUS_VOLT_FDBK_MSK + SEQUENCE_LENGHT;
        //ADC_InjectedChannelConfig(ADC2, PHASE_C_CHANNEL,1,
        //                                    SAMPLING_TIME_CK);
        ADC2->JSQR = PHASE_C_MSK + TEMP_FDBK_MSK + SEQUENCE_LENGHT;
        break;
    case SECTOR_2:
        hTimePhA = (T / 8) + ((((T + wY) - wZ) / 2) / 131072);
        hTimePhB = hTimePhA + wZ / 131072;
        hTimePhC = hTimePhA - wY / 131072;

        // ADC Syncronization setting value
        if ((u16)(PWM_PERIOD - hTimePhB) > TW_AFTER)
        {
            hTimePhD = PWM_PERIOD - 1;
        }
        else
        {
            hDeltaDuty = (u16)(hTimePhB - hTimePhA);

            // Definition of crossing point
            if (hDeltaDuty > (u16)(PWM_PERIOD - hTimePhB) * 2)
            {
                hTimePhD = hTimePhB - TW_BEFORE; // Ts before Phase B
            }
            else
            {
                hTimePhD = hTimePhB + TW_AFTER; // DT + Tn after Phase B

                if (hTimePhD >= PWM_PERIOD)
                {
                    // Trigger of ADC at Falling Edge PWM4
                    // OCR update

                    //Set Polarity of CC4 Low
                    PWM4Direction = PWM1_MODE;

                    hTimePhD = (2 * PWM_PERIOD) - hTimePhD - 1;
                }
            }
        }

        //ADC_InjectedChannelConfig(ADC1, PHASE_A_CHANNEL,1,
        //                                     SAMPLING_TIME_CK);
        ADC1->JSQR = PHASE_A_MSK + BUS_VOLT_FDBK_MSK + SEQUENCE_LENGHT;
        //ADC_InjectedChannelConfig(ADC2,
        //                   PHASE_C_CHANNEL,1,SAMPLING_TIME_CK);
        ADC2->JSQR = PHASE_C_MSK + TEMP_FDBK_MSK + SEQUENCE_LENGHT;
        break;

    case SECTOR_3:
        hTimePhA = (T / 8) + ((((T - wX) + wY) / 2) / 131072);
        hTimePhC = hTimePhA - wY / 131072;
        hTimePhB = hTimePhC + wX / 131072;

        // ADC Syncronization setting value
        if ((u16)(PWM_PERIOD - hTimePhB) > TW_AFTER)
        {
            hTimePhD = PWM_PERIOD - 1;
        }
        else
        {
            hDeltaDuty = (u16)(hTimePhB - hTimePhC);

            // Definition of crossing point
            if (hDeltaDuty > (u16)(PWM_PERIOD - hTimePhB) * 2)
            {
                hTimePhD = hTimePhB - TW_BEFORE; // Ts before Phase B
            }
            else
            {
                hTimePhD = hTimePhB + TW_AFTER; // DT + Tn after Phase B

                if (hTimePhD >= PWM_PERIOD)
                {
                    // Trigger of ADC at Falling Edge PWM4
                    // OCR update

                    //Set Polarity of CC4 Low
                    PWM4Direction = PWM1_MODE;

                    hTimePhD = (2 * PWM_PERIOD) - hTimePhD - 1;
                }
            }
        }

        //ADC_InjectedChannelConfig(ADC1, PHASE_A_CHANNEL,1,
        //                                    SAMPLING_TIME_CK);
        ADC1->JSQR = PHASE_A_MSK + BUS_VOLT_FDBK_MSK + SEQUENCE_LENGHT;
        //ADC_InjectedChannelConfig(ADC2, PHASE_C_CHANNEL,1,
        //                                    SAMPLING_TIME_CK);
        ADC2->JSQR = PHASE_C_MSK + TEMP_FDBK_MSK + SEQUENCE_LENGHT;
        break;

    case SECTOR_4:
        hTimePhA = (T / 8) + ((((T + wX) - wZ) / 2) / 131072);
        hTimePhB = hTimePhA + wZ / 131072;
        hTimePhC = hTimePhB - wX / 131072;

        // ADC Syncronization setting value
        if ((u16)(PWM_PERIOD - hTimePhC) > TW_AFTER)
        {
            hTimePhD = PWM_PERIOD - 1;
        }
        else
        {
            hDeltaDuty = (u16)(hTimePhC - hTimePhB);

            // Definition of crossing point
            if (hDeltaDuty > (u16)(PWM_PERIOD - hTimePhC) * 2)
            {
                hTimePhD = hTimePhC - TW_BEFORE; // Ts before Phase C
            }
            else
            {
                hTimePhD = hTimePhC + TW_AFTER; // DT + Tn after Phase C

                if (hTimePhD >= PWM_PERIOD)
                {
                    // Trigger of ADC at Falling Edge PWM4
                    // OCR update

                    //Set Polarity of CC4 Low
                    PWM4Direction = PWM1_MODE;

                    hTimePhD = (2 * PWM_PERIOD) - hTimePhD - 1;
                }
            }
        }

        //ADC_InjectedChannelConfig(ADC1, PHASE_A_CHANNEL,1,
        //                                    SAMPLING_TIME_CK);
        ADC1->JSQR = PHASE_A_MSK + BUS_VOLT_FDBK_MSK + SEQUENCE_LENGHT;
        //ADC_InjectedChannelConfig(ADC2, PHASE_B_CHANNEL,1,
        //                                     SAMPLING_TIME_CK);
        ADC2->JSQR = PHASE_B_MSK + TEMP_FDBK_MSK + SEQUENCE_LENGHT;
        break;

    case SECTOR_5:
        hTimePhA = (T / 8) + ((((T + wY) - wZ) / 2) / 131072);
        hTimePhB = hTimePhA + wZ / 131072;
        hTimePhC = hTimePhA - wY / 131072;

        // ADC Syncronization setting value
        if ((u16)(PWM_PERIOD - hTimePhC) > TW_AFTER)
        {
            hTimePhD = PWM_PERIOD - 1;
        }
        else
        {
            hDeltaDuty = (u16)(hTimePhC - hTimePhA);

            // Definition of crossing point
            if (hDeltaDuty > (u16)(PWM_PERIOD - hTimePhC) * 2)
            {
                hTimePhD = hTimePhC - TW_BEFORE; // Ts before Phase C
            }
            else
            {
                hTimePhD = hTimePhC + TW_AFTER; // DT + Tn after Phase C

                if (hTimePhD >= PWM_PERIOD)
                {
                    // Trigger of ADC at Falling Edge PWM4
                    // OCR update

                    //Set Polarity of CC4 Low
                    PWM4Direction = PWM1_MODE;

                    hTimePhD = (2 * PWM_PERIOD) - hTimePhD - 1;
                }
            }
        }

        //ADC_InjectedChannelConfig(ADC1, PHASE_A_CHANNEL,1,
        //                                   SAMPLING_TIME_CK);
        ADC1->JSQR = PHASE_A_MSK + BUS_VOLT_FDBK_MSK + SEQUENCE_LENGHT;
        //ADC_InjectedChannelConfig(ADC2, PHASE_B_CHANNEL,1,
        //                                     SAMPLING_TIME_CK);
        ADC2->JSQR = PHASE_B_MSK + TEMP_FDBK_MSK + SEQUENCE_LENGHT;
        break;

    case SECTOR_6:
        hTimePhA = (T / 8) + ((((T - wX) + wY) / 2) / 131072);
        hTimePhC = hTimePhA - wY / 131072;
        hTimePhB = hTimePhC + wX / 131072;

        // ADC Syncronization setting value
        if ((u16)(PWM_PERIOD - hTimePhA) > TW_AFTER)
        {
            hTimePhD = PWM_PERIOD - 1;
        }
        else
        {
            hDeltaDuty = (u16)(hTimePhA - hTimePhC);

            // Definition of crossing point
            if (hDeltaDuty > (u16)(PWM_PERIOD - hTimePhA) * 2)
            {
                hTimePhD = hTimePhA - TW_BEFORE; // Ts before Phase A
            }
            else
            {
                hTimePhD = hTimePhA + TW_AFTER; // DT + Tn after Phase A

                if (hTimePhD >= PWM_PERIOD)
                {
                    // Trigger of ADC at Falling Edge PWM4
                    // OCR update

                    //Set Polarity of CC4 Low
                    PWM4Direction = PWM1_MODE;

                    hTimePhD = (2 * PWM_PERIOD) - hTimePhD - 1;
                }
            }
        }

        //ADC_InjectedChannelConfig(ADC1, PHASE_B_CHANNEL,1,
        //                                    SAMPLING_TIME_CK);
        ADC1->JSQR = PHASE_B_MSK + BUS_VOLT_FDBK_MSK + SEQUENCE_LENGHT;
        //ADC_InjectedChannelConfig(ADC2, PHASE_C_CHANNEL,1,
        //                                    SAMPLING_TIME_CK);
        ADC2->JSQR = PHASE_C_MSK + TEMP_FDBK_MSK + SEQUENCE_LENGHT;
        break;
    default:
        break;
    }

    if (PWM4Direction == PWM2_MODE)
    {
        //Set Polarity of CC4 High
        TIM1->CCER &= 0xDFFF;
    }
    else
    {
        //Set Polarity of CC4 Low
        TIM1->CCER |= 0x2000;
    }

    /* Load compare registers values */
    TIM1->CCR1 = hTimePhA;
    TIM1->CCR2 = hTimePhB;
    TIM1->CCR3 = hTimePhC;
    TIM1->CCR4 = hTimePhD; // To Syncronyze the ADC
}

使用特权

评论回复
地板
stly| | 2021-10-17 23:18 | 只看该作者
在其它地方打开的,你没有找到函数吧
要不然怎么切换

使用特权

评论回复
5
jiajs|  楼主 | 2021-10-17 23:20 | 只看该作者
我有搜索过全项目,没有找到对相关寄存器的操作.难道是在库文件.lib文件中操作的吗?

使用特权

评论回复
6
heweibig| | 2021-10-17 23:22 | 只看该作者
你贴出来的程序最最最后面不是吗?
   /* Load compare registers values */
    TIM1->CCR1 = hTimePhA;
    TIM1->CCR2 = hTimePhB;
    TIM1->CCR3 = hTimePhC;
    TIM1->CCR4 = hTimePhD; // To Syncronyze the ADC

使用特权

评论回复
7
jiajs|  楼主 | 2021-10-17 23:24 | 只看该作者

搞定了,呵呵,犯了低级错误……

使用特权

评论回复
8
qcliu| | 2021-11-5 11:11 | 只看该作者
这是什么种类的pwm啊

使用特权

评论回复
9
coshi| | 2021-11-5 11:11 | 只看该作者
有对这个函数的描述吗

使用特权

评论回复
10
zljiu| | 2021-11-5 11:12 | 只看该作者
没有用过这个函数啊

使用特权

评论回复
11
wiba| | 2021-11-5 11:42 | 只看该作者
如何进行切换呢

使用特权

评论回复
12
tfqi| | 2021-11-5 12:15 | 只看该作者
主要用在什么地方呢

使用特权

评论回复
13
nawu| | 2021-11-5 12:16 | 只看该作者
这是种什么算法啊

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

940

主题

11975

帖子

6

粉丝