|
@@ -0,0 +1,383 @@
|
|
|
+/************************************************************************
|
|
|
+ Project: Welling Motor Control Paltform
|
|
|
+ Filename: obs.c
|
|
|
+ Partner Filename: obs.h
|
|
|
+ Description: The position and speed observer for PMSM
|
|
|
+ Complier: IAR Embedded Workbench for ARM 7.80, IAR Systems.
|
|
|
+ CPU TYPE : GD32F3x0
|
|
|
+*************************************************************************
|
|
|
+ Copyright (c) 2018 Welling Motor Technology(Shanghai) Co. Ltd.
|
|
|
+ All rights reserved.
|
|
|
+*************************************************************************
|
|
|
+*************************************************************************
|
|
|
+Revising History (ECL of this file):
|
|
|
+
|
|
|
+************************************************************************/
|
|
|
+
|
|
|
+/************************************************************************
|
|
|
+ Beginning of File, do not put anything above here except notes
|
|
|
+ Compiler Directives:
|
|
|
+*************************************************************************/
|
|
|
+#ifndef _OBS_C_
|
|
|
+#define _OBS_C_
|
|
|
+#endif
|
|
|
+
|
|
|
+/************************************************************************
|
|
|
+ Included File:
|
|
|
+*************************************************************************/
|
|
|
+#include "syspar.h"
|
|
|
+#include "user.h"
|
|
|
+
|
|
|
+/************************************************************************
|
|
|
+ Private Variables
|
|
|
+*************************************************************************/
|
|
|
+SWORD obs_pvt_swEMFAlphaCompPu = 0; // Q14, Output stationary alfa-axis EMF value
|
|
|
+SWORD obs_pvt_swEMFBetaCompPu = 0; // Q14, Output stationary beta-axis EMF value
|
|
|
+SLONG obs_pvt_slDeltaErrPu = 0; // Q15, Last delta value for PLL PI control
|
|
|
+
|
|
|
+/************************************************************************
|
|
|
+ Constant Table (N/A)
|
|
|
+*************************************************************************/
|
|
|
+
|
|
|
+/************************************************************************
|
|
|
+ Exported Functions:
|
|
|
+*************************************************************************/
|
|
|
+/***************************************************************
|
|
|
+ Function: obs_voObsInit;
|
|
|
+ Description: observer output initialization
|
|
|
+ Call by:
|
|
|
+ Input Variables: N/A
|
|
|
+ Output/Return Variables: N/A
|
|
|
+ Subroutine Call: N/A;
|
|
|
+ Reference: N/A
|
|
|
+****************************************************************/
|
|
|
+void obs_voObsInit(void)
|
|
|
+{
|
|
|
+ obs_stObsOutPu.slFluxAlphaPu = 0; // Q26
|
|
|
+ obs_stObsOutPu.slFluxBetaPu = 0; // Q26
|
|
|
+ obs_stObsOutPu.swElecFreqPu = 0; // Q15
|
|
|
+ obs_stObsOutPu.slElecFreqPu = 0; // Q29
|
|
|
+ obs_stObsOutPu.uwElecThetaPu = 0; // Q15
|
|
|
+ obs_stObsOutPu.slElecThetaPu = 0; // Q29
|
|
|
+ obs_stObsOutPu.swActiveFluxPu = 0; // Q10
|
|
|
+ obs_stObsOutPu.swFluxAlphaPu = 0; // Q10
|
|
|
+ obs_stObsOutPu.swFluxBetaPu = 0; // Q10
|
|
|
+
|
|
|
+ obs_stFluxAlphaPIOut.slURefPu = 0; // Q28
|
|
|
+ obs_stFluxAlphaPIOut.swURefPu = 0; // Q14
|
|
|
+ obs_stFluxAlphaPIOut.swErrZ1Pu = 0; // Q10
|
|
|
+
|
|
|
+ obs_stFluxBetaPIOut.slURefPu = 0; // Q28
|
|
|
+ obs_stFluxBetaPIOut.swURefPu = 0; // Q14
|
|
|
+ obs_stFluxBetaPIOut.swErrZ1Pu = 0; // Q10
|
|
|
+
|
|
|
+ obs_pvt_swEMFAlphaCompPu = 0;
|
|
|
+ obs_pvt_swEMFBetaCompPu = 0;
|
|
|
+ obs_pvt_slDeltaErrPu = 0;
|
|
|
+}
|
|
|
+
|
|
|
+/***************************************************************
|
|
|
+ Function: obs_voObsCoef;
|
|
|
+ Description: Coefficient calculation for "asr_voSpdPI"
|
|
|
+ Call by: functions in main loop;
|
|
|
+ Input Variables: ASR_SPDPI_COFIN
|
|
|
+ Output/Return Variables: ASR_SPDPI_COF
|
|
|
+ Subroutine Call: N/A;
|
|
|
+ Reference: N/A
|
|
|
+****************************************************************/
|
|
|
+void obs_voObsCoef(OBS_COF_IN *in, OBS_COF *out)
|
|
|
+{
|
|
|
+ UWORD uwWebRadps;
|
|
|
+ UWORD uwMvcPu;
|
|
|
+ ULONG ulDamper;
|
|
|
+ UWORD uwDamper;
|
|
|
+ ULONG ulKp;
|
|
|
+ ULONG ulKi;
|
|
|
+ UWORD uwDampingRatio;
|
|
|
+ UWORD uwCrossFreq;
|
|
|
+
|
|
|
+ if (in->uwRbOm < 10)
|
|
|
+ {
|
|
|
+ in->uwRbOm = 10;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (in->uwLbHm < 10)
|
|
|
+ {
|
|
|
+ in->uwLbHm = 10;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (in->uwFluxbWb < 10)
|
|
|
+ {
|
|
|
+ in->uwFluxbWb = 10;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (in->uwFbHz < 10)
|
|
|
+ {
|
|
|
+ in->uwFbHz = 10;
|
|
|
+ }
|
|
|
+ else if (in->uwFbHz > 10000)
|
|
|
+ {
|
|
|
+ in->uwFbHz = 10000;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (in->uwFreqTbcHz < 10)
|
|
|
+ {
|
|
|
+ in->uwFreqTbcHz = 10;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (in->uwSpdPllMcoef > 100)
|
|
|
+ {
|
|
|
+ in->uwSpdPllMcoef = 100;
|
|
|
+ }
|
|
|
+
|
|
|
+ if ((in->uwFluxWb >> 5) > in->uwFluxbWb)
|
|
|
+ {
|
|
|
+ in->uwFluxWb = (in->uwFluxbWb << 5);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (in->uwRsOm > in->uwRbOm)
|
|
|
+ {
|
|
|
+ in->uwRsOm = in->uwRbOm;
|
|
|
+ }
|
|
|
+
|
|
|
+ if ((in->uwLqHm >> 5) > in->uwLbHm)
|
|
|
+ {
|
|
|
+ in->uwLqHm = (in->uwLbHm << 5);
|
|
|
+ }
|
|
|
+
|
|
|
+ if ((in->uwLdHm >> 5) > in->uwLbHm)
|
|
|
+ {
|
|
|
+ in->uwLdHm = (in->uwLbHm << 5);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (in->uwFbHz > ((ULONG)in->uwFreqTbcHz * 0x2AAA >> 15))
|
|
|
+ {
|
|
|
+ in->uwFbHz = (ULONG)in->uwFreqTbcHz * 0x2AAA >> 15;
|
|
|
+ }
|
|
|
+
|
|
|
+ uwWebRadps = (ULONG)2 * 31416 * in->uwFbHz / 10000; // unit: rad/s, Electrical radian frequency base
|
|
|
+
|
|
|
+ if (in->uwFluxDampingRatio < 1)
|
|
|
+ {
|
|
|
+ in->uwFluxDampingRatio = 1;
|
|
|
+ }
|
|
|
+ else if (in->uwFluxDampingRatio > 100)
|
|
|
+ {
|
|
|
+ in->uwFluxDampingRatio = 100;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (in->uwFluxCrossFreqHz < 1)
|
|
|
+ {
|
|
|
+ in->uwFluxCrossFreqHz = 1;
|
|
|
+ }
|
|
|
+ else if (in->uwFluxCrossFreqHz > 100)
|
|
|
+ {
|
|
|
+ in->uwFluxCrossFreqHz = 100;
|
|
|
+ }
|
|
|
+
|
|
|
+ out->uwFluxPPu = ((ULONG)in->uwFluxWb << 10) / in->uwFluxbWb; // Q10
|
|
|
+ out->uwRsPu = ((ULONG)in->uwRsOm << 15) / in->uwRbOm; // Q15
|
|
|
+ out->uwLqPu = ((ULONG)in->uwLqHm << 10) / in->uwLbHm; // Q10
|
|
|
+ out->uwLdPu = ((ULONG)in->uwLdHm << 10) / in->uwLbHm; // Q10
|
|
|
+ out->uwCurTsPu = ((ULONG)205887 * in->uwFbHz) / in->uwFreqTbcHz; // Q15, Q15(2pi)-->205887
|
|
|
+ out->uwCurTs = ((ULONG)in->uwFbHz << 10) / in->uwFreqTbcHz; // Q10, TBC time
|
|
|
+
|
|
|
+ /************************Speed PLL Coefficient*****************************/
|
|
|
+ uwMvcPu = ((ULONG)in->uwSpdPllWvcHz << 10) / in->uwFbHz; // Q10
|
|
|
+
|
|
|
+ /* PLL Kp=M*w/sqrt(1+M^2) */
|
|
|
+ ulDamper = (1 + in->uwSpdPllMcoef * in->uwSpdPllMcoef) << 8; // Q8
|
|
|
+ uwDamper = mth_slSqrt(ulDamper); // Q4
|
|
|
+ out->uwSpdPllKpPu = ((ULONG)in->uwSpdPllMcoef * uwMvcPu / uwDamper) << 8; // Q10-Q4+Q8=Q14
|
|
|
+
|
|
|
+ /* PLL Ki=w^2*T_cnt_ctrl/sqrt(1+M^2) */
|
|
|
+ out->uwSpdPllKiPu = ((((ULONG)uwMvcPu * out->uwCurTsPu) / uwDamper) * uwMvcPu) >> 17; // Q10+Q15-Q4+Q10-Q17=Q14
|
|
|
+
|
|
|
+ /**************************Flux PI Coefficient*****************************/
|
|
|
+ /* Flux PI regulator Kp=2*k*w */
|
|
|
+ uwDampingRatio = ((ULONG)in->uwFluxDampingRatio << 12) / 10; // Q12
|
|
|
+ uwCrossFreq = ((ULONG)2 * 31416 * in->uwFluxCrossFreqHz / 10000) << 8; // Q8
|
|
|
+
|
|
|
+ ulKp = (ULONG)uwDampingRatio * uwCrossFreq * 2; // Q12+Q8=Q20
|
|
|
+ out->uwFluxKpPu = ulKp / uwWebRadps >> 2; // Q20-Q2=Q18
|
|
|
+
|
|
|
+ /* Flux PI regulator Ki=w^2 */
|
|
|
+ ulKi = (ULONG)uwCrossFreq * uwCrossFreq; // Q8+Q8=Q16
|
|
|
+ out->uwFluxKitPu = (ulKi / uwWebRadps * out->uwCurTsPu / uwWebRadps) >> 3; // Q16+Q15-Q3=Q28
|
|
|
+}
|
|
|
+
|
|
|
+/***************************************************************
|
|
|
+ Function: obs_voObsCalc
|
|
|
+ Description: speed and position caculate
|
|
|
+ Call by: tbc_it
|
|
|
+ Input Variables:
|
|
|
+ Output/Return Variables:
|
|
|
+ Subroutine Call:
|
|
|
+ Reference: N/A
|
|
|
+****************************************************************/
|
|
|
+void obs_voObsCalc(OBS_IN *in, OBS_COF *coef, OBS_OUT *out)
|
|
|
+{
|
|
|
+ SWORD swEMFAlphaPu, swEMFBetaPu;
|
|
|
+ SWORD swRtFluxAlphaPu, swRtFluxBetaPu;
|
|
|
+ SINCOS sincosTmp; //, sincosTmp1;
|
|
|
+ SLONG slDeltaTmpPu, slDeltaErrTmpPu;
|
|
|
+ SLONG slKpTmpPu, slKitTmpPu;
|
|
|
+ SLONG slSpdRefPu;
|
|
|
+ SLONG slPreRtPosPu, slActRtPosPu;
|
|
|
+ UWORD uwPreRtPosPu;
|
|
|
+ SWORD swFluxDPu, swFluxQPu;
|
|
|
+ SWORD swMaxVsPu;
|
|
|
+
|
|
|
+ /*****************************Current Model*****************************/
|
|
|
+ /* Predict the rotor Angle according to last rotor angle and speed */
|
|
|
+ slPreRtPosPu = out->slElecThetaPu + ((out->slElecFreqPu >> 10) * coef->uwCurTs); // Q29-Q10+Q10=Q29
|
|
|
+ if (slPreRtPosPu >= 0x20000000) // Q29
|
|
|
+ {
|
|
|
+ slPreRtPosPu -= 0x20000000;
|
|
|
+ }
|
|
|
+ else if (slPreRtPosPu < 0)
|
|
|
+ {
|
|
|
+ slPreRtPosPu += 0x20000000;
|
|
|
+ }
|
|
|
+ uwPreRtPosPu = (UWORD)(slPreRtPosPu >> 14); // Q29-Q14=Q15
|
|
|
+ mth_voSinCos(uwPreRtPosPu, &sincosTmp);
|
|
|
+
|
|
|
+ /* Current Park (I_alpha I_beta -> Id Iq) */
|
|
|
+ obs_stParkInPu.swAlphaPu = in->swIalphaPu; // Q14
|
|
|
+ obs_stParkInPu.swBetaPu = in->swIbetaPu; // Q14
|
|
|
+ obs_stParkInPu.uwThetaPu = uwPreRtPosPu; // Q15
|
|
|
+ crd_voPark(&obs_stParkInPu, &obs_stFluxParkPu);
|
|
|
+
|
|
|
+ /* Flux_D = Ld*id+Flux_PM; Flux_Q = Lq*iq */
|
|
|
+ swFluxDPu = coef->uwFluxPPu + (((SLONG)obs_stFluxParkPu.swDPu * coef->uwLdPu) >> 14); // Q14+Q10-Q14=Q10
|
|
|
+ swFluxQPu = ((SLONG)obs_stFluxParkPu.swQPu * coef->uwLqPu) >> 14; // Q14+Q10-Q14=Q10
|
|
|
+
|
|
|
+ /* Flux IPark (Fluxd Fluxq -> Fluxalpha Fluxbeta) */
|
|
|
+ obs_stIParkInPu.swDPu = swFluxDPu; // Q10
|
|
|
+ obs_stIParkInPu.swQPu = swFluxQPu; // Q10
|
|
|
+ obs_stIParkInPu.uwThetaPu = uwPreRtPosPu; // Q15
|
|
|
+ crd_voIPark(&obs_stIParkInPu, &obs_stFluxIParkPu);
|
|
|
+
|
|
|
+ /*****************************Voltage Model*****************************/
|
|
|
+ swEMFAlphaPu = in->swUalphaPu - (in->swIalphaPu * coef->uwRsPu >> 15); // Q14+Q15-Q15=Q14
|
|
|
+ swEMFBetaPu = in->swUbetaPu - (in->swIbetaPu * coef->uwRsPu >> 15); // Q14+Q15-Q15=Q14
|
|
|
+
|
|
|
+ obs_pvt_swEMFAlphaCompPu = swEMFAlphaPu + obs_stFluxAlphaPIOut.swURefPu; // Q14
|
|
|
+ obs_pvt_swEMFBetaCompPu = swEMFBetaPu + obs_stFluxBetaPIOut.swURefPu; // Q14
|
|
|
+
|
|
|
+ out->slFluxAlphaPu = out->slFluxAlphaPu + ((SLONG)obs_pvt_swEMFAlphaCompPu * coef->uwCurTsPu >> 3); // Q14+Q15-Q3=Q26
|
|
|
+ out->slFluxBetaPu = out->slFluxBetaPu + ((SLONG)obs_pvt_swEMFBetaCompPu * coef->uwCurTsPu >> 3); // Q14+Q15-Q3=Q26
|
|
|
+ out->swFluxAlphaPu = out->slFluxAlphaPu >> 16; // Q26-Q16=Q10
|
|
|
+ out->swFluxBetaPu = out->slFluxBetaPu >> 16; // Q26-Q16=Q10
|
|
|
+
|
|
|
+ swMaxVsPu = ((SLONG)in->uwVdcPu * 0x5555) >> 15; // Q14+Q15-Q15=Q14
|
|
|
+
|
|
|
+ /* Flux alpha PI regulator */
|
|
|
+ obs_stFluxAlphaPIIn.swRefPu = obs_stFluxIParkPu.swAlphaPu; // Q10
|
|
|
+ obs_stFluxAlphaPIIn.swFdbPu = out->swFluxAlphaPu; // Q10
|
|
|
+ obs_stFluxAlphaPIIn.swUmaxPu = swMaxVsPu; // Q14
|
|
|
+ obs_stFluxAlphaPIIn.swUminPu = -swMaxVsPu; // Q14
|
|
|
+ obs_stFluxAlphaPICoef.uwFluxKpPu = coef->uwFluxKpPu; // Q18
|
|
|
+ obs_stFluxAlphaPICoef.uwFluxKitPu = coef->uwFluxKitPu; // Q28
|
|
|
+ obs_voFluxPI(&obs_stFluxAlphaPIIn, &obs_stFluxAlphaPICoef, &obs_stFluxAlphaPIOut);
|
|
|
+
|
|
|
+ /* Flux beta PI regulator */
|
|
|
+ obs_stFluxBetaPIIn.swRefPu = obs_stFluxIParkPu.swBetaPu; // Q10
|
|
|
+ obs_stFluxBetaPIIn.swFdbPu = out->swFluxBetaPu; // Q10
|
|
|
+ obs_stFluxBetaPIIn.swUmaxPu = swMaxVsPu; // Q14
|
|
|
+ obs_stFluxBetaPIIn.swUminPu = -swMaxVsPu; // Q14
|
|
|
+ obs_stFluxBetaPICoef.uwFluxKpPu = coef->uwFluxKpPu; // Q18
|
|
|
+ obs_stFluxBetaPICoef.uwFluxKitPu = coef->uwFluxKitPu; // Q28
|
|
|
+ obs_voFluxPI(&obs_stFluxBetaPIIn, &obs_stFluxBetaPICoef, &obs_stFluxBetaPIOut);
|
|
|
+
|
|
|
+ /* Stator Flux -> Rotor Flux */
|
|
|
+ swRtFluxAlphaPu = out->swFluxAlphaPu - (((SLONG)in->swIalphaPu * coef->uwLqPu) >> 14); // Q14+Q10-Q14=Q10
|
|
|
+ swRtFluxBetaPu = out->swFluxBetaPu - (((SLONG)in->swIbetaPu * coef->uwLqPu) >> 14); // Q14+Q10-Q14=Q10
|
|
|
+
|
|
|
+ /* PLL to trace the latest speed */
|
|
|
+ slDeltaTmpPu = (((SLONG)swRtFluxBetaPu * sincosTmp.swCosPu) - ((SLONG)swRtFluxAlphaPu * sincosTmp.swSinPu)) >> 10; // Q10+Q15-Q10=Q15
|
|
|
+ slDeltaErrTmpPu = slDeltaTmpPu - obs_pvt_slDeltaErrPu; // Q15
|
|
|
+ obs_pvt_slDeltaErrPu = slDeltaTmpPu; // Q15
|
|
|
+ slKpTmpPu = slDeltaErrTmpPu * coef->uwSpdPllKpPu; // Q15+Q14=Q29
|
|
|
+ slKitTmpPu = slDeltaTmpPu * coef->uwSpdPllKiPu; // Q15+Q14=Q29
|
|
|
+ slSpdRefPu = slKpTmpPu + slKitTmpPu + out->slElecFreqPu; // Q29
|
|
|
+
|
|
|
+ /* Limit the speed value to avoid overflow */
|
|
|
+ if (slSpdRefPu >= 0x20000000)
|
|
|
+ {
|
|
|
+ slSpdRefPu = 0x20000000 - 1; // Q29
|
|
|
+ }
|
|
|
+ else if (slSpdRefPu <= -0x20000000)
|
|
|
+ {
|
|
|
+ slSpdRefPu = -0x20000000; // Q29
|
|
|
+ }
|
|
|
+ out->slElecFreqPu = slSpdRefPu; // Q29
|
|
|
+ out->swElecFreqPu = out->slElecFreqPu >> 14; // Q29-Q14=Q15
|
|
|
+ /* Electrical speed to Electrical position */
|
|
|
+ // slActRtPosPu = out->slElecThetaPu + ((((slSpdRefPu + out->slElecFreqPu) >> 1) >> 10) * coef->uwCurTs); //Q29+Q10-Q10=Q29
|
|
|
+ slActRtPosPu = out->slElecThetaPu + (((SLONG)out->swElecFreqPu * coef->uwCurTs) << 4);
|
|
|
+ if (slActRtPosPu >= 0x20000000)
|
|
|
+ {
|
|
|
+ slActRtPosPu -= 0x20000000; // Q15+Q14=Q29
|
|
|
+ }
|
|
|
+ else if (slActRtPosPu < 0)
|
|
|
+ {
|
|
|
+ slActRtPosPu += 0x20000000; // Q15+Q14=Q29
|
|
|
+ }
|
|
|
+ out->slElecThetaPu = slActRtPosPu; // Q29
|
|
|
+ out->uwElecThetaPu = out->slElecThetaPu >> 14; // Q29-Q14=Q15
|
|
|
+
|
|
|
+ // mth_voSinCos(out->uwElecThetaPu, &sincosTmp1);
|
|
|
+ // slActiveFluxPu = (SLONG)swRtFluxAlphaPu * sincosTmp1.swCosPu + (SLONG)swRtFluxBetaPu * sincosTmp1.swSinPu; //Q10+Q15=Q25
|
|
|
+ // out->swActiveFluxPu = slActiveFluxPu >> 15; //Q25-Q15=Q10
|
|
|
+ // //Q29-Q14=Q15
|
|
|
+}
|
|
|
+/***************************************************************
|
|
|
+ Function: obs_voFluxPI;
|
|
|
+ Description: Flux PI regulator;
|
|
|
+ Call by: functions in TBC;
|
|
|
+ Input Variables: ACR_CURPI_IN,ACR_CURPI_COF
|
|
|
+ Output/Return Variables: ACR_CURPI_OUT
|
|
|
+ Subroutine Call: N/A;
|
|
|
+ Reference: N/A
|
|
|
+****************************************************************/
|
|
|
+void obs_voFluxPI(OBS_FLUXPI_IN *in, OBS_FLUXPI_COF *coef, OBS_FLUXPI_OUT *out)
|
|
|
+{
|
|
|
+ SWORD tmp_swErrPu, tmp_swDeltaErrPu;
|
|
|
+ SLONG tmp_slUpPu, tmp_slUiPu, tmp_slURefPu;
|
|
|
+ SLONG tmp_slUmaxPu, tmp_slUminPu;
|
|
|
+
|
|
|
+ /* U(k) = U(k-1) + Kp * (Err(k) - Err(k-1)) + Kit * Err(k) */
|
|
|
+ tmp_swErrPu = in->swRefPu - in->swFdbPu; // Q10
|
|
|
+ tmp_swDeltaErrPu = tmp_swErrPu - out->swErrZ1Pu; // Q10
|
|
|
+ tmp_slUpPu = (SLONG)tmp_swDeltaErrPu * coef->uwFluxKpPu; // Q10+Q18=Q28
|
|
|
+ tmp_slUiPu = ((SLONG)tmp_swErrPu * coef->uwFluxKitPu) >> 10; // Q10+Q28-Q10=Q28
|
|
|
+ tmp_slURefPu = out->slURefPu + tmp_slUpPu + tmp_slUiPu; // Q28
|
|
|
+ tmp_slUmaxPu = (SLONG)in->swUmaxPu << 14; // Q14+Q14=Q28
|
|
|
+ tmp_slUminPu = (SLONG)in->swUminPu << 14; // Q14+Q14=Q28
|
|
|
+ if (tmp_slURefPu > tmp_slUmaxPu)
|
|
|
+ {
|
|
|
+ tmp_slURefPu = tmp_slUmaxPu;
|
|
|
+ }
|
|
|
+ else if (tmp_slURefPu < tmp_slUminPu)
|
|
|
+ {
|
|
|
+ tmp_slURefPu = tmp_slUminPu;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {}
|
|
|
+ out->swURefPu = tmp_slURefPu >> 14; // Q28-Q14=Q14
|
|
|
+ out->slURefPu = tmp_slURefPu; // Q28
|
|
|
+ out->swErrZ1Pu = tmp_swErrPu; // Q10
|
|
|
+}
|
|
|
+
|
|
|
+/************************************************************************
|
|
|
+ Copyright (c) 2018 Welling Motor Technology(Shanghai) Co. Ltd.
|
|
|
+ All rights reserved.
|
|
|
+*************************************************************************/
|
|
|
+#ifdef _OBS_C_
|
|
|
+#undef _OBS_C_
|
|
|
+#endif
|
|
|
+/*************************************************************************
|
|
|
+ End of this File (EOF):
|
|
|
+ !!!!!!Do not put anything after this part!!!!!!!!!!!
|
|
|
+*************************************************************************/
|