FOC无感开环启动排除掉高频注入这种直接识别当前转子dq轴的位置直接闭环启动,大部分的常规启动方式就是三段式启动,对齐-强拖-观测器介入-观测器误差稳定后平滑过渡-闭环。
这里就只写出I/F(V/F)启动的角度输出的代码,力矩就是一条y=kx+b的直线,没什么好说的。
这里的逻辑是我搭建的Simulink仿真的逻辑
simulink仿真如下图
相关参数
#define MOTOR_POLE_PAIRS 4 //4对极#define OPEN_LOOP_END_SPEED 300 //RPM
#define OPEN_LOOP_END_TIME 20 //Second
#define OPEN_LOOP_FREQ 0.001f //1kHz#define OPEN_LOOP_CURRENT 0.2f
#define OPEN_LOOP_CURRENT_END 1.1f
#define OPEN_LOOP_VOLTAGE 0.4f
#define OPEN_LOOP_VOLTAGE_END 1.1f#define OPEN_LOOP_TORQUE_DURATION 500 //ms
开环启动控制头文件
struct OpenLoopControl
{int8_t CloseLoopFlag; //指示是否可以切入闭环float StartAngle; //初始角度,对齐的角度float OpenLoopAngleAcc; //角加速度float OpenLoopAngleSpeed; //角速度float OpenLoopElecTheta; //电角度uint16_t OpenLoopAccCount; //计数器uint16_t OpenLoopAccTime; //时间float OpenLoopOutAngle; //计算出的开环实际角度float OpenLoopTorqueSlop; //开环力矩斜率float OpenLoopOutTorque; //计算出的实际力矩,V/F是电压,I/F是电流
};void OpenLoopSlopInit(void);
void OpenLoopCtrl(void);
相关实现
#define PI 3.11415926535f
#define PI_2 (2 * PI)
#define RadGain 2 * PI / 60.0fstatic void OpenLoopTorqueCtrl(void);
static void OpenLoopAngleCtrl(void);struct OpenLoopControl _sOpenLoopHandle;//初始化
void OpenLoopSlopInit(void)
{_sOpenLoopHandle.CloseLoopFlag = 0;_sOpenLoopHandle.OpenLoopOutAngle = 0;_sOpenLoopHandle.OpenLoopOutTorque = OPEN_LOOP_CURRENT;_sOpenLoopHandle.StartAngle = 0;_sOpenLoopHandle.OpenLoopAngleAcc = OPEN_LOOP_END_SPEED * MOTOR_POLE_PAIRS * RadGain / OPEN_LOOP_END_TIME;_sOpenLoopHandle.OpenLoopAccCount = 0;_sOpenLoopHandle.OpenLoopAccTime = (OPEN_LOOP_END_TIME / OPEN_LOOP_FREQ);_sOpenLoopHandle.OpenLoopAngleSpeed = 0.0f;_sOpenLoopHandle.OpenLoopElecTheta = 0.0f;_sOpenLoopHandle.OpenLoopOutAngle = 0.0f;_sOpenLoopHandle.OpenLoopTorqueSlop = (OPEN_LOOP_CURRENT_END - OPEN_LOOP_CURRENT) / OPEN_LOOP_TORQUE_DURATION;
} //开环曲线计算
void OpenLoopCtrl(void)
{OpenLoopTorqueCtrl();OpenLoopAngleCtrl();_sOpenLoopHandle.OpenLoopOutAngle = fmodf(_sOpenLoopHandle.OpenLoopElecTheta ,PI_2);} static void OpenLoopTorqueCtrl(void)
{if(_sOpenLoopHandle.OpenLoopOutTorque < OPEN_LOOP_CURRENT_END){_sOpenLoopHandle.OpenLoopOutTorque += _sOpenLoopHandle.OpenLoopTorqueSlop;}else{_sOpenLoopHandle.OpenLoopOutTorque = OPEN_LOOP_CURRENT_END;}
}static void OpenLoopAngleCtrl(void)
{if(_sOpenLoopHandle.OpenLoopAccCount < _sOpenLoopHandle.OpenLoopAccTime){_sOpenLoopHandle.OpenLoopAngleSpeed += _sOpenLoopHandle.OpenLoopAngleAcc * OPEN_LOOP_FREQ;_sOpenLoopHandle.OpenLoopElecTheta += _sOpenLoopHandle.OpenLoopAngleSpeed * OPEN_LOOP_FREQ;_sOpenLoopHandle.OpenLoopAccCount++;}else{_sOpenLoopHandle.OpenLoopElecTheta += _sOpenLoopHandle.OpenLoopAngleSpeed * OPEN_LOOP_FREQ;}
}
该开环启动算法是在1ms的周期执行的实测如下