|
|
@@ -18,7 +18,7 @@ static __INLINE void RevPark(DQ_t *dq, s16q5_t angle, AB_t *alpha_beta) {
|
|
|
s16q14_t c,s;
|
|
|
SinCos_Lut(angle, &s, &c);
|
|
|
|
|
|
- alpha_beta->a = S16_mul(dq->d, c, 14) - S16_mul(dq->q, s, 14);
|
|
|
+ alpha_beta->a = S16_mul(dq->d, c, 14) - S16_mul(dq->q, s, 14);
|
|
|
alpha_beta->b = S16_mul(dq->d, s, 14) + S16_mul(dq->q, c, 14);
|
|
|
}
|
|
|
|
|
|
@@ -50,10 +50,10 @@ static __INLINE s16q14_t Circle_Limitation(DQ_t *vdq, s16q5_t vDC, s16q14_t modu
|
|
|
return S16Q14(1); // s16q5 32 means int 1
|
|
|
}
|
|
|
|
|
|
-static __INLINE void FOC_Set_DqRamp(idq_Ctrl *c, s16q5_t target) {
|
|
|
+static __INLINE void FOC_Set_DqRamp(dq_Rctrl *c, s16q5_t target, int time) {
|
|
|
s32q14_t cp = c->s_Cp;
|
|
|
c->s_FinalTgt = (s32)target << 9; // to s32q14
|
|
|
- c->s_Step = (c->s_FinalTgt - cp) / (IDQ_CTRL_TS/SPD_CTRL_TS);
|
|
|
+ c->s_Step = (c->s_FinalTgt - cp) / time;
|
|
|
if (c->s_Step == 0) {
|
|
|
if (c->s_FinalTgt - cp > 0) {
|
|
|
c->s_Step = S32Q14(1);
|
|
|
@@ -63,20 +63,40 @@ static __INLINE void FOC_Set_DqRamp(idq_Ctrl *c, s16q5_t target) {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-static __INLINE s32q14_t FOC_Get_DqRamp(idq_Ctrl *c) {
|
|
|
- c->s_Cp += c->s_Step;
|
|
|
- if (c->s_Step < 0) {
|
|
|
- if (c->s_Cp < c->s_FinalTgt) {
|
|
|
- c->s_Cp = c->s_FinalTgt;
|
|
|
- }
|
|
|
- }else {
|
|
|
- if (c->s_Cp > c->s_FinalTgt) {
|
|
|
- c->s_Cp = c->s_FinalTgt;
|
|
|
+static __INLINE s32q14_t FOC_Get_DqRamp(dq_Rctrl *c) {
|
|
|
+ if (++c->n_StepCount == c->n_CtrlCount) {
|
|
|
+ c->s_Cp += c->s_Step;
|
|
|
+ if (c->s_Step < 0) {
|
|
|
+ if (c->s_Cp < c->s_FinalTgt) {
|
|
|
+ c->s_Cp = c->s_FinalTgt;
|
|
|
+ }
|
|
|
+ }else {
|
|
|
+ if (c->s_Cp > c->s_FinalTgt) {
|
|
|
+ c->s_Cp = c->s_FinalTgt;
|
|
|
+ }
|
|
|
}
|
|
|
+ c->n_StepCount = 0;
|
|
|
}
|
|
|
return c->s_Cp;
|
|
|
}
|
|
|
|
|
|
+static __INLINE void FOC_DqRamp_init(dq_Rctrl *c, int count) {
|
|
|
+ c->n_CtrlCount = count;
|
|
|
+ c->n_StepCount = 0;
|
|
|
+ c->s_Cp = 0;
|
|
|
+ c->s_FinalTgt = 0;
|
|
|
+ c->s_Step = 0;
|
|
|
+}
|
|
|
+
|
|
|
+static __INLINE void FOC_Set_iDqRamp(dq_Rctrl *c, s16q5_t target) {
|
|
|
+ FOC_Set_DqRamp(c, target, (IDQ_CTRL_TS/SPD_CTRL_TS - 1));
|
|
|
+}
|
|
|
+
|
|
|
+static __INLINE void FOC_Set_vDqRamp(dq_Rctrl *c, s16q5_t target) {
|
|
|
+ FOC_Set_DqRamp(c, target, (VDQ_RAMP_FINAL_TIME/VDQ_RAMP_TS));
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
static void PMSM_FOC_Reset_PID(void) {
|
|
|
PI_Controller_Reset(_gFOC_Ctrl.id_ctl, 0);
|
|
|
PI_Controller_Reset(_gFOC_Ctrl.iq_ctl, 0);
|
|
|
@@ -101,8 +121,11 @@ void PMSM_FOC_CoreInit(void) {
|
|
|
_gFOC_Ctrl.out.f_vdqRation = S16Q14(0.9f);
|
|
|
_gFOC_Ctrl.in.s_manualAngle = 0xFFFF;
|
|
|
|
|
|
- FOC_Set_DqRamp(_gFOC_Ctrl.dq_ctl, 0);
|
|
|
- FOC_Set_DqRamp(_gFOC_Ctrl.dq_ctl + 1, 0);
|
|
|
+ FOC_DqRamp_init(&_gFOC_Ctrl.idq_ctl[0], 1);
|
|
|
+ FOC_DqRamp_init(&_gFOC_Ctrl.idq_ctl[1], 1);
|
|
|
+
|
|
|
+ FOC_DqRamp_init(&_gFOC_Ctrl.vdq_ctl[0], (IDQ_CTRL_TS/VDQ_RAMP_TS));
|
|
|
+ FOC_DqRamp_init(&_gFOC_Ctrl.vdq_ctl[1], (IDQ_CTRL_TS/VDQ_RAMP_TS));
|
|
|
PMSM_FOC_Reset_PID();
|
|
|
}
|
|
|
|
|
|
@@ -113,8 +136,7 @@ static __INLINE void PMSM_FOC_Update_Hardware(void) {
|
|
|
_gFOC_Ctrl.in.s_motAngle = hall_sensor_get_theta();
|
|
|
}
|
|
|
_gFOC_Ctrl.in.s_motRPM = hall_sensor_get_speed();
|
|
|
-
|
|
|
- //sample current
|
|
|
+ //sample current
|
|
|
phase_current_get(_gFOC_Ctrl.in.s_iABC);
|
|
|
|
|
|
_gFOC_Ctrl.in.s_vDC = get_vbus_sfix5();
|
|
|
@@ -124,11 +146,11 @@ static __INLINE void PMSM_FOC_Update_Hardware(void) {
|
|
|
static __INLINE void PMSM_FOC_idq_Assign(void) {
|
|
|
_gFOC_Ctrl.in.s_targetIdq.d = 0;
|
|
|
_gFOC_Ctrl.in.s_targetIdq.q = _gFOC_Ctrl.in.s_targetTrq;
|
|
|
- FOC_Set_DqRamp(_gFOC_Ctrl.dq_ctl, _gFOC_Ctrl.in.s_targetIdq.d);
|
|
|
- FOC_Set_DqRamp(_gFOC_Ctrl.dq_ctl+1, _gFOC_Ctrl.in.s_targetIdq.q);
|
|
|
+ FOC_Set_iDqRamp(&_gFOC_Ctrl.idq_ctl[0], _gFOC_Ctrl.in.s_targetIdq.d);
|
|
|
+ FOC_Set_iDqRamp(&_gFOC_Ctrl.idq_ctl[1], _gFOC_Ctrl.in.s_targetIdq.q);
|
|
|
}
|
|
|
|
|
|
-
|
|
|
+static int _g_ctl_count = 0;
|
|
|
void PMSM_FOC_Schedule(void) {
|
|
|
AB_t vAB;
|
|
|
s16q5_t *iabc = _gFOC_Ctrl.in.s_iABC;
|
|
|
@@ -140,11 +162,14 @@ void PMSM_FOC_Schedule(void) {
|
|
|
|
|
|
Park(&vAB, _gFOC_Ctrl.in.s_motAngle, &_gFOC_Ctrl.out.s_RealIdq);
|
|
|
|
|
|
- s32q14_t err = FOC_Get_DqRamp(_gFOC_Ctrl.dq_ctl) - (_gFOC_Ctrl.out.s_RealIdq.d << 9);
|
|
|
+ s32q14_t err = FOC_Get_DqRamp(&_gFOC_Ctrl.idq_ctl[0]) - (_gFOC_Ctrl.out.s_RealIdq.d << 9);
|
|
|
_gFOC_Ctrl.in.s_targetVdq.d = PI_Controller_run(_gFOC_Ctrl.id_ctl, err);
|
|
|
|
|
|
- err = FOC_Get_DqRamp(_gFOC_Ctrl.dq_ctl+1) - (_gFOC_Ctrl.out.s_RealIdq.q << 9);
|
|
|
+ err = FOC_Get_DqRamp(&_gFOC_Ctrl.idq_ctl[1]) - (_gFOC_Ctrl.out.s_RealIdq.q << 9);
|
|
|
_gFOC_Ctrl.in.s_targetVdq.q = PI_Controller_run(_gFOC_Ctrl.iq_ctl, err);
|
|
|
+ }else {
|
|
|
+ _gFOC_Ctrl.in.s_targetVdq.d = FOC_Get_DqRamp(&_gFOC_Ctrl.vdq_ctl[0]) >> 9;
|
|
|
+ _gFOC_Ctrl.in.s_targetVdq.q = FOC_Get_DqRamp(&_gFOC_Ctrl.vdq_ctl[1]) >> 9;
|
|
|
}
|
|
|
_gFOC_Ctrl.out.f_vdqRation = Circle_Limitation(&_gFOC_Ctrl.in.s_targetVdq, _gFOC_Ctrl.in.s_vDC, _gFOC_Ctrl.in.n_modulation, &_gFOC_Ctrl.out.s_OutVdq);
|
|
|
|
|
|
@@ -152,18 +177,21 @@ void PMSM_FOC_Schedule(void) {
|
|
|
|
|
|
SVM_Duty_Fix(&vAB, _gFOC_Ctrl.in.s_vDC, FOC_PWM_Half_Period, &_gFOC_Ctrl.out);
|
|
|
|
|
|
+ if (_g_ctl_count++ % 10 == 0) {
|
|
|
+ plot_3data16(_gFOC_Ctrl.out.n_Duty[0], _gFOC_Ctrl.out.n_Duty[1], _gFOC_Ctrl.out.n_Duty[2]);
|
|
|
+ //plot_3data16(_gFOC_Ctrl.in.s_iABC[0], _gFOC_Ctrl.in.s_iABC[1], _gFOC_Ctrl.in.s_iABC[2]);
|
|
|
+ }
|
|
|
phase_current_point(&_gFOC_Ctrl.out);
|
|
|
|
|
|
pwm_update_duty(_gFOC_Ctrl.out.n_Duty[0], _gFOC_Ctrl.out.n_Duty[1], _gFOC_Ctrl.out.n_Duty[2]);
|
|
|
pwm_update_sample(_gFOC_Ctrl.out.n_Sample1, _gFOC_Ctrl.out.n_Sample2, _gFOC_Ctrl.out.n_Sector);
|
|
|
-
|
|
|
- plot_3data16(_gFOC_Ctrl.in.s_iABC[0], _gFOC_Ctrl.in.s_iABC[1], _gFOC_Ctrl.in.s_iABC[2]);
|
|
|
}
|
|
|
|
|
|
void PMSM_FOC_LogDebug(void) {
|
|
|
//sys_debug("Duty %d, %d, %d\n", _gFOC_Ctrl.out.n_Duty[0], _gFOC_Ctrl.out.n_Duty[1], _gFOC_Ctrl.out.n_Duty[2]);
|
|
|
- //sys_debug("Vdq %f, %f-->%f, %f, %f\n", S16Q5toF(_gFOC_Ctrl.in.s_targetVdq.d), S16Q5toF(_gFOC_Ctrl.in.s_targetVdq.q), S16Q5toF(_gFOC_Ctrl.out.s_OutVdq.d), S16Q5toF(_gFOC_Ctrl.out.s_OutVdq.q), S16Q14toF(_gFOC_Ctrl.out.f_vdqRation));
|
|
|
- sys_debug("iABC %f, %f, %f\n", S16Q5toF(_gFOC_Ctrl.in.s_iABC[0]), S16Q5toF(_gFOC_Ctrl.in.s_iABC[1]), S16Q5toF(_gFOC_Ctrl.in.s_iABC[2]));
|
|
|
+ sys_debug("Vdq %f, %f-->%f, %f, %f\n", S16Q5toF(_gFOC_Ctrl.in.s_targetVdq.d), S16Q5toF(_gFOC_Ctrl.in.s_targetVdq.q), S16Q5toF(_gFOC_Ctrl.out.s_OutVdq.d), S16Q5toF(_gFOC_Ctrl.out.s_OutVdq.q), S16Q14toF(_gFOC_Ctrl.out.f_vdqRation));
|
|
|
+ sys_debug("VBUS: %f, %d, %d\n", S16Q5toF(get_vbus_sfix5()), _gFOC_Ctrl.out.n_Sample1, _gFOC_Ctrl.out.n_Sample2);
|
|
|
+ //sys_debug("iABC %f, %f, %f\n", S16Q5toF(_gFOC_Ctrl.in.s_iABC[0]), S16Q5toF(_gFOC_Ctrl.in.s_iABC[1]), S16Q5toF(_gFOC_Ctrl.in.s_iABC[2]));
|
|
|
//plot_1data16(_gFOC_Ctrl.in.s_iABC[0]);
|
|
|
//sys_debug("sample %d, %d\n", _gFOC_Ctrl.out.n_Sample1, _gFOC_Ctrl.out.n_Sample2);
|
|
|
}
|
|
|
@@ -240,8 +268,8 @@ void PMSM_FOC_SetCtrlMode(u8 mode) {
|
|
|
}
|
|
|
|
|
|
void PMSM_FOC_SetOpenVdq(s16q5_t vd, s16q5_t vq) {
|
|
|
- _gFOC_Ctrl.in.s_targetVdq.d = vd;
|
|
|
- _gFOC_Ctrl.in.s_targetVdq.q = vq;
|
|
|
+ FOC_Set_vDqRamp(&_gFOC_Ctrl.vdq_ctl[0], vd);
|
|
|
+ FOC_Set_vDqRamp(&_gFOC_Ctrl.vdq_ctl[1], vq);
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -286,7 +314,7 @@ bool PMSM_FOC_Set_CruiseSpeed(float rpm) {
|
|
|
}
|
|
|
|
|
|
void PMSM_FOC_Set_Angle(s16 angle) {
|
|
|
- _gFOC_Ctrl.in.s_manualAngle = S16Q14(angle);
|
|
|
+ _gFOC_Ctrl.in.s_manualAngle = S16Q5(angle);
|
|
|
}
|
|
|
|
|
|
s32q4_t PMSM_FOC_GetSpeed(void) {
|