Selaa lähdekoodia

feat():完成powerlimit解封,编译通过

CN\zhangkai71 4 kuukautta sitten
vanhempi
sitoutus
c73e66ffbc

BIN
User project/2.MotorDrive/Lib/WLMCP_LIB.lib


+ 1 - 1
User project/2.MotorDrive/Source/packed

@@ -1 +1 @@
-Subproject commit 3bc9db31141c162b2fd8d52f9de4649740ebe48c
+Subproject commit e75c0fee19c174f082eedbb982a441bf6c2241ea

+ 354 - 0
User project/2.MotorDrive/Source/pwrlim.c

@@ -0,0 +1,354 @@
+/************************************************************************
+ Project:             Welling Motor Control Paltform
+ Filename:            pwrlim.c
+ Partner Filename:    pwrlim.h
+ Description:         Motor input power limit
+ 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):
+Fjy create this file;
+************************************************************************/
+
+/************************************************************************
+ Beginning of File, do not put anything above here except notes
+ Compiler Directives:
+*************************************************************************/
+#ifndef _PWRLIM_C_
+#define _PWRLIM_C_
+#endif
+
+/************************************************************************
+Include File
+************************************************************************/
+#include "user.h"
+
+/************************************************************************
+Constant Table:
+************************************************************************/
+
+/************************************************************************
+ Private Variables
+*************************************************************************/
+
+/************************************************************************
+Exported Functions:
+************************************************************************/
+/************************************************************************
+ Function: pwr_voPwrLimInit;
+ Description: Initialize Variables for "pwr_voPwrLim"
+ Call by:
+ Input Variables:
+ Output/Return Variables:
+ Subroutine Call:
+ Reference:
+************************************************************************/
+void pwr_voPwrLimInit(void)
+{
+    pwr_stPwrLimOut.swIqLimPu      = (SWORD)cof_uwCurMaxPu;
+    pwr_stPwrLimOut.swPwrErrZ1     = 0;
+    pwr_stPwrLimOut.slIqLimDetaSum = 0;
+    pwr_stPwrLimOut.swIqLimDetaSum = 0;
+    pwr_stPwrLimOut.swIqLimPu      = 0;
+
+    pwr_stPwrLimOut2.slIqLimDetaSum   = 0;
+    pwr_stPwrLimOut2.swIqLimDetaSum   = 0;
+    pwr_stPwrLimOut2.swPwrErrZ1       = 0;
+    pwr_stPwrLimOut2.swPwrLimActualPu = (SWORD)cof_uwPwrMaxPu;
+    pwr_stPwrLimOut2.swIqLimPu        = 0;
+}
+
+/************************************************************************
+Function: pwr_voPwrLimCof;
+Description: Coefficient calculation for "pwr_voPwrLim"
+Call by:
+Input Variables:
+Output/Return Variables:
+Subroutine Call:
+Reference:
+************************************************************************/
+void pwr_voPwrLimCof(PWRLIM_COFIN *in, PWRLIM_COF *out)
+{
+    UWORD uwPwrLim;
+    ULONG ulPbWt;
+
+    if (in->uwIBaseAp > 32767)
+    {
+        in->uwIBaseAp = 32767;
+    }
+    else if (in->uwIBaseAp < 1)
+    {
+        in->uwIBaseAp = 1;
+    }
+    else
+    {
+        // do nothing
+    }
+
+    if (in->uwUbVt < 100)
+    {
+        in->uwUbVt = 100;
+    }
+    else {}
+
+    if (in->swPwrLimW > 30000)
+    {
+        in->swPwrLimW = 30000;
+    }
+    else if (in->swPwrLimW < 100)
+    {
+        in->swPwrLimW = 100;
+    }
+    else
+    {
+        // do noting
+    }
+    if (in->uwPwrErrW < 20)
+    {
+        in->uwPwrErrW = 20;
+    }
+    else if (in->uwPwrErrW >= in->swPwrLimW)
+    {
+        in->uwPwrErrW = in->swPwrLimW - 10;
+    }
+    else
+    {
+        // do noting
+    }
+
+    if (in->swIqMaxAp > in->uwIBaseAp)
+    {
+        in->swIqMaxAp = (SWORD)in->uwIBaseAp;
+    }
+    else if (in->swIqMaxAp < 1)
+    {
+        in->swIqMaxAp = 1;
+    }
+    else
+    {
+        // do nothing
+    }
+
+    out->swIqMaxPu = (SWORD)(((SLONG)in->swIqMaxAp << 14) / (SLONG)in->uwIBaseAp); // Q14, Max phase current (peak value)
+
+    ulPbWt = ((ULONG)3 * in->uwUbVt * in->uwIBaseAp / 100) >> 1; // Q0, unit: 0.1w, Power base
+
+    uwPwrLim        = (UWORD)(((ULONG)in->uwPwrErrW << 15) / ulPbWt);   // Q15
+    out->uwPwrLimKp = (UWORD)(((ULONG)out->swIqMaxPu << 6) / uwPwrLim); // 14+6-15=Q5
+
+    if (in->swPwrLimW > ((SWORD)in->uwPwrErrW))
+    {
+        out->swPwrLimPu = (SWORD)((((SLONG)in->swPwrLimW - (SLONG)in->uwPwrErrW) << 15) / (SLONG)ulPbWt); // Q15
+    }
+    else
+    {
+        out->swPwrLimPu = 0;
+    }
+
+    out->swPwrLimStartTemp = (SWORD)in->swPwrLimStartTempCe;
+    out->swPwrLimEndTemp   = (SWORD)((in->swAlarmTempCe + in->swPwrLimStartTempCe) >> 1);
+    out->swPwrLimTempCof   = (out->swPwrLimPu >> 1) / (out->swPwrLimEndTemp - out->swPwrLimStartTemp); 
+    out->swIqLimTempCof =
+        ((SLONG)out->swIqMaxPu * 83 >> 7) / (out->swPwrLimEndTemp - out->swPwrLimStartTemp);   ///< 0.65=83>>7
+
+    out->uwPwrLimStartBatCap = 20;
+    out->uwPwrLimEndBatCap   = 5;
+    out->uwPwrlimBatCapCof =
+        ((SLONG)out->swPwrLimPu * 3 >> 2) / (out->uwPwrLimStartBatCap - out->uwPwrLimEndBatCap); 
+
+    out->uwPwrLimPIKp = in->uwPwrLimPIKp; // Q15
+    out->uwPwrLimPIKi = in->uwPwrLimPIKi; // Q15
+}
+
+/************************************************************************
+Function: pwr_voPwrLim;
+Description: Power Limit Using Kp;
+Call by:
+Input Variables:
+Output/Return Variables:
+Subroutine Call:
+Reference:
+************************************************************************/
+void pwr_voPwrLim(const PWRLIM_IN *in, const PWRLIM_COF *cof, PWRLIM_OUT *out)
+{
+    SWORD swEmPwLimIqPu; // Q14
+
+    if (in->swMotorPwrPu > cof->swPwrLimPu)
+    {
+        if (in->swSpdPu >= 0)
+        {
+            swEmPwLimIqPu =
+                (SWORD)(((SLONG)cof->swPwrLimPu - (SLONG)in->swMotorPwrPu) * (SLONG)cof->uwPwrLimKp >> 6) + cof->swIqMaxPu; // Q15+Q5-Q6=Q14
+            if (swEmPwLimIqPu > cof->swIqMaxPu)
+            {
+                swEmPwLimIqPu = cof->swIqMaxPu;
+            }
+            else if (swEmPwLimIqPu < 0)
+            {
+                swEmPwLimIqPu = 0;
+            }
+            else
+            {
+                // do nothing
+            }
+            out->swIqLimPu = swEmPwLimIqPu;
+        }
+        else
+        {
+            swEmPwLimIqPu = (SWORD)((((SLONG)in->swMotorPwrPu - cof->swPwrLimPu) * (SWORD)cof->uwPwrLimKp >> 6) - cof->swIqMaxPu); // Q14
+            if (swEmPwLimIqPu < -cof->swIqMaxPu)
+            {
+                swEmPwLimIqPu = -cof->swIqMaxPu;
+            }
+            else if (swEmPwLimIqPu > 0)
+            {
+                swEmPwLimIqPu = 0;
+            }
+            else
+            {
+                // do nothing
+            }
+            out->swIqLimPu = swEmPwLimIqPu;
+        }
+    }
+    else
+    {
+        if (in->swSpdPu >= 0)
+        {
+            out->swIqLimPu = cof->swIqMaxPu;
+        }
+        else
+        {
+            out->swIqLimPu = -cof->swIqMaxPu;
+        }
+    }
+}
+
+/************************************************************************
+Function: pwr_voPwrLim;
+Description: Power Limit Using Kp and Ki;
+Call by:
+Input Variables:
+Output/Return Variables:
+Subroutine Call:
+Reference:
+************************************************************************/
+void pwr_voPwrLimPI(const PWRLIM_IN *in, const PWRLIM_COF *cof, PWRLIM_OUT *out)
+{
+    SWORD swError, swErrorDeta;                                                     ///< Q14
+    SLONG slError;                                                                  ///< Q15
+    SLONG slIqLimDetaP, slIqLimDetaI, slIqLimSum;                                   ///< Q30
+    SWORD swPwrLimActualPu1 = cof->swPwrLimPu, swPwrLimActualPu2 = cof->swPwrLimPu; ///< Q15
+    SWORD swIqlimPu1 = cof->swIqMaxPu, swIqlimPu2 = cof->swIqMaxPu;                 ///< Q14
+
+    /* 根据温度限制功率,电机测试模式开放 */
+    if (cp_stFlg.RunModelSelect == ClZLOOP)
+    {
+        if (in->swPCBTemp < cof->swPwrLimStartTemp)
+        {
+            swPwrLimActualPu1 = cof->swPwrLimPu;
+        }
+        else if (in->swPCBTemp < cof->swPwrLimEndTemp)
+        {
+            swPwrLimActualPu1 = cof->swPwrLimPu - ((in->swPCBTemp - cof->swPwrLimStartTemp) * cof->swPwrLimTempCof);
+        }
+        else
+        {
+            swPwrLimActualPu1 = cof->swPwrLimPu >> 1; ///< EndTemp时限制为1/2的功率
+        }
+    }
+
+    /* 根据电池电量限制功率 */
+    if (in->uwBatCap > cof->uwPwrLimStartBatCap)
+    {
+        swPwrLimActualPu2 = cof->swPwrLimPu;
+    }
+    else if (in->uwBatCap > cof->uwPwrLimEndBatCap)
+    {
+        swPwrLimActualPu2 = cof->swPwrLimPu - ((cof->uwPwrLimStartBatCap - in->uwBatCap) * cof->uwPwrlimBatCapCof);
+    }
+    else
+    {
+        swPwrLimActualPu2 = cof->swPwrLimPu >> 2; ///< EndTemp时限制为1/4的功率
+    }
+
+    out->swPwrLimActualPu = (swPwrLimActualPu1 < swPwrLimActualPu2) ? swPwrLimActualPu1 : swPwrLimActualPu2;
+
+    /* 根据PCB温度限制电流 */
+    if (cp_stFlg.RunModelSelect == CityBIKE || cp_stFlg.RunModelSelect == MountainBIKE)
+    {
+        if (in->swPCBTemp < cof->swPwrLimStartTemp)
+        {
+            swIqlimPu1 = cof->swIqMaxPu;
+        }
+        else if (in->swPCBTemp < cof->swPwrLimEndTemp)
+        {
+            swIqlimPu1 = cof->swIqMaxPu - ((SLONG)(in->swPCBTemp - cof->swPwrLimStartTemp) * cof->swIqLimTempCof);
+        }
+        else
+        {
+            swIqlimPu1 = (SWORD)((SLONG)cof->swIqMaxPu * 45 >> 7); ///< EndTemp时限制为额定电流=0.35*最大电流
+        }
+    }
+
+    /* 功率限制PI调节:根据功率限制电流 */
+    slError = out->swPwrLimActualPu - in->swMotorPwrPu;
+    if (slError >= 32768)
+    {
+        slError = 32768;
+    }
+    else if (slError < -32768)
+    {
+        slError = -32768;
+    }
+    else
+    {
+        // do nothing
+    }
+
+    swError         = (SWORD)slError;
+    swErrorDeta     = swError - out->swPwrErrZ1;
+    out->swPwrErrZ1 = swError;
+    slIqLimDetaP    = (SLONG)cof->uwPwrLimPIKp * swErrorDeta; ///< Q15+Q15=Q30
+    slIqLimDetaI    = (SLONG)cof->uwPwrLimPIKi * swError;     ///< Q15+Q15=Q30
+    slIqLimSum      = out->slIqLimDetaSum + slIqLimDetaP + slIqLimDetaI;
+
+    if (slIqLimSum > 0)
+    {
+        out->slIqLimDetaSum = 0;
+    }
+    else if (slIqLimSum < -((SLONG)cof->swIqMaxPu << 16))
+    {
+        out->slIqLimDetaSum = -((SLONG)cof->swIqMaxPu << 16);
+    }
+    else
+    {
+        out->slIqLimDetaSum = slIqLimSum; ///< Q30
+    }
+    out->swIqLimDetaSum = (SWORD)(out->slIqLimDetaSum >> 16); ///< Q30-Q16=Q14
+
+    swIqlimPu2 = cof->swIqMaxPu + out->swIqLimDetaSum;
+
+    /* 电流限制值输出 */
+    out->swIqLimPu = (swIqlimPu1 < swIqlimPu2) ? swIqlimPu1 : swIqlimPu2;
+}
+
+/************************************************************************
+Local Functions (N/A)
+************************************************************************/
+
+/************************************************************************
+Copyright (c) 2018 Welling Motor Technology(Shanghai) Co. Ltd.
+All rights reserved.
+************************************************************************/
+#ifdef _PWRLIM_C_
+#undef _PWRLIM_C_ /* parasoft-suppress MISRA2004-19_6 "本项目中无法更改,后续避免使用" */
+#endif
+/************************************************************************
+End of this File (EOF)!
+Do not put anything after this part!
+************************************************************************/

+ 9 - 3
WLMCP.ewp

@@ -2629,9 +2629,6 @@
                     <file>
                         <name>$PROJ_DIR$\User project\2.MotorDrive\Source\packed\obs.c</name>
                     </file>
-                    <file>
-                        <name>$PROJ_DIR$\User project\2.MotorDrive\Source\packed\pwrlim.c</name>
-                    </file>
                     <file>
                         <name>$PROJ_DIR$\User project\2.MotorDrive\Source\packed\torqobs.c</name>
                     </file>
@@ -2645,6 +2642,9 @@
                 <file>
                     <name>$PROJ_DIR$\User project\2.MotorDrive\Source\pwm.c</name>
                 </file>
+                <file>
+                    <name>$PROJ_DIR$\User project\2.MotorDrive\Source\pwrlim.c</name>
+                </file>
                 <file>
                     <name>$PROJ_DIR$\User project\2.MotorDrive\Source\spdctrFSM.c</name>
                 </file>
@@ -2699,6 +2699,9 @@
                 <file>
                     <name>$PROJ_DIR$\User project\3.BasicFunction\Include\flash_master.h</name>
                 </file>
+                <file>
+                    <name>$PROJ_DIR$\User project\3.BasicFunction\Include\giant_can.h</name>
+                </file>
                 <file>
                     <name>$PROJ_DIR$\User project\3.BasicFunction\Include\i2c_master.h</name>
                 </file>
@@ -2771,6 +2774,9 @@
                 <file>
                     <name>$PROJ_DIR$\User project\3.BasicFunction\Source\flash_master.c</name>
                 </file>
+                <file>
+                    <name>$PROJ_DIR$\User project\3.BasicFunction\Source\giant_can.c</name>
+                </file>
                 <file>
                     <name>$PROJ_DIR$\User project\3.BasicFunction\Source\i2c_master.c</name>
                 </file>

+ 0 - 3
WLMCP_LIB.ewp

@@ -2153,9 +2153,6 @@
         <file>
             <name>$PROJ_DIR$\User project\2.MotorDrive\Source\packed\obs.c</name>
         </file>
-        <file>
-            <name>$PROJ_DIR$\User project\2.MotorDrive\Source\packed\pwrlim.c</name>
-        </file>
         <file>
             <name>$PROJ_DIR$\User project\2.MotorDrive\Source\packed\torqobs.c</name>
         </file>

+ 3 - 0
WLMCP_PACKED.ewp

@@ -2603,6 +2603,9 @@
                 <file>
                     <name>$PROJ_DIR$\User project\2.MotorDrive\Source\pwm.c</name>
                 </file>
+                <file>
+                    <name>$PROJ_DIR$\User project\2.MotorDrive\Source\pwrlim.c</name>
+                </file>
                 <file>
                     <name>$PROJ_DIR$\User project\2.MotorDrive\Source\spdctrFSM.c</name>
                 </file>