void FOC_SVPWM(float Uq, float Ud, float angle) {

    int sector;

    // 美妙的视频介绍了空间矢量调制 (FOC_SVPWM) 算法
    // https://www.youtube.com/watch?v=QMSWUMEAejg

    // 算法步骤如下:
    // 1) Ualpha, Ubeta
    // 2) Uout = sqrt(Ualpha^2 + Ubeta^2)
    // 3) angle_el = atan2(Ubeta, Ualpha)
    //
    // 等价于2),因为幅值不变:
    // Uout = sqrt(Ud^2 + Uq^2)
    // 等价于3)是:
    // angle_el = angle_el + atan2(Uq,Ud)

    float Uout = _sqrt(Ud * Ud + Uq * Uq) / VOLTAGE_LIMIT; // 实际上,Uout是一个比率
    angle = _normalizeAngle(angle + atan2(Uq, Ud));

    // 找出当前所在的扇区
    sector = floor(angle / _PI_3) + 1;
    // 计算占空比
    float T1 = _SQRT3 * _sin(sector * _PI_3 - angle) * Uout;
    float T2 = _SQRT3 * _sin(angle - (sector - 1.0f) * _PI_3) * Uout;
    // 有两种版本
//    float T0 = 0; // 拉向0 - 更适用于低电源电压
    float T0 = 1 - T1 - T2; // 调制中心在driver->voltage_limit/2

    // 计算占空比(时间)
    float Ta, Tb, Tc;
    switch (sector) {
        case 1:
            Ta = T1 + T2 + T0 / 2;
            Tb = T2 + T0 / 2;
            Tc = T0 / 2;
            break;
        case 2:
            Ta = T1 + T0 / 2;
            Tb = T1 + T2 + T0 / 2;
            Tc = T0 / 2;
            break;
        case 3:
            Ta = T0 / 2;
            Tb = T1 + T2 + T0 / 2;
            Tc = T2 + T0 / 2;
            break;
        case 4:
            Ta = T0 / 2;
            Tb = T1 + T0 / 2;
            Tc = T1 + T2 + T0 / 2;
            break;
        case 5:
            Ta = T2 + T0 / 2;
            Tb = T0 / 2;
            Tc = T1 + T2 + T0 / 2;
            break;
        case 6:
            Ta = T1 + T2 + T0 / 2;
            Tb = T0 / 2;
            Tc = T1 + T0 / 2;
            break;
        default:
            // 可能的错误状态
            Ta = 0;
            Tb = 0;
            Tc = 0;
    }

    // Ta, Tb, Tc 范围 [0,1]

    _writeDutyCycle3PWM(Ta, Tb, Tc);
}

该函数实现了一种名为 FOC_SVPWM 的空间矢量调制算法,它用于控制电机。函数接收三个输入参数:

  • Uq:q轴电压
  • Ud:d轴电压
  • angle:电机转子角度

函数的实现步骤如下:

  1. 计算输出电压幅值 Uout
    float Uout = _sqrt(Ud * Ud + Uq * Uq) / VOLTAGE_LIMIT; // 实际上,Uout是一个比率
    
  2. 计算相位角 angle
    angle = _normalizeAngle(angle + atan2(Uq, Ud));
    
  3. 确定当前所在的扇区 sector
    sector = floor(angle / _PI_3) + 1;
    
  4. 计算三个占空比 T1T2T0
    float T1 = _SQRT3 * _sin(sector * _PI_3 - angle) * Uout;
    float T2 = _SQRT3 * _sin(angle - (sector - 1.0f) * _PI_3) * Uout;
    // 有两种版本
    

// float T0 = 0; // 拉向0 - 更适用于低电源电压 float T0 = 1 - T1 - T2; // 调制中心在driver->voltage_limit/2 5. 根据扇区号 **sector** 计算三个PWM占空比 **Ta**,**Tb** 和 **Tc**:c float Ta, Tb, Tc; switch (sector) { // ... } ``` 6. 最后调用函数 _writeDutyCycle3PWM 将三个PWM占空比写入硬件寄存器。

该函数的注释和中文翻译有助于理解代码的逻辑,并方便学习者掌握该算法的实现细节。

C语言FOC_SVPWM函数注释及中文翻译

原文地址: https://www.cveoy.top/t/topic/n5hx 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录