|
|
@@ -184,9 +184,9 @@ void PMSM_FOC_RT_LimInit(void) {
|
|
|
gFoc_Ctrl.protLim.s_iDCLim = HW_LIMIT_NONE;
|
|
|
gFoc_Ctrl.protLim.s_TorqueLim = HW_LIMIT_NONE;
|
|
|
|
|
|
- eRamp_init_target(&gFoc_Ctrl.rtLim.rpmLimRamp, gFoc_Ctrl.userLim.s_motRPMLim, CONFIG_LIMIT_RAMP_TIME, CONFIG_LIMIT_RAMP_TIME);
|
|
|
- eRamp_init_target(&gFoc_Ctrl.rtLim.torqueLimRamp, gFoc_Ctrl.userLim.s_torqueLim, CONFIG_LIMIT_RAMP_TIME, CONFIG_LIMIT_RAMP_TIME);
|
|
|
- eRamp_init_target(&gFoc_Ctrl.rtLim.DCCurrLimRamp, gFoc_Ctrl.userLim.s_iDCLim, CONFIG_LIMIT_RAMP_TIME, CONFIG_LIMIT_RAMP_TIME);
|
|
|
+ eRamp_init_target2(&gFoc_Ctrl.rtLim.rpmLimRamp, gFoc_Ctrl.userLim.s_motRPMLim, CONFIG_LIMIT_RAMP_TIME);
|
|
|
+ eRamp_init_target2(&gFoc_Ctrl.rtLim.torqueLimRamp, gFoc_Ctrl.userLim.s_torqueLim, CONFIG_LIMIT_RAMP_TIME);
|
|
|
+ eRamp_init_target2(&gFoc_Ctrl.rtLim.DCCurrLimRamp, gFoc_Ctrl.userLim.s_iDCLim, CONFIG_LIMIT_RAMP_TIME);
|
|
|
}
|
|
|
|
|
|
void PMSM_FOC_CoreInit(void) {
|
|
|
@@ -222,14 +222,15 @@ void PMSM_FOC_CoreInit(void) {
|
|
|
gFoc_Ctrl.params.ld = nv_get_motor_params()->ld;
|
|
|
gFoc_Ctrl.params.flux = nv_get_motor_params()->flux_linkage;
|
|
|
gFoc_Ctrl.in.s_manualAngle = INVALID_ANGLE;
|
|
|
+ gFoc_Ctrl.in.s_dqAngle = INVALID_ANGLE;
|
|
|
gFoc_Ctrl.in.b_fwEnable = nv_get_foc_params()->n_FwEnable;
|
|
|
gFoc_Ctrl.in.s_vDC = nv_get_foc_params()->s_maxDCVol;//(CONFIG_RATED_DC_VOL);
|
|
|
-// gFoc_Ctrl.params.f_DCLim = get_vbus_float();
|
|
|
- eRamp_init_target(&gFoc_Ctrl.in.cruiseRpmRamp, 0, CONFIG_ACC_TIME, CONFIG_DEC_TIME);
|
|
|
|
|
|
gFoc_Ctrl.out.n_RunMode = CTRL_MODE_OPEN;
|
|
|
gFoc_Ctrl.out.f_vdqRation = 0;
|
|
|
|
|
|
+ eRamp_init_target2(&gFoc_Ctrl.in.cruiseRpmRamp, 0, CONFIG_CRUISE_RAMP_TIME);
|
|
|
+
|
|
|
FOC_DqRamp_init(&gFoc_Ctrl.idq_ctl[0], 1);
|
|
|
FOC_DqRamp_init(&gFoc_Ctrl.idq_ctl[1], 1);
|
|
|
|
|
|
@@ -244,7 +245,7 @@ void PMSM_FOC_CoreInit(void) {
|
|
|
|
|
|
/* 通过三相电流重构母线电流,和单电阻采样正好相反,原理一致 */
|
|
|
static __INLINE void PMSM_FOC_Calc_iDC_Fast(void) {
|
|
|
- float deadtime = (float)(NS_2_TCLK(PWM_DEAD_TIME_NS))/(float)FOC_PWM_Half_Period;
|
|
|
+ float deadtime = (float)(NS_2_TCLK(PWM_DEAD_TIME_NS + HW_DEAD_TIME_NS))/(float)FOC_PWM_Half_Period;
|
|
|
float duty_pu[3];
|
|
|
duty_pu[0] = (float)gFoc_Ctrl.out.n_Duty[0] / (float)FOC_PWM_Half_Period;
|
|
|
duty_pu[1] = (float)gFoc_Ctrl.out.n_Duty[1] / (float)FOC_PWM_Half_Period;
|
|
|
@@ -254,18 +255,84 @@ static __INLINE void PMSM_FOC_Calc_iDC_Fast(void) {
|
|
|
float iDC;
|
|
|
if ((duty_pu[0] >= duty_pu[1]) && (duty_pu[1] >= duty_pu[2])) {
|
|
|
iDC = iABC[0] * MAX(duty_pu[0] - duty_pu[1] - deadtime, 0) + (iABC[0] + iABC[1]) * MAX(duty_pu[1] - duty_pu[2] - deadtime, 0);
|
|
|
+ if (iABC[0] < 0) {
|
|
|
+ iDC = iDC + iABC[0] * deadtime;
|
|
|
+ }
|
|
|
+ if (iABC[1] > 0) {
|
|
|
+ iDC = iDC + iABC[0] * deadtime;
|
|
|
+ }else {
|
|
|
+ iDC = iDC + (iABC[0] + iABC[1]) * deadtime;
|
|
|
+ }
|
|
|
+ if (iABC[2] > 0) {
|
|
|
+ iDC = iDC + (iABC[0] + iABC[1]) * deadtime;
|
|
|
+ }
|
|
|
}else if ((duty_pu[0] >= duty_pu[2]) && (duty_pu[2] >= duty_pu[1])) {
|
|
|
iDC = iABC[0] * MAX(duty_pu[0] - duty_pu[2] - deadtime, 0) + (iABC[0] + iABC[2]) * MAX(duty_pu[2] - duty_pu[1] - deadtime, 0);
|
|
|
+ if (iABC[0] < 0) {
|
|
|
+ iDC = iDC + iABC[0] * deadtime;
|
|
|
+ }
|
|
|
+ if (iABC[2] > 0) {
|
|
|
+ iDC = iDC + iABC[0] * deadtime;
|
|
|
+ }else {
|
|
|
+ iDC = iDC + (iABC[0] + iABC[2]) * deadtime;
|
|
|
+ }
|
|
|
+ if (iABC[1] > 0) {
|
|
|
+ iDC = iDC + (iABC[0] + iABC[2]) * deadtime;
|
|
|
+ }
|
|
|
}else if ((duty_pu[1] >= duty_pu[0]) && (duty_pu[0] >= duty_pu[2])) {
|
|
|
iDC = iABC[1] * MAX(duty_pu[1] - duty_pu[0] - deadtime, 0) + (iABC[1] + iABC[0]) * MAX(duty_pu[0] - duty_pu[2] - deadtime, 0);
|
|
|
+ if (iABC[1] < 0) {
|
|
|
+ iDC = iDC + iABC[1] * deadtime;
|
|
|
+ }
|
|
|
+ if (iABC[0] > 0) {
|
|
|
+ iDC = iDC + iABC[1] * deadtime;
|
|
|
+ }else {
|
|
|
+ iDC = iDC + (iABC[1] + iABC[0]) * deadtime;
|
|
|
+ }
|
|
|
+ if (iABC[2] > 0) {
|
|
|
+ iDC = iDC + (iABC[1] + iABC[0]) * deadtime;
|
|
|
+ }
|
|
|
}else if ((duty_pu[1] >= duty_pu[2]) && (duty_pu[2] >= duty_pu[0])) {
|
|
|
iDC = iABC[1] * MAX(duty_pu[1] - duty_pu[2] - deadtime, 0) + (iABC[1] + iABC[2]) * MAX(duty_pu[2] - duty_pu[0] - deadtime, 0);
|
|
|
+ if (iABC[1] < 0) {
|
|
|
+ iDC = iDC + iABC[1] * deadtime;
|
|
|
+ }
|
|
|
+ if (iABC[2] > 0) {
|
|
|
+ iDC = iDC + iABC[1] * deadtime;
|
|
|
+ }else {
|
|
|
+ iDC = iDC + (iABC[1] + iABC[2]) * deadtime;
|
|
|
+ }
|
|
|
+ if (iABC[0] > 0) {
|
|
|
+ iDC = iDC + (iABC[1] + iABC[2]) * deadtime;
|
|
|
+ }
|
|
|
}else if ((duty_pu[2] >= duty_pu[0]) && (duty_pu[0] >= duty_pu[1])) {
|
|
|
iDC = iABC[2] * MAX(duty_pu[2] - duty_pu[0] - deadtime, 0) + (iABC[2] + iABC[0]) * MAX(duty_pu[0] - duty_pu[1] - deadtime, 0);
|
|
|
+ if (iABC[2] < 0) {
|
|
|
+ iDC = iDC + iABC[2] * deadtime;
|
|
|
+ }
|
|
|
+ if (iABC[0] > 0) {
|
|
|
+ iDC = iDC + iABC[2] * deadtime;
|
|
|
+ }else {
|
|
|
+ iDC = iDC + (iABC[2] + iABC[0]) * deadtime;
|
|
|
+ }
|
|
|
+ if (iABC[1] > 0) {
|
|
|
+ iDC = iDC + (iABC[2] + iABC[0]) * deadtime;
|
|
|
+ }
|
|
|
}else { // duty_pu[2] >= duty_pu[1] && duty_pu[1] >= duty_pu[0]
|
|
|
iDC = iABC[2] * MAX(duty_pu[2] - duty_pu[1] - deadtime, 0) + (iABC[2] + iABC[1]) * MAX(duty_pu[1] - duty_pu[0] - deadtime, 0);
|
|
|
+ if (iABC[2] < 0) {
|
|
|
+ iDC = iDC + iABC[2] * deadtime;
|
|
|
+ }
|
|
|
+ if (iABC[1] > 0) {
|
|
|
+ iDC = iDC + iABC[2] * deadtime;
|
|
|
+ }else {
|
|
|
+ iDC = iDC + (iABC[2] + iABC[1]) * deadtime;
|
|
|
+ }
|
|
|
+ if (iABC[0] > 0) {
|
|
|
+ iDC = iDC + (iABC[2] + iABC[1]) * deadtime;
|
|
|
+ }
|
|
|
}
|
|
|
- LowPass_Filter(gFoc_Ctrl.out.s_CalciDC2, iDC, 0.01f);
|
|
|
+ LowPass_Filter(gFoc_Ctrl.out.s_CalciDC2, iDC, 0.005f);
|
|
|
}
|
|
|
|
|
|
//#define UPDATE_Lq_By_iq /* Q轴电感 通过Iq电流补偿 */
|
|
|
@@ -553,9 +620,9 @@ static __INLINE float PMSM_FOC_Limit_Speed(float maxTrq) {
|
|
|
|
|
|
static __INLINE void PMSM_FOC_idq_Assign(void) {
|
|
|
if (gFoc_Ctrl.out.n_RunMode == CTRL_MODE_CURRENT) {
|
|
|
- if (gFoc_Ctrl.in.b_MTPA_calibrate && (gFoc_Ctrl.in.s_manualAngle != INVALID_ANGLE)) {
|
|
|
+ if (gFoc_Ctrl.in.b_MTPA_calibrate && (gFoc_Ctrl.in.s_dqAngle != INVALID_ANGLE)) {
|
|
|
float s, c;
|
|
|
- normal_sincosf(degree_2_pi(gFoc_Ctrl.in.s_manualAngle + 90.0f), &s, &c);
|
|
|
+ normal_sincosf(degree_2_pi(gFoc_Ctrl.in.s_dqAngle + 90.0f), &s, &c);
|
|
|
gFoc_Ctrl.in.s_targetIdq.d = gFoc_Ctrl.in.s_targetCurrent * c;
|
|
|
|
|
|
if (gFoc_Ctrl.in.s_targetIdq.d > gFoc_Ctrl.hwLim.s_FWDCurrMax) {
|
|
|
@@ -819,7 +886,7 @@ void PMSM_FOC_RT_PhaseCurrLim(float lim) {
|
|
|
if (lim > gFoc_Ctrl.hwLim.s_PhaseCurrMax) {
|
|
|
lim = gFoc_Ctrl.hwLim.s_PhaseCurrMax;
|
|
|
}
|
|
|
- eRamp_init_target(&gFoc_Ctrl.rtLim.torqueLimRamp, lim, CONFIG_LIMIT_RAMP_TIME, CONFIG_LIMIT_RAMP_TIME);
|
|
|
+ eRamp_init_target2(&gFoc_Ctrl.rtLim.torqueLimRamp, lim, CONFIG_LIMIT_RAMP_TIME);
|
|
|
}
|
|
|
|
|
|
float PMSM_FOC_GetPhaseCurrLim(void) {
|
|
|
@@ -839,7 +906,7 @@ bool PMSM_FOC_EnableCruise(bool enable) {
|
|
|
PMSM_FOC_SetErrCode(FOC_NowAllowed_With_Speed);
|
|
|
return false;
|
|
|
}
|
|
|
- eRamp_init_target(&gFoc_Ctrl.in.cruiseRpmRamp, motSpd, CONFIG_ACC_TIME, CONFIG_DEC_TIME);
|
|
|
+ eRamp_init_target2(&gFoc_Ctrl.in.cruiseRpmRamp, motSpd, CONFIG_CRUISE_RAMP_TIME);
|
|
|
gFoc_Ctrl.in.s_cruiseRPM = motSpd;
|
|
|
gFoc_Ctrl.in.b_cruiseEna = enable;
|
|
|
}
|
|
|
@@ -854,7 +921,7 @@ bool PMSM_FOC_PauseCruise(void) {
|
|
|
|
|
|
bool PMSM_FOC_ResumeCruise(void) {
|
|
|
gFoc_Ctrl.in.b_cruiseEna = true;
|
|
|
- eRamp_init_target(&gFoc_Ctrl.in.cruiseRpmRamp, PMSM_FOC_GetSpeed(), CONFIG_ACC_TIME, CONFIG_DEC_TIME);
|
|
|
+ eRamp_init_target2(&gFoc_Ctrl.in.cruiseRpmRamp, PMSM_FOC_GetSpeed(), CONFIG_CRUISE_RAMP_TIME);
|
|
|
eRamp_set_step_target(&gFoc_Ctrl.in.cruiseRpmRamp, gFoc_Ctrl.in.s_cruiseRPM, CONFIG_eCTRL_STEP_TS);
|
|
|
return true;
|
|
|
}
|
|
|
@@ -914,17 +981,21 @@ bool PMSM_FOC_Set_CruiseSpeed(float rpm) {
|
|
|
void PMSM_FOC_MTPA_Calibrate(bool enable) {
|
|
|
if (enable) {
|
|
|
gFoc_Ctrl.in.b_MTPA_calibrate = true;
|
|
|
- gFoc_Ctrl.in.s_manualAngle = 0;
|
|
|
+ gFoc_Ctrl.in.s_dqAngle = 0;
|
|
|
}else {
|
|
|
- gFoc_Ctrl.in.s_manualAngle = INVALID_ANGLE;
|
|
|
+ gFoc_Ctrl.in.s_dqAngle = INVALID_ANGLE;
|
|
|
gFoc_Ctrl.in.b_MTPA_calibrate = false;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-void PMSM_FOC_Set_Angle(float angle) {
|
|
|
+void PMSM_FOC_Set_MotAngle(float angle) {
|
|
|
gFoc_Ctrl.in.s_manualAngle = (angle);
|
|
|
}
|
|
|
|
|
|
+void PMSM_FOC_Set_Dq_Angle(float angle) {
|
|
|
+ gFoc_Ctrl.in.s_dqAngle = (angle);
|
|
|
+}
|
|
|
+
|
|
|
void PMSM_FOC_Get_TgtIDQ(DQ_t * dq) {
|
|
|
dq->d = gFoc_Ctrl.in.s_targetIdq.d;
|
|
|
dq->q = gFoc_Ctrl.in.s_targetIdq.q;
|
|
|
@@ -940,7 +1011,6 @@ void PMSM_FOC_AutoHold(bool lock) {
|
|
|
motor_encoder_lock_pos(lock);
|
|
|
PI_Controller_Reset(&gFoc_Ctrl.pi_lock, 0);
|
|
|
if (!lock) {
|
|
|
- //解锁后为了防止倒溜,需要把当前
|
|
|
if (gFoc_Ctrl.out.n_RunMode == CTRL_MODE_TRQ) {
|
|
|
#ifdef CONFIG_SPEED_LADRC
|
|
|
ladrc_reset(&gFoc_Ctrl.vel_lim_adrc, 0, gFoc_Ctrl.in.s_targetTorque * 1.1f);
|
|
|
@@ -1040,7 +1110,7 @@ void PMSM_FOC_Calc_Current(void) {
|
|
|
LowPass_Filter(gFoc_Ctrl.out.s_CalciDC, raw_idc, 0.1f);
|
|
|
|
|
|
raw_idc = get_vbus_current();
|
|
|
- LowPass_Filter(gFoc_Ctrl.out.s_FilteriDC, raw_idc, 0.1f);
|
|
|
+ LowPass_Filter(gFoc_Ctrl.out.s_FilteriDC, raw_idc, 0.05f);
|
|
|
|
|
|
gFoc_Ctrl.out.s_RealCurrentFiltered = sqrtf(SQ(gFoc_Ctrl.out.s_FilterIdq.d) + SQ(gFoc_Ctrl.out.s_FilterIdq.q));
|
|
|
|