Просмотр исходного кода

限速

Signed-off-by: huhui <huhui@sharkgulf.com>
huhui 3 лет назад
Родитель
Сommit
78f47e2d21

+ 1 - 1
Applications/app/app.c

@@ -46,7 +46,7 @@ void fetch_jtag_cmd(void) {
 		foc_send_command(&foc_cmd);
 		jtag_cmd = 0;
 	}else if (jtag_cmd == 5) {
-		PMSM_FOC_Set_Current((float)jtag_data/10.0f);
+		PMSM_FOC_Set_Torque((float)jtag_data/10.0f);
 		jtag_cmd = 0;
 	}else if (jtag_cmd == 6) {
 		PMSM_FOC_EnableCruise(true);

+ 4 - 3
Applications/app/nv_storage.c

@@ -32,8 +32,8 @@ static void nv_default_motor_params(void) {
 	m_params.ld = MOTOR_Ld;
 	m_params.lq = MOTOR_Lq;
 	m_params.offset = (360-128);
-	m_params.est_pll_band = 200;
-	m_params.pos_lock_pll_band = 200;
+	m_params.est_pll_band = 100;
+	m_params.pos_lock_pll_band = 100;
 	m_params.flux_linkage = 0.0f;
 }
 
@@ -42,13 +42,14 @@ static void nv_default_foc_params(void) {
 	foc_params.s_maxiDC = 30;
 	foc_params.s_maxIdq = 30;
 	foc_params.s_minIdq = -30;
-	foc_params.s_maxRPM = 8200;
+	foc_params.s_maxRPM = 1500;
 	foc_params.s_maxEpmRPM = 133;
 	foc_params.s_maxTorque = 30;
 	foc_params.s_maxBrkCurrent = 2.0f;
 	foc_params.n_currentBand = 500;
 	foc_params.n_modulation = 1.0f;
 	foc_params.n_PhaseFilterCeof = 0.2f;
+	foc_params.n_TrqVelLimGain = 1.0f;
 	foc_params.spd_kp = 0.001f;
 	foc_params.spd_ki = 0.01;
 	foc_params.trq_kp = 0.001f;

+ 1 - 0
Applications/app/nv_storage.h

@@ -16,6 +16,7 @@ typedef struct {
 	float n_modulation;
 	float n_PhaseFilterCeof;
 	float n_currentBand; //电流环带宽
+	float n_TrqVelLimGain;
 	float spd_kp;
 	float spd_ki;
 	float trq_kp;

+ 14 - 1
Applications/foc/core/PI_Controller.h

@@ -33,6 +33,7 @@ typedef struct {
 	float  max;
 	float  min;
 	float  Ui;
+	float  sat;
 	float  DT;
 }PI_Controller;
 
@@ -45,7 +46,7 @@ static __INLINE void PI_Controller_Reset(PI_Controller *pi, float init) {
 }
 
 static __INLINE float PI_Controller_run(PI_Controller *pi, float err) {
-	float kp_err = (err) * pi->kp;//S16_mul(err,pi->kp, 5);
+	float kp_err = (err) * pi->kp;
 	float ki_err = (err) * pi->ki;
 	float integral = ki_err * pi->DT;
 	pi->Ui = MATH_sat(pi->Ui + integral, pi->min, pi->max);
@@ -53,6 +54,18 @@ static __INLINE float PI_Controller_run(PI_Controller *pi, float err) {
 	return (MATH_sat(out, pi->min, pi->max));
 }
 
+static __INLINE float PI_Controller_RunSat(PI_Controller *pi, float err, float sat_gain) {
+	float kp_err = (err) * pi->kp;
+	float ki_err = (err) * pi->ki;
+	float integral = ki_err * pi->DT;
+	pi->Ui = pi->Ui + integral + pi->sat * sat_gain;
+	float out = pi->Ui + kp_err ;
+	float out_sat = MATH_sat(out, pi->min, pi->max);
+	pi->sat = out_sat - out;
+	return out_sat;
+}
+
+
 static __INLINE float PI_Controller_RunSerial(PI_Controller *pi, float err) {
 	float kp_err = (err) * pi->kp_s;//S16_mul(err,pi->kp, 5);
 	float ki_err = (kp_err) * pi->ki_s;

+ 20 - 7
Applications/foc/core/PMSM_FOC_Core.c

@@ -12,8 +12,9 @@
 #include "app/nv_storage.h"
 #include "bsp/pwm.h"
 #include "libs/logger.h"
-
+#include "math/fir.h"
 PMSM_FOC_Ctrl _gFOC_Ctrl;
+static Fir_t phase1, phase2;
 
 static __INLINE void RevPark(DQ_t *dq, float angle, AB_t *alpha_beta) {
 	float c,s;
@@ -36,7 +37,7 @@ static __INLINE void Park(AB_t *alpha_beta, float angle, DQ_t *dq) {
 	dq->q = -alpha_beta->a * s + alpha_beta->b * c;
 }
 
-//#define VD_PRIO_HIGH
+#define VD_PRIO_HIGH
 static __INLINE float Circle_Limitation(DQ_t *vdq, float vDC, float module, DQ_t *out) {
 	float sq_vdq = vdq->d * vdq->d + vdq->q * vdq->q;
 	float vDC_m = vDC * module;
@@ -116,6 +117,8 @@ static void PMSM_FOC_Reset_PID(void) {
 
 
 void PMSM_FOC_CoreInit(void) {
+	Fir_init(&phase1);
+	Fir_init(&phase2);
 	_gFOC_Ctrl.pi_ctl_id = &PI_Ctrl_ID;
 	_gFOC_Ctrl.pi_ctl_iq = &PI_Ctrl_IQ;
 	_gFOC_Ctrl.pi_ctl_spd = &PI_Ctrl_Spd;
@@ -136,6 +139,7 @@ void PMSM_FOC_CoreInit(void) {
 	_gFOC_Ctrl.params.s_minIdq = nv_get_foc_params()->s_minIdq;//-MAX_iDQ;	
 	_gFOC_Ctrl.params.n_modulation = nv_get_foc_params()->n_modulation;//SVM_Modulation;
 	_gFOC_Ctrl.params.n_PhaseFilterCeof = nv_get_foc_params()->n_PhaseFilterCeof;//(0.2f);
+	_gFOC_Ctrl.params.n_TrqVelLimGain = nv_get_foc_params()->n_TrqVelLimGain;
 	_gFOC_Ctrl.params.n_poles = nv_get_motor_params()->poles;//MOTOR_POLES;
 	_gFOC_Ctrl.out.n_RunMode = CTRL_MODE_OPEN;
 	_gFOC_Ctrl.out.f_vdqRation = 0;
@@ -150,7 +154,8 @@ void PMSM_FOC_CoreInit(void) {
 	PMSM_FOC_Reset_PID();
 }
 
-//#define PHASE_LFP
+//#define PHASE_LFP_FIR
+#define PHASE_LFP
 static __INLINE void PMSM_FOC_Update_Hardware(void) {
 	if (!_gFOC_Ctrl.in.b_MTPA_calibrate && (_gFOC_Ctrl.in.s_manualAngle != INVALID_ANGLE)) {
 		_gFOC_Ctrl.in.s_motAngle = _gFOC_Ctrl.in.s_manualAngle;
@@ -169,7 +174,11 @@ static __INLINE void PMSM_FOC_Update_Hardware(void) {
 	LowPass_Filter(_gFOC_Ctrl.in.s_iABCFilter[0], _gFOC_Ctrl.in.s_iABC[0], _gFOC_Ctrl.params.n_PhaseFilterCeof);
 	LowPass_Filter(_gFOC_Ctrl.in.s_iABCFilter[1], _gFOC_Ctrl.in.s_iABC[1], _gFOC_Ctrl.params.n_PhaseFilterCeof);
 	LowPass_Filter(_gFOC_Ctrl.in.s_iABCFilter[2], _gFOC_Ctrl.in.s_iABC[2], _gFOC_Ctrl.params.n_PhaseFilterCeof);
-#endif	
+#elif defined PHASE_LFP_FIR
+	_gFOC_Ctrl.in.s_iABCFilter[1] = Fir_Filter(&phase1, _gFOC_Ctrl.in.s_iABC[1]);
+	_gFOC_Ctrl.in.s_iABCFilter[2] = Fir_Filter(&phase2, _gFOC_Ctrl.in.s_iABC[2]);
+	_gFOC_Ctrl.in.s_iABCFilter[0] = -(_gFOC_Ctrl.in.s_iABCFilter[1] + _gFOC_Ctrl.in.s_iABCFilter[2]);
+#endif
 }
 
 static __INLINE void PMSM_FOC_Update_PI_Idq(void) {
@@ -201,7 +210,9 @@ static __INLINE void PMSM_FOC_Plot_Debug(void) {
 		//plot_3data16(_gFOC_Ctrl.in.s_motRPM, FtoS16x1000(_gFOC_Ctrl.out.s_OutVdq.d), FtoS16x1000(_gFOC_Ctrl.out.s_OutVdq.q));
 		//plot_3data16(_gFOC_Ctrl.in.s_motRPM, FtoS16x1000(_gFOC_Ctrl.out.s_RealIdq.d), FtoS16x1000(_gFOC_Ctrl.out.s_RealIdq.q));
 		if (jtag_plot == 2) {
-			plot_3data16(FtoS16(_gFOC_Ctrl.in.s_iABC[1]), FtoS16(_gFOC_Ctrl.in.s_motRPM), FtoS16(_gFOC_Ctrl.in.s_hallAngle));
+			//plot_3data16(_gFOC_Ctrl.in.s_motRPM, FtoS16x10(_gFOC_Ctrl.out.s_RealIdq.d), FtoS16x10(_gFOC_Ctrl.out.s_RealIdq.q));
+			plot_3data16(FtoS16x10(_gFOC_Ctrl.in.s_iABCFilter[0]), FtoS16x10(_gFOC_Ctrl.in.s_iABCFilter[1]), FtoS16x10(_gFOC_Ctrl.in.s_iABCFilter[2]));
+			//plot_2data16(_gFOC_Ctrl.in.s_iABC[0], _gFOC_Ctrl.in.s_iABCFilter[0]);
 		}
 		//plot_1data16(FtoS16(_gFOC_Ctrl.in.s_hallAngle));
 		//plot_1data16(_gFOC_Ctrl.in.s_motRPM);
@@ -212,6 +223,8 @@ void PMSM_FOC_Schedule(void) {
 	AB_t vAB;
 #ifdef PHASE_LFP	
 	float *iabc = _gFOC_Ctrl.in.s_iABCFilter;
+#elif defined PHASE_LFP_FIR
+	float *iabc = _gFOC_Ctrl.in.s_iABCFilter;
 #else
 	float *iabc = _gFOC_Ctrl.in.s_iABC;
 #endif
@@ -345,7 +358,7 @@ void PMSM_FOC_idqCalc(void) {
 			_gFOC_Ctrl.pi_ctl_trq->min = 0; //防止倒转
 		}
 		float errRef = _gFOC_Ctrl.params.s_maxRPM - _gFOC_Ctrl.in.s_motRPM;
-		_gFOC_Ctrl.in.s_targetTorque = PI_Controller_run(_gFOC_Ctrl.pi_ctl_trq, errRef);
+		_gFOC_Ctrl.in.s_targetTorque = PI_Controller_RunSat(_gFOC_Ctrl.pi_ctl_trq, errRef, _gFOC_Ctrl.params.n_TrqVelLimGain);
 	}else if (_gFOC_Ctrl.out.n_RunMode == CTRL_MODE_SPD){
 		_gFOC_Ctrl.pi_ctl_spd->max = _gFOC_Ctrl.params.s_maxIdq;
 		_gFOC_Ctrl.pi_ctl_spd->min = _gFOC_Ctrl.params.s_minIdq;
@@ -358,7 +371,7 @@ void PMSM_FOC_idqCalc(void) {
 			_gFOC_Ctrl.pi_ctl_spd->min = 0; //防止倒转
 		}
 		float errRef = refSpeed - _gFOC_Ctrl.in.s_motRPM;
-		_gFOC_Ctrl.in.s_targetTorque = PI_Controller_run(_gFOC_Ctrl.pi_ctl_spd, errRef);		
+		_gFOC_Ctrl.in.s_targetTorque = PI_Controller_RunSat(_gFOC_Ctrl.pi_ctl_spd, errRef, _gFOC_Ctrl.params.n_TrqVelLimGain);		
 	}
 	PMSM_FOC_idq_Assign();
 }

+ 1 - 0
Applications/foc/core/PMSM_FOC_Core.h

@@ -31,6 +31,7 @@ typedef struct {
 	float s_maxTorque;
 	float n_modulation;
 	float n_PhaseFilterCeof;
+	float n_TrqVelLimGain;
 }FOC_Params;
 
 typedef struct {

+ 4 - 4
Applications/foc/core/PMSM_FOC_Params.h

@@ -25,8 +25,8 @@ static PI_Controller PI_Ctrl_IQ = {
 };
 
 static PI_Controller PI_Ctrl_trq = {
-	.kp = 0.001f,
-	.ki = 0.01f,
+	.kp = 0.1f,
+	.ki = 0.5f,
 	.max = (MAX_TORQUE),
 	.min = (-MAX_TORQUE),
 	.DT  = (1.0f/(float)SPD_CTRL_TS),
@@ -34,8 +34,8 @@ static PI_Controller PI_Ctrl_trq = {
 };
 
 static PI_Controller PI_Ctrl_Spd = {
-	.kp = 0.001f,
-	.ki = 0.01f,
+	.kp = 0.1f,
+	.ki = 0.5f,
 	.max = (MAX_TORQUE),
 	.min = (-MAX_TORQUE),
 	.DT  = (1.0f/(float)SPD_CTRL_TS),

+ 1 - 1
Applications/foc/foc_config.h

@@ -39,7 +39,7 @@
 #define eCTRL_NEG_TORQUE (-100)   /* ebrake 的最大方向DQ电流,单位 ACKED_KEY*/
 
 
-#define CURRENT_BANDWITH 500 /* 电流环带宽 */
+#define CURRENT_BANDWITH 250 /* 电流环带宽 */
 
 #define SVM_Modulation 1.0f //(0.96f)
 

+ 2 - 0
Applications/foc/motor/current.c

@@ -271,6 +271,7 @@ void phase_current_get(float *iABC){
 		/* Ib = PhaseBOffset - ADC converted value) */
 		cs->adc_ib = (phase_current1 - cs->adc_offset_b);
 		cs->adc_ic = (phase_current2 - cs->adc_offset_c);
+#ifndef HIGH_SIDE_CURRENT_SENSOR		
 		LowPass_Filter(cs->adc_ib_filter, cs->adc_ib, LOW_FP_COEF);
 		LowPass_Filter(cs->adc_ic_filter, cs->adc_ic, LOW_FP_COEF);
 		cs->adc_ia_filter = -(cs->adc_ib_filter + cs->adc_ic_filter);
@@ -287,6 +288,7 @@ void phase_current_get(float *iABC){
 			cs->adc_ic = cs->adc_ic_filter;
 		}
 		cs->adc_ia = -(cs->adc_ib + cs->adc_ic);
+#endif
 	}else if (cs->c_phases == PHASE_AC) {
 		/* Current on Phase B is not accessible 	*/
 		/* Ia = PhaseAOffset - ADC converted value) */

+ 55 - 0
Applications/math/Fir.c

@@ -0,0 +1,55 @@
+/*
+ * Filter Coefficients (C Source) generated by the Filter Design and Analysis Tool
+ * Generated by MATLAB(R) 9.9 and Signal Processing Toolbox 8.5.
+ * Generated on: 06-Oct-2022 12:50:19
+ */
+
+/*
+ * 离散时间 FIR 滤波器(实数)
+ * ----------------
+ * 滤波器结构  : 直接型 FIR
+ * 滤波器长度  : 16
+ * 稳定     : 是
+ * 线性相位   : 是 (Type 2)
+ */
+
+/* General type conversion for MATLAB generated C-code  */
+//#include "tmwtypes.h"
+/* 
+ * Expected path to tmwtypes.h 
+ * D:\Program Files\R2020b\extern\include\tmwtypes.h 
+ */
+/*
+ * Warning - Filter coefficients were truncated to fit specified data type.  
+ *   The resulting response may not match generated theoretical response.
+ *   Use the Filter Design & Analysis Tool to design accurate
+ *   single-precision filter coefficients.
+ */
+
+#include "math/fir.h"
+
+static const float Fir_Ceofs[16] = {
+  -0.002180566313,-0.009224493057, -0.01853588782, -0.01606058516,   0.0186471995,
+    0.09345125407,   0.1863618642,   0.2517603636,   0.2517603636,   0.1863618642,
+    0.09345125407,   0.0186471995, -0.01606058516, -0.01853588782,-0.009224493057,
+  -0.002180566313
+};
+
+void Fir_init(Fir_t *fir) {
+	for (int i = 0; i < FIR_Ceof_Len; i++) {
+		fir->X[0] = 0.0f;
+	}
+	fir->k = 0;
+}
+
+
+float Fir_Filter(Fir_t *fir, float in) {
+	float out = 0;
+	fir->X[fir->k] = in;
+	for (int i = 1; i <= FIR_Ceof_Len; i++) {
+		out += Fir_Ceofs[i-1] * fir->X[(i+fir->k) % FIR_Ceof_Len];
+	}
+	fir->k = (fir->k + 1) % FIR_Ceof_Len;
+	return out;
+}
+

+ 13 - 0
Applications/math/Fir.h

@@ -0,0 +1,13 @@
+#ifndef _FIR_H__
+#define _FIR_H__
+
+#define  FIR_Ceof_Len  16
+typedef struct {
+	float X[FIR_Ceof_Len];
+	int   k;
+}Fir_t;
+void Fir_init(Fir_t *);
+float Fir_Filter(Fir_t *fir, float in);
+
+#endif /*_FIR_H__ */
+

+ 13 - 0
Applications/math/fast_math.h

@@ -53,5 +53,18 @@ static void normal_sincosf(float angle, float *sin, float *cos) {
 //#define LowPass_Filter(value, sample, filter_constant)	(value = value * (1.0f - filter_constant) + sample * filter_constant)
 #define LowPass_Filter(value, sample, filter_constant)	(value = ((float)sample - (float)value) * filter_constant + value)
 
+
+static float limitRPM(float vel_limit, float vel_estimate, float vel_gain, float torque) {
+    float Tmax = (vel_limit - vel_estimate) * vel_gain;
+    float Tmin = (-vel_limit - vel_estimate) * vel_gain;
+	if (torque < Tmin) {
+		return Tmin;
+	}
+	if (Tmax > torque) {
+		return torque;
+	}
+	return Tmax;
+}
+
 #endif /* _Fast_Math_H__ */
 

+ 59 - 43
Project/MC100.uvoptx

@@ -117,6 +117,10 @@
         <pMon>Segger\JL2CM3.dll</pMon>
       </DebugOpt>
       <TargetDriverDllRegistry>
+        <SetRegEntry>
+          <Number>0</Number>
+          <Key>DLGUARM</Key>
+        </SetRegEntry>
         <SetRegEntry>
           <Number>0</Number>
           <Key>ARMRTXEVENTFLAGS</Key>
@@ -586,6 +590,18 @@
       <RteFlg>0</RteFlg>
       <bShared>0</bShared>
     </File>
+    <File>
+      <GroupNumber>5</GroupNumber>
+      <FileNumber>23</FileNumber>
+      <FileType>1</FileType>
+      <tvExp>0</tvExp>
+      <tvExpOptDlg>0</tvExpOptDlg>
+      <bDave2>0</bDave2>
+      <PathWithFileName>..\Applications\math\Fir.c</PathWithFileName>
+      <FilenameWithoutPath>Fir.c</FilenameWithoutPath>
+      <RteFlg>0</RteFlg>
+      <bShared>0</bShared>
+    </File>
   </Group>
 
   <Group>
@@ -596,7 +612,7 @@
     <RteFlg>0</RteFlg>
     <File>
       <GroupNumber>6</GroupNumber>
-      <FileNumber>23</FileNumber>
+      <FileNumber>24</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -608,7 +624,7 @@
     </File>
     <File>
       <GroupNumber>6</GroupNumber>
-      <FileNumber>24</FileNumber>
+      <FileNumber>25</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -620,7 +636,7 @@
     </File>
     <File>
       <GroupNumber>6</GroupNumber>
-      <FileNumber>25</FileNumber>
+      <FileNumber>26</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -632,7 +648,7 @@
     </File>
     <File>
       <GroupNumber>6</GroupNumber>
-      <FileNumber>26</FileNumber>
+      <FileNumber>27</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -644,7 +660,7 @@
     </File>
     <File>
       <GroupNumber>6</GroupNumber>
-      <FileNumber>27</FileNumber>
+      <FileNumber>28</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -656,7 +672,7 @@
     </File>
     <File>
       <GroupNumber>6</GroupNumber>
-      <FileNumber>28</FileNumber>
+      <FileNumber>29</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -668,7 +684,7 @@
     </File>
     <File>
       <GroupNumber>6</GroupNumber>
-      <FileNumber>29</FileNumber>
+      <FileNumber>30</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -680,7 +696,7 @@
     </File>
     <File>
       <GroupNumber>6</GroupNumber>
-      <FileNumber>30</FileNumber>
+      <FileNumber>31</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -692,7 +708,7 @@
     </File>
     <File>
       <GroupNumber>6</GroupNumber>
-      <FileNumber>31</FileNumber>
+      <FileNumber>32</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -704,7 +720,7 @@
     </File>
     <File>
       <GroupNumber>6</GroupNumber>
-      <FileNumber>32</FileNumber>
+      <FileNumber>33</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -716,7 +732,7 @@
     </File>
     <File>
       <GroupNumber>6</GroupNumber>
-      <FileNumber>33</FileNumber>
+      <FileNumber>34</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -728,7 +744,7 @@
     </File>
     <File>
       <GroupNumber>6</GroupNumber>
-      <FileNumber>34</FileNumber>
+      <FileNumber>35</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -740,7 +756,7 @@
     </File>
     <File>
       <GroupNumber>6</GroupNumber>
-      <FileNumber>35</FileNumber>
+      <FileNumber>36</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -752,7 +768,7 @@
     </File>
     <File>
       <GroupNumber>6</GroupNumber>
-      <FileNumber>36</FileNumber>
+      <FileNumber>37</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -764,7 +780,7 @@
     </File>
     <File>
       <GroupNumber>6</GroupNumber>
-      <FileNumber>37</FileNumber>
+      <FileNumber>38</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -776,7 +792,7 @@
     </File>
     <File>
       <GroupNumber>6</GroupNumber>
-      <FileNumber>38</FileNumber>
+      <FileNumber>39</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -796,7 +812,7 @@
     <RteFlg>0</RteFlg>
     <File>
       <GroupNumber>7</GroupNumber>
-      <FileNumber>39</FileNumber>
+      <FileNumber>40</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -808,7 +824,7 @@
     </File>
     <File>
       <GroupNumber>7</GroupNumber>
-      <FileNumber>40</FileNumber>
+      <FileNumber>41</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -820,7 +836,7 @@
     </File>
     <File>
       <GroupNumber>7</GroupNumber>
-      <FileNumber>41</FileNumber>
+      <FileNumber>42</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -832,7 +848,7 @@
     </File>
     <File>
       <GroupNumber>7</GroupNumber>
-      <FileNumber>42</FileNumber>
+      <FileNumber>43</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -844,7 +860,7 @@
     </File>
     <File>
       <GroupNumber>7</GroupNumber>
-      <FileNumber>43</FileNumber>
+      <FileNumber>44</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -856,7 +872,7 @@
     </File>
     <File>
       <GroupNumber>7</GroupNumber>
-      <FileNumber>44</FileNumber>
+      <FileNumber>45</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -876,7 +892,7 @@
     <RteFlg>0</RteFlg>
     <File>
       <GroupNumber>8</GroupNumber>
-      <FileNumber>45</FileNumber>
+      <FileNumber>46</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -888,7 +904,7 @@
     </File>
     <File>
       <GroupNumber>8</GroupNumber>
-      <FileNumber>46</FileNumber>
+      <FileNumber>47</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -900,7 +916,7 @@
     </File>
     <File>
       <GroupNumber>8</GroupNumber>
-      <FileNumber>47</FileNumber>
+      <FileNumber>48</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -920,7 +936,7 @@
     <RteFlg>0</RteFlg>
     <File>
       <GroupNumber>9</GroupNumber>
-      <FileNumber>48</FileNumber>
+      <FileNumber>49</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -932,7 +948,7 @@
     </File>
     <File>
       <GroupNumber>9</GroupNumber>
-      <FileNumber>49</FileNumber>
+      <FileNumber>50</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -944,7 +960,7 @@
     </File>
     <File>
       <GroupNumber>9</GroupNumber>
-      <FileNumber>50</FileNumber>
+      <FileNumber>51</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -956,7 +972,7 @@
     </File>
     <File>
       <GroupNumber>9</GroupNumber>
-      <FileNumber>51</FileNumber>
+      <FileNumber>52</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -968,7 +984,7 @@
     </File>
     <File>
       <GroupNumber>9</GroupNumber>
-      <FileNumber>52</FileNumber>
+      <FileNumber>53</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -980,7 +996,7 @@
     </File>
     <File>
       <GroupNumber>9</GroupNumber>
-      <FileNumber>53</FileNumber>
+      <FileNumber>54</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -992,7 +1008,7 @@
     </File>
     <File>
       <GroupNumber>9</GroupNumber>
-      <FileNumber>54</FileNumber>
+      <FileNumber>55</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -1004,7 +1020,7 @@
     </File>
     <File>
       <GroupNumber>9</GroupNumber>
-      <FileNumber>55</FileNumber>
+      <FileNumber>56</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -1016,7 +1032,7 @@
     </File>
     <File>
       <GroupNumber>9</GroupNumber>
-      <FileNumber>56</FileNumber>
+      <FileNumber>57</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -1028,7 +1044,7 @@
     </File>
     <File>
       <GroupNumber>9</GroupNumber>
-      <FileNumber>57</FileNumber>
+      <FileNumber>58</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -1040,7 +1056,7 @@
     </File>
     <File>
       <GroupNumber>9</GroupNumber>
-      <FileNumber>58</FileNumber>
+      <FileNumber>59</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -1052,7 +1068,7 @@
     </File>
     <File>
       <GroupNumber>9</GroupNumber>
-      <FileNumber>59</FileNumber>
+      <FileNumber>60</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -1064,7 +1080,7 @@
     </File>
     <File>
       <GroupNumber>9</GroupNumber>
-      <FileNumber>60</FileNumber>
+      <FileNumber>61</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -1076,7 +1092,7 @@
     </File>
     <File>
       <GroupNumber>9</GroupNumber>
-      <FileNumber>61</FileNumber>
+      <FileNumber>62</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -1088,7 +1104,7 @@
     </File>
     <File>
       <GroupNumber>9</GroupNumber>
-      <FileNumber>62</FileNumber>
+      <FileNumber>63</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -1100,7 +1116,7 @@
     </File>
     <File>
       <GroupNumber>9</GroupNumber>
-      <FileNumber>63</FileNumber>
+      <FileNumber>64</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -1120,7 +1136,7 @@
     <RteFlg>0</RteFlg>
     <File>
       <GroupNumber>10</GroupNumber>
-      <FileNumber>64</FileNumber>
+      <FileNumber>65</FileNumber>
       <FileType>1</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>
@@ -1132,7 +1148,7 @@
     </File>
     <File>
       <GroupNumber>10</GroupNumber>
-      <FileNumber>65</FileNumber>
+      <FileNumber>66</FileNumber>
       <FileType>2</FileType>
       <tvExp>0</tvExp>
       <tvExpOptDlg>0</tvExpOptDlg>

+ 5 - 0
Project/MC100.uvprojx

@@ -513,6 +513,11 @@
               <FileType>4</FileType>
               <FilePath>..\Applications\math\arm_cortexM4lf_math.lib</FilePath>
             </File>
+            <File>
+              <FileName>Fir.c</FileName>
+              <FileType>1</FileType>
+              <FilePath>..\Applications\math\Fir.c</FilePath>
+            </File>
           </Files>
         </Group>
         <Group>