本期测评让电机进行开环强拖,电角度使用自增电角度。上期测评我们已经把工程配置的差不多了,这期就直接上代码了。
先上总的控制框图:
而我们本期做的是下面这个部分
开环强拖分为3部分:
- 反park变换
- svpwm
- 电角度
1. 反park变换
参考公式
void ipark(Motor_State *motor)
{
voltage_int(motor);
motor->v_alpha = motor->vd_int * motor->theta_cos - motor->vq_int * motor->theta_sin;
motor->v_beta = motor->vq_int * motor->theta_cos + motor->vd_int * motor->theta_sin;
}
这里voltage_int函数我们后面再解释。
2.svpwm
void svpwm(Motor_State *motor, uint32_t PWMFullDutyCycle)
{
float ts = 1,k_svpwm;
ipark(motor);
float u1 = motor->v_beta;
float u2 = -0.8660254037844386 * motor->v_alpha - 0.5 * motor->v_beta;
float u3 = 0.8660254037844386 * motor->v_alpha - 0.5 * motor->v_beta;
uint8_t sector = (u1 > 0.0) + ((u2 > 0.0) << 1) + ((u3 > 0.0) << 2);
if (sector == 5)
{
float t4 = u3;
float t6 = u1;
float sum = t4 + t6;
if (sum > ts)
{
k_svpwm = ts / sum;
t4 = k_svpwm * t4;
t6 = k_svpwm * t6;
}
float t7 = (ts - t4 - t6) / 2;
motor->ta = t4 + t6 + t7;
motor->tb = t6 + t7;
motor->tc = t7;
}
else if (sector == 1)
{
float t2 = -u3;
float t6 = -u2;
float sum = t2 + t6;
if (sum > ts)
{
k_svpwm = ts / sum;
t2 = k_svpwm * t2;
t6 = k_svpwm * t6;
}
float t7 = (ts - t2 - t6) / 2;
motor->ta = t6 + t7;
motor->tb = t2 + t6 + t7;
motor->tc = t7;
}
else if (sector == 3)
{
float t2 = u1;
float t3 = u2;
float sum = t2 + t3;
if (sum > ts)
{
k_svpwm = ts / sum;
t2 = k_svpwm * t2;
t3 = k_svpwm * t3;
}
float t7 = (ts - t2 - t3) / 2;
motor->ta = t7;
motor->tb = t2 + t3 + t7;
motor->tc = t3 + t7;
}
else if (sector == 2)
{
float t1 = -u1;
float t3 = -u3;
float sum = t1 + t3;
if (sum > ts)
{
k_svpwm = ts / sum;
t1 = k_svpwm * t1;
t3 = k_svpwm * t3;
}
float t7 = (ts - t1 - t3) / 2;
motor->ta = t7;
motor->tb = t3 + t7;
motor->tc = t1 + t3 + t7;
}
else if (sector == 6)
{
float t1 = u2;
float t5 = u3;
float sum = t1 + t5;
if (sum > ts)
{
k_svpwm = ts / sum;
t1 = k_svpwm * t1;
t5 = k_svpwm * t5;
}
float t7 = (ts - t1 - t5) / 2;
motor->ta = t5 + t7;
motor->tb = t7;
motor->tc = t1 + t5 + t7;
}
else if (sector == 4)
{
float t4 = -u2;
float t5 = -u1;
float sum = t4 + t5;
if (sum > ts)
{
k_svpwm = ts / sum;
t4 = k_svpwm * t4;
t5 = k_svpwm * t5;
}
float t7 = (ts - t4 - t5) / 2;
motor->ta = t4 + t5 + t7;
motor->tb = t7;
motor->tc = t5 + t7;
}
motor->pwma = motor->ta * PWMFullDutyCycle;
motor->pwmb = motor->tb * PWMFullDutyCycle;
motor->pwmc = motor->tc * PWMFullDutyCycle;
}
这里大家可以参考这篇文章:深入浅出FOC控制-CSDN博客
我直接贴出重点
我的代码中,让这个地方的K等于1了,这样可以减少计算,这样前面传入的数据也必须除以K,所以上面代码的voltage_int就是做的这个事情,可以理解成这里将vd和vq标幺化成了1,如下
void voltage_int(Motor_State *motor)
{
motor->vd_int = (motor->vd) / (motor->v_bus) * ONE_BY_SQRT3;
motor->vq_int = (motor->vq) / (motor->v_bus) * ONE_BY_SQRT3;
}
3.电角度自增
这里我人为给一个电角度,用来强拖电机
4.现象
首先给大家看一下svpwm的马鞍波
最后给大家看一下电机转动的情况
VID20250120174059