123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288 |
- /************************************************************************
- Project: Welling Motor Control Paltform
- Filename: torqobs.c
- Partner Filename: torqobs.h
- Description: Automatic current regulator
- Complier: IAR Embedded Workbench for ARM 8.40, IAR Systems.
- CPU TYPE : STM32F30x
- *************************************************************************
- Copyright (c) 2022 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 _TORQOBS_C_
- #define _TORQOBS_C_
- #endif
- /************************************************************************
- Included File:
- *************************************************************************/
- #include "torqobs.h"
- /************************************************************************
- Constant Table:
- *************************************************************************/
- /*************************************************************************
- extern Parameter
- **************************************************************************/
- TORQOBS_COEFIN torqobs_stCoefIn;
- TORQOBS_COEFOUT torqobs_stCoef;
- TORQOBS_IN torqobs_stCalIn;
- TORQOBS_OUT torqobs_stCalOut;
- /************************************************************************
- Exported Functions:
- *************************************************************************/
- /***************************************************************
- Function: ;
- Description:
- Call by: functions
- Input Variables:
- Output/Return Variables:
- Subroutine Call: N/A;
- Reference: N/A
- ****************************************************************/
- void torqobs_voInit(void)
- {
- torqobs_stCalOut.slSpdObsPu = 0;
- torqobs_stCalOut.slIqLoadPu = 0;
- torqobs_stCalOut.swErrZ1Pu = 0;
- torqobs_stCalOut.swIqLoadPu = 0;
- torqobs_stCalOut.swSpdObsPu = 0;
- torqobs_stCalOut.swSpdObsPu = 0;
- torqobs_stCalOut.swTorqObsPu = 0;
- }
- /***************************************************************
- Function: ;
- Description:
- Call by: functions
- Input Variables:
- Output/Return Variables:
- Subroutine Call: N/A;
- Reference: N/A
- ****************************************************************/
- void torqobs_voCoef(TORQOBS_COEFIN *in, TORQOBS_COEFOUT*out)
- {
- UWORD uwWebRadps;
- UWORD uwPbWt;
- UWORD uwWmb;
- UWORD uwTbUs;
- UWORD uwTbNm;
- UWORD uwJb;
- UWORD uwJmPu;
- UWORD uwFluxbWb;
- UWORD uwFluxPu;
- UWORD uwWtcPu;
- UWORD uwTCtrPu;
- ULONG ulJmPu;
- if (in->uwFbHz < 1)
- {
- in->uwFbHz = 1;
- }
- if (in->uwUbVt < 1)
- {
- in->uwUbVt = 1;
- }
- if (in->uwIbAp < 1)
- {
- in->uwIbAp = 1;
- }
- if (in->uwPairs < 1)
- {
- in->uwPairs = 1;
- }
- if (in->uwMtJm < 1)
- {
- in->uwMtJm = 1;
- }
- if (in->uwMtFlxWb < 1)
- {
- in->uwMtFlxWb = 1;
- }
- if (in->uwFTbsHz < 1)
- {
- in->uwFTbsHz = 1;
- }
- if (in->uwRatioJm > 10)
- {
- in->uwRatioJm = 10;
- }
- if (in->uwWtcHz > 50)
- {
- in->uwWtcHz = 50;
- }
- uwWebRadps = (ULONG)2 * 31416 * in->uwFbHz / 1000; /* unit: 0.1rad/s, Electrical radian frequency base */
- uwPbWt = (ULONG)3 * in->uwUbVt * in->uwIbAp / 100 >> 1; /* unit: 0.1w, Power base */
- uwWmb = uwWebRadps / in->uwPairs; /* unit: 0.1rad/s, Mechanical radian frequency base */
- uwTbUs = (ULONG)100000000 / uwWebRadps; /* unit: 0.1us, Time base */
- uwTbNm = (ULONG)uwPbWt * 1000 / uwWmb; /* unit: mNm, Torque base */
- uwJb = ((ULONG)uwTbNm * uwTbUs * 10) / uwWmb; /* unit: 10^-10*kg*m2, Rotational inertia base */
- uwJmPu = ((ULONG)in->uwMtJm * 1000) / uwJb; /* Q0, Rotational inertia */
- uwFluxbWb = ((ULONG)in->uwUbVt * 1000000) / uwWebRadps; /* unit: 0.001mWb, Flux linkage base */
- uwFluxPu = ((ULONG)in->uwMtFlxWb << 12) / uwFluxbWb; /* Q12, Flux linkage */
- uwTCtrPu = (ULONG)2 * 12868 * in->uwFbHz / in->uwFTbsHz; /* Q12, Speed control period Pu, pi(Q12)=12868 */
- /* Jm */
- //ulJmPu = uwJmPu;
- ulJmPu = (ULONG)(in->uwRatioJm + 1) * uwJmPu; // Q0
-
- /* Kp = Wtc * Jm /FluxF */
- uwWtcPu = (((ULONG)in->uwWtcHz << 15) / in->uwFbHz); // Q15 BW_HZ2PU(x)
- out->uwKpPu = (ulJmPu * uwWtcPu << 3) / uwFluxPu; // Q6
- /* Kit = Kp * Wtc * T_spd_ctrl */
- out->uwKitPu = (((ULONG)uwWtcPu * uwTCtrPu) >> 18) * out->uwKpPu * 4; // Q15
-
- if (out->uwKitPu < 1)
- {
- out->uwKitPu = 1;
- }
- out->ulJmPu_Inv = ((ULONG) 1 << 12) / ulJmPu; // Q12
- out->uwTCtrPu = uwTCtrPu; // Q12
- out->uwCur2TorqKPu = uwFluxPu; // Q12
- }
- /***************************************************************
- Function: ;
- Description:
- Call by: functions
- Input Variables:
- Output/Return Variables:
- Subroutine Call: N/A;
- Reference: N/A
- ****************************************************************/
- void torqobs_voCal(TORQOBS_IN *in, TORQOBS_COEFOUT *cof, TORQOBS_OUT *out)
- {
- SLONG slIqMaxPu; // Q30
- SLONG slIqMinPu; // Q30
- SLONG slSpdErrPu; // Q15
- SLONG slDeltaErrPu;
- SQWORD sqIqLoadPu;
- SQWORD sqIqpPu;
- SQWORD sqIqiPu;
- SLONG slDeltaTorqPu;
- SLONG slSpdObsPu;
- /* Coefficient get */
- slIqMaxPu = (SLONG)in->swIqMaxPu << 16; // Q14+Q16=Q30
- slIqMinPu = (SLONG)in->swIqMinPu << 16; // Q14+Q16=Q30
-
- /* Calculate the error */
- slSpdErrPu = (SLONG)in->swSpdPu - out->swSpdObsPu; // Q15
- if (slSpdErrPu > 32767)
- {
- slSpdErrPu = 32767;
- }
- else if (slSpdErrPu < -32767)
- {
- slSpdErrPu = -32767;
- }
- else
- {
- /* Nothing */
- }
- /* Calculate the delta error */
- slDeltaErrPu = slSpdErrPu - out->swErrZ1Pu; // Q15
- if (slDeltaErrPu > 32767)
- {
- slDeltaErrPu = 32767;
- }
- else if (slDeltaErrPu < -32768)
- {
- slDeltaErrPu = -32768;
- }
- else
- {
- /* Nothing */
- }
- sqIqpPu = ((SQWORD)slDeltaErrPu * cof->uwKpPu) << 9; // Q30
- /* Calculate the integral output */
- sqIqiPu = (SQWORD)slSpdErrPu * cof->uwKitPu; // Q30
- // if (sqIqiPu > 32768)
- // {
- // sqIqiPu = 32768;
- // }
- // else if (sqIqiPu < -32768)
- // {
- // sqIqiPu = -32768;
- // }
- // else
- // {}
- /* Calculate the Controller output */
- sqIqLoadPu = sqIqpPu + sqIqiPu + (SQWORD)out->slIqLoadPu; // Q30
- /* Iq output limit */
- if (sqIqLoadPu > slIqMaxPu)
- {
- out->slIqLoadPu = slIqMaxPu;
- }
- else if (sqIqLoadPu < slIqMinPu)
- {
- out->slIqLoadPu = slIqMinPu;
- }
- else
- {
- out->slIqLoadPu = (SLONG)sqIqLoadPu;
- }
- out->swIqLoadPu = out->slIqLoadPu >> 16; // Q30-Q16=Q14
- out->swErrZ1Pu = (SWORD)slSpdErrPu;
- out->swTorqObsPu = (SWORD)-(SWORD)((SLONG)out->swIqLoadPu * cof->uwCur2TorqKPu >> 12); // Q14+Q12-Q12=Q14
- slDeltaTorqPu = (SLONG)cof->uwCur2TorqKPu * (in->swIqfbkPu + out->swIqLoadPu) >> 12; // Q14
- slSpdObsPu = out->slSpdObsPu + ((SLONG)slDeltaTorqPu * cof->uwTCtrPu >> 9) * cof->ulJmPu_Inv; // Q29
- if(slSpdObsPu >= 531502202L)
- {
- out->slSpdObsPu = 531502202L;
- }
- else if(slSpdObsPu <= -531502202L)
- {
- out->slSpdObsPu = -531502202L;
- }
- else
- {
- out->slSpdObsPu = slSpdObsPu;
- }
-
- out->swSpdObsPu = out->slSpdObsPu >> 14; // Q15
- out->slDeltaTorqPu = slDeltaTorqPu;
- }
- /*************************************************************************
- Local Functions (N/A)
- *************************************************************************/
- /************************************************************************
- Copyright (c) 2018 Welling Motor Technology(Shanghai) Co., Ltd.
- All rights reserved.
- *************************************************************************/
- #ifdef _TORQOBS_C_
- #undef _TORQOBS_C_
- #endif
- /*************************************************************************
- End of this File (EOF)!
- Do not put anything after this part!
- *************************************************************************/
|