Эх сурвалжийг харах

feat:增加车速单元测试并通过

CN\guohui27 2 жил өмнө
parent
commit
be716d39d8

+ 9 - 0
User project/3.BasicFunction/Include/bikespeed.h

@@ -16,6 +16,10 @@
 #define BIKESPEED_H
 
 #include "typedefine.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif // __cplusplus
 /****************************************
  *
  *          Definitions & Macros
@@ -112,6 +116,7 @@ typedef struct
     UWORD uwCaputureOverflowMinCnt;
     UWORD uwBikeForwardCnt;   // Count number to calculate trip
     BOOL  blUpdateTripCntFlg; // Unit the same as BIKESPEED_COF.uwMinTriptoUpdate ��need clear after update trip.
+    UWORD uwOverflowfirst;
 } BIKESPEED_OUT;
 
 
@@ -161,6 +166,10 @@ void bikespeed_voPI(const BIKESPDPI_IN *in, BIKESPDPI_OUT *out);
 /************************************************************************
  Flag Define (N/A)
 *************************************************************************/
+#ifdef __cplusplus
+}
+#endif // __cplusplus
+
 #endif
 /************************************************************************
  Copyright (c) 2018 Welling Motor Technology(Shanghai) Co. Ltd.

+ 39 - 44
User project/3.BasicFunction/Source/Cadence.c

@@ -33,7 +33,7 @@ static ULONG cad_pvt_ulCadFreqPu = 0;
 /***************************************************************
  Function: cadence_voCadenceCof;
  Description: cadence function coef cal
- Call by: functions in main loop;
+ Call by: 
  Input Variables: N/A
  Output/Return Variables: N/A
  Subroutine Call: N/A;
@@ -54,9 +54,9 @@ void cadence_voCadenceCof(void)
 }
 
 /***************************************************************
- Function: cadence_voFreGet;
- Description: cadence frequency get
- Call by: functions in main loop;
+ Function: cadence_voCadenceIdle;
+ Description: 
+ Call by: 
  Input Variables: N/A
  Output/Return Variables: N/A
  Subroutine Call: N/A;
@@ -103,14 +103,13 @@ static void cadence_voCadenceIdle(UWORD source)
         }
     }
 }
-
 /***************************************************************
- Function: cadence_voFreGet;
- Description: cadence frequency get
- Call by: functions in main loop;
+ Function: cadence_voCadenceHighFrequencyWork
+ Description: 
+ Call by: functions in main loop
  Input Variables: N/A
  Output/Return Variables: N/A
- Subroutine Call: N/A;
+ Subroutine Call: N/A
  Reference: N/A
 ****************************************************************/
 static ULONG ulCaputureCntErr = 0,ulCaputureCntErrLast = 0;
@@ -134,7 +133,7 @@ static void cadence_voCadenceHighFrequencyWork(UWORD source)
             if(cadence_stFreGetOut.uwOverflowfirst == 1)
             {
                 cadence_stFreGetOut.uwCaputureOverflowCnt -=1;
-                ulCaputureCntErr = ((ULONG)cadence_stFreGetOut.uwCaputureOverflowCnt * 720 * cadence_stFreGetCof.uwTimerUnit) + cadence_stFreGetOut.uwCaputure2Cnt 
+                ulCaputureCntErr = ((ULONG)cadence_stFreGetOut.uwCaputureOverflowCnt * TIM1CLK_KHZ * cadence_stFreGetCof.uwTimerUnit) + cadence_stFreGetOut.uwCaputure2Cnt 
                                     -cadence_stFreGetOut.uwCaputure1Cnt;
                 cadence_stFreGetOut.uwCaputureOverflowCnt = 1; 
                 cadence_stFreGetOut.uwOverflowfirst = 0;
@@ -142,14 +141,14 @@ static void cadence_voCadenceHighFrequencyWork(UWORD source)
             }
             else
             {
-                ulCaputureCntErr = ((ULONG)cadence_stFreGetOut.uwCaputureOverflowCnt * 720 * cadence_stFreGetCof.uwTimerUnit) + cadence_stFreGetOut.uwCaputure2Cnt 
+                ulCaputureCntErr = ((ULONG)cadence_stFreGetOut.uwCaputureOverflowCnt * TIM1CLK_KHZ * cadence_stFreGetCof.uwTimerUnit) + cadence_stFreGetOut.uwCaputure2Cnt 
                                     -cadence_stFreGetOut.uwCaputure1Cnt;
                 cadence_stFreGetOut.uwCaputureOverflowCnt = 0;
                 cadence_stFreGetOut.uwOverflowfirst = 0;
             }
 
             /* Cadence Freq Cal */
-            cad_pvt_ulCadFreqPu = (ULONG)(((UQWORD)720000 << 20) / ((((UQWORD)ulCaputureCntErr + (UQWORD)ulCaputureCntErrLast)>>1)* cadence_stFreGetCof.uwNumbersPulses * FBASE));
+            cad_pvt_ulCadFreqPu = (ULONG)(((UQWORD)TIM1CLK_KHZ * 1000 << 20) / ((((UQWORD)ulCaputureCntErr + (UQWORD)ulCaputureCntErrLast)>>1)* cadence_stFreGetCof.uwNumbersPulses * FBASE));
 
             cadence_stFreGetOut.uwCaputureNumCnt = 1;
             cadence_stFreGetOut.uwCaputure1Cnt = cadence_stFreGetOut.uwCaputure2Cnt; 
@@ -182,7 +181,7 @@ static void cadence_voCadenceHighFrequencyWork(UWORD source)
             cadence_stFreGetOut.uwCaputureOverflowCnt = 0;
 
             /* Cadence Freq Cal */
-            cad_pvt_ulCadFreqPu = (ULONG)(((UQWORD)720000 << 20) / ((((UQWORD)ulCaputureCntErr + (UQWORD)ulCaputureCntErrLast)>>1)* cadence_stFreGetCof.uwNumbersPulses * FBASE));
+            cad_pvt_ulCadFreqPu = (ULONG)(((UQWORD)TIM1CLK_KHZ * 1000 << 20) / ((((UQWORD)ulCaputureCntErr + (UQWORD)ulCaputureCntErrLast)>>1)* cadence_stFreGetCof.uwNumbersPulses * FBASE));
 
             cadence_stFreGetOut.uwCaputureNumCnt = 1;
             cadence_stFreGetOut.uwCaputure1Cnt = cadence_stFreGetOut.uwCaputure2Cnt; 
@@ -203,53 +202,51 @@ static void cadence_voCadenceHighFrequencyWork(UWORD source)
         cadence_stFreGetOut.cadence_fsm = CADENCE_BACKWOR;
     }
 
-    if (cadence_stFreGetOut.uwCaputureOverflowCnt >= cadence_stFreGetCof.uwHfMaxTimeCnt) // 100ms
+    if (cad_pvt_ulCadFreqPu > cadence_stFreGetCof.uwMaxCadenceFre)
     {
         cadence_stFreGetOut.uwFrequencyPu = 0;
         cadence_stFreGetOut.uwLPFFrequencyPu = 0;
         cadence_stFreGetOut.blCadenceCalStartState = FALSE;
-        cadence_stFreGetOut.blCadenceSensorErrorFlg = FALSE;
+        cadence_stFreGetOut.blCadenceSensorErrorFlg = TRUE;
         cadence_stFreGetOut.uwCaputureOverflowCnt = 0;
         cadence_stFreGetOut.uwCaputureNumCnt = 0;
         cadence_stFreGetOut.uwCaputure2Cnt = 0;
         cadence_stFreGetOut.uwCaputure1Cnt = 0;
-        cadence_stFreGetOut.cadence_dir = CADENCE_DIR_IDLE;
-        cadence_stFreGetOut.cadence_fsm = CADENCE_IDLE;
+        cadence_stFreGetOut.cadence_dir = CADENCE_DIR_ERROR;
+        cadence_stFreGetOut.cadence_fsm = CADENCE_ERROR;
         cadence_stFreGetOut.uwFreqPercent = 0;
+        cp_stHistoryPara.uwCadSensorAlamTimes++;
     }
-    else if (cad_pvt_ulCadFreqPu > cadence_stFreGetCof.uwMaxCadenceFre)
+    else if (cadence_stFreGetOut.uwCaputureOverflowCnt > cadence_stFreGetCof.uwHfMaxTimeCnt)
     {
         cadence_stFreGetOut.uwFrequencyPu = 0;
         cadence_stFreGetOut.uwLPFFrequencyPu = 0;
         cadence_stFreGetOut.blCadenceCalStartState = FALSE;
-        cadence_stFreGetOut.blCadenceSensorErrorFlg = TRUE;
+        cadence_stFreGetOut.blCadenceSensorErrorFlg = FALSE;
         cadence_stFreGetOut.uwCaputureOverflowCnt = 0;
         cadence_stFreGetOut.uwCaputureNumCnt = 0;
         cadence_stFreGetOut.uwCaputure2Cnt = 0;
         cadence_stFreGetOut.uwCaputure1Cnt = 0;
-        cadence_stFreGetOut.cadence_dir = CADENCE_DIR_ERROR;
-        cadence_stFreGetOut.cadence_fsm = CADENCE_ERROR;
+        cadence_stFreGetOut.cadence_dir = CADENCE_DIR_IDLE;
+        cadence_stFreGetOut.cadence_fsm = CADENCE_IDLE;
         cadence_stFreGetOut.uwFreqPercent = 0;
-        cp_stHistoryPara.uwCadSensorAlamTimes++;
     }
     else 
     {
         cadence_stFreGetOut.uwFrequencyPu = cad_pvt_ulCadFreqPu;
         
         cadence_stFreGetOut.uwLPFFrequencyPu = (cadence_stFreGetOut.uwLPFFrequencyPu * cadence_stFreGetCof.uwCadenceLPFgain +
-                                                cadence_stFreGetOut.uwFrequencyPu * (100 - cadence_stFreGetCof.uwCadenceLPFgain)) /
-                                                100;
+                                                cadence_stFreGetOut.uwFrequencyPu * (100 - cadence_stFreGetCof.uwCadenceLPFgain)) / 100;
         cadence_stFreGetOut.uwFreqPercent = (UWORD)(((ULONG)cadence_stFreGetOut.uwLPFFrequencyPu << 14) / cadence_stFreGetCof.uwMaxCadenceFre); // Q14
     }
 }
-
 /***************************************************************
- Function: cadence_voFreGet;
- Description: cadence frequency get
- Call by: functions in main loop;
+ Function: cadence_voCadenceBackword
+ Description: 
+ Call by: functions in main loop
  Input Variables: N/A
  Output/Return Variables: N/A
- Subroutine Call: N/A;
+ Subroutine Call: N/A
  Reference: N/A
 ****************************************************************/
 static void cadence_voCadenceBackword(UWORD source)
@@ -276,12 +273,12 @@ static void cadence_voCadenceBackword(UWORD source)
     }
 }
 /***************************************************************
- Function: cadence_voFreGet;
+ Function: cadence_voCadenceDir
  Description: cadence frequency get
- Call by: functions in main loop;
+ Call by: functions in main loop
  Input Variables: N/A
  Output/Return Variables: N/A
- Subroutine Call: N/A;
+ Subroutine Call: N/A
  Reference: N/A
 ****************************************************************/
 static void cadence_voCadenceDir(void)
@@ -296,12 +293,12 @@ static void cadence_voCadenceDir(void)
     }
 }
 /***************************************************************
- Function: cadence_voFreGet;
- Description: cadence frequency get
- Call by: functions in main loop;
+ Function: cadence_voCadenceError
+ Description: 
+ Call by: 
  Input Variables: N/A
  Output/Return Variables: N/A
- Subroutine Call: N/A;
+ Subroutine Call: N/A
  Reference: N/A
 ****************************************************************/
 static void cadence_voCadenceError(UWORD source)
@@ -317,14 +314,13 @@ static void cadence_voCadenceError(UWORD source)
         cadence_stFreGetOut.cadence_fsm = CADENCE_IDLE;
     }
 }
-
 /***************************************************************
-Function: cadence_voFreGetInit;
+Function: cadence_voFreGetInit
 Description: cadence frequency get initialization
-Call by: functions in main loop;
+Call by: 
 Input Variables: N/A
 Output/Return Variables: N/A
-Subroutine Call: N/A;
+Subroutine Call: N/A
 Reference: N/A
 ****************************************************************/
 void cadence_voCadenceInit(void)
@@ -341,14 +337,13 @@ void cadence_voCadenceInit(void)
     cadence_stFreGetOut.cadence_fsm = CADENCE_IDLE;
     cadence_stFreGetOut.cadence_dir = CADENCE_DIR_IDLE;
 }
-
 /***************************************************************
- Function: cadence_voFreGet;
+ Function: cadence_voCadenceCal
  Description: cadence frequency get
- Call by: functions in main loop;
+ Call by: 
  Input Variables: N/A
  Output/Return Variables: N/A
- Subroutine Call: N/A;
+ Subroutine Call: N/A
  Reference: N/A
 ****************************************************************/
 void cadence_voCadenceCal(UWORD source)

+ 4 - 0
User project/3.BasicFunction/Source/bikebrake.c

@@ -16,6 +16,10 @@
 #include "typedefine.h"
 #include "bikebrake.h"
 #include "hwsetup.h"
+
+#ifdef RUN_ARCH_SIM
+#include "test_user.h"
+#endif
 /******************************
  *
  *  Parameter

+ 108 - 41
User project/3.BasicFunction/Source/bikespeed.c

@@ -16,9 +16,11 @@
 #include "syspar.h"
 #include "bikespeed.h"
 #include "CodePara.h"
-#include "asr.h"
-#include "can.h"
 #include "hwsetup.h"
+
+#ifdef RUN_ARCH_SIM
+#include "test_user.h"
+#endif
 /******************************
  *
  *  Parameter
@@ -30,10 +32,12 @@ BIKESPEED_OUT bikespeed_stFreGetOut = BIKESPEED_OUT_DEFAULT;
 BIKESPDPI_IN bikespeed_stPIIn;
 static BIKESPDPI_COF  bikespeed_stPICof;
 BIKESPDPI_OUT bikespeed_stPIOut;
+
+static ULONG bikespeed_pvt_FreqPu = 0;
 /***************************************************************
- Function: bikespeed_voBikeSpeedCof;
+ Function: bikespeed_voBikeSpeedCof
  Description: Bike speed cof calculation
- Call by: functions in main loop;
+ Call by: 
  Input Variables: N/A
  Output/Return Variables: N/A
  Subroutine Call: N/A;
@@ -62,10 +66,10 @@ void bikespeed_voBikeSpeedCof(void)
 /***************************************************************
  Function: bikespeed_voBikeSpeedIdle;
  Description: bike speed function in idel state
- Call by: functions in main loop;
+ Call by: 
  Input Variables: N/A
  Output/Return Variables: N/A
- Subroutine Call: N/A;
+ Subroutine Call: N/A
  Reference: N/A
 ****************************************************************/
 static void bikespeed_voBikeSpeedIdle(UWORD source)
@@ -94,20 +98,20 @@ static void bikespeed_voBikeSpeedIdle(UWORD source)
 //            bikespeed_stFreGetOut.uwCaputureNumCnt = 0;
             bikespeed_stFreGetOut.uwCaputureNumCnt = 1;
             bikespeed_stFreGetOut.bikespeed_fsm = BIKESPEED_WORK;
-            
-            bikespeed_stFreGetOut.uwFrequencyPu = 1 * BIKESPEED_KMPERH2FREQPU;  
+            bikespeed_pvt_FreqPu = 1 * BIKESPEED_KMPERH2FREQPU ;
+            bikespeed_stFreGetOut.uwFrequencyPu =  (UWORD)bikespeed_pvt_FreqPu;  
             bikespeed_stFreGetOut.uwCaputure1Cnt = (UWORD)TIMER1_CAP_BIKESPD;
         }
     }
 }
 
 /***************************************************************
- Function: bikespeed_voBikeSpeedWork;
+ Function: bikespeed_voBikeSpeedWork
  Description: bike speed function in work state
- Call by: functions in main loop;
+ Call by: 
  Input Variables: N/A
  Output/Return Variables: N/A
- Subroutine Call: N/A;
+ Subroutine Call: N/A
  Reference: N/A
 ****************************************************************/
 static void bikespeed_voBikeSpeedWork(UWORD source)
@@ -116,6 +120,46 @@ static void bikespeed_voBikeSpeedWork(UWORD source)
     if (source == 1 && bikespeed_stFreGetOut.uwCaputureNumCnt == 1)
     {
         bikespeed_stFreGetOut.uwCaputureOverflowCnt++;
+        if (timer_interrupt_flag_get(TIMER1, TIMER_INT_FLAG_CH3) != 0)
+        {
+            bikespeed_stFreGetOut.uwCaputure2Cnt =(UWORD)TIMER1_CAP_BIKESPD;
+            if(bikespeed_stFreGetOut.uwCaputure2Cnt > 9000) // TIMER1 half Period 
+            {
+                bikespeed_stFreGetOut.uwOverflowfirst= 1;
+            }
+            else
+            {
+                bikespeed_stFreGetOut.uwOverflowfirst= 2;
+            }   
+
+            if(bikespeed_stFreGetOut.uwOverflowfirst == 1)
+            {
+                bikespeed_stFreGetOut.uwCaputureOverflowCnt -=1;
+                ulCaputureCntErr = ((ULONG)bikespeed_stFreGetOut.uwCaputureOverflowCnt * TIM1CLK_KHZ * bikespeed_stFreGetCof.uwTimerUnit) + bikespeed_stFreGetOut.uwCaputure2Cnt 
+                                    -bikespeed_stFreGetOut.uwCaputure1Cnt;
+                bikespeed_stFreGetOut.uwCaputureOverflowCnt = 1; 
+                bikespeed_stFreGetOut.uwOverflowfirst = 0;
+                
+            }
+            else
+            {
+                ulCaputureCntErr = ((ULONG)bikespeed_stFreGetOut.uwCaputureOverflowCnt * TIM1CLK_KHZ * bikespeed_stFreGetCof.uwTimerUnit) + bikespeed_stFreGetOut.uwCaputure2Cnt 
+                                    -bikespeed_stFreGetOut.uwCaputure1Cnt;
+                bikespeed_stFreGetOut.uwCaputureOverflowCnt = 0;
+                bikespeed_stFreGetOut.uwOverflowfirst = 0;
+            }
+
+            /* BikeSpeed Freq Cal */
+            bikespeed_pvt_FreqPu = (ULONG)(((UQWORD)720000 << 20) / ((UQWORD)ulCaputureCntErr * bikespeed_stFreGetCof.uwNumbersPulses * FBASE));
+
+            bikespeed_stFreGetOut.uwCaputureNumCnt = 1;
+            bikespeed_stFreGetOut.uwCaputure1Cnt = bikespeed_stFreGetOut.uwCaputure2Cnt; 
+            timer_interrupt_flag_clear(TIMER1, TIMER_INT_FLAG_CH3);
+        }
+        else
+        {
+            bikespeed_stFreGetOut.uwOverflowfirst= 0;
+        }
     }
     else if (source == 3)
     {
@@ -129,21 +173,25 @@ static void bikespeed_voBikeSpeedWork(UWORD source)
             bikespeed_stFreGetOut.uwCaputureNumCnt = 2;
             bikespeed_stFreGetOut.uwCaputure2Cnt = (UWORD)TIMER1_CAP_BIKESPD;
 
-            ulCaputureCntErr = (ULONG)(((UQWORD)bikespeed_stFreGetOut.uwCaputureOverflowCnt * (720 * bikespeed_stFreGetCof.uwTimerUnit)) -
-                               bikespeed_stFreGetOut.uwCaputure1Cnt + bikespeed_stFreGetOut.uwCaputure2Cnt);
+            ulCaputureCntErr = (ULONG)(((UQWORD)bikespeed_stFreGetOut.uwCaputureOverflowCnt * (720 * bikespeed_stFreGetCof.uwTimerUnit))+ bikespeed_stFreGetOut.uwCaputure2Cnt
+                                - bikespeed_stFreGetOut.uwCaputure1Cnt);
             
             bikespeed_stFreGetOut.uwCaputureOverflowMinCnt = (UWORD)(bikespeed_stFreGetOut.uwCaputureOverflowCnt << 1);
             if(bikespeed_stFreGetOut.uwCaputureOverflowMinCnt > bikespeed_stFreGetCof.uwHfMinTimeCnt)
             {
-              bikespeed_stFreGetOut.uwCaputureOverflowMinCnt = bikespeed_stFreGetCof.uwHfMinTimeCnt;
+                bikespeed_stFreGetOut.uwCaputureOverflowMinCnt = bikespeed_stFreGetCof.uwHfMinTimeCnt;
+            }
+            else if(bikespeed_stFreGetOut.uwCaputureOverflowMinCnt < 1)
+            {
+                bikespeed_stFreGetOut.uwCaputureOverflowMinCnt = 1;
             }
             else
             {
+                //do noting
             }
-            // ulCaputureCntErr =  ((SQWORD)bikespeed_stFreGetOut.uwCaputureOverflowCnt*(72000000/100/(1000/bikespeed_stFreGetCof.uwTimerUnit))) -
-            // bikespeed_stFreGetOut.uwCaputure1Cnt + bikespeed_stFreGetOut.uwCaputure2Cnt;
-            bikespeed_stFreGetOut.uwFrequencyPu =
-                (UWORD)(((SQWORD)720000 << 20) / ((SQWORD)ulCaputureCntErr * bikespeed_stFreGetCof.uwNumbersPulses * FBASE));
+
+            /* BikeSpeed Freq Cal */
+            bikespeed_pvt_FreqPu = (ULONG)(((UQWORD)720000 << 20) / ((UQWORD)ulCaputureCntErr * bikespeed_stFreGetCof.uwNumbersPulses * FBASE));
             bikespeed_stFreGetOut.uwCaputure1Cnt = bikespeed_stFreGetOut.uwCaputure2Cnt;
             bikespeed_stFreGetOut.uwBikeForwardCnt++;
             bikespeed_stFreGetOut.uwCaputureOverflowCnt = 0;
@@ -159,7 +207,7 @@ static void bikespeed_voBikeSpeedWork(UWORD source)
     	//do noting
     }
    
-    if (bikespeed_stFreGetOut.uwCaputureOverflowCnt >= bikespeed_stFreGetOut.uwCaputureOverflowMinCnt) //
+    if (bikespeed_pvt_FreqPu > bikespeed_stFreGetCof.uwMaxBikeSpeedFre) 
     {
         bikespeed_stFreGetOut.uwFrequencyPu = 0;
         bikespeed_stFreGetOut.blBikeSpeedCalStartState = FALSE;
@@ -167,11 +215,12 @@ static void bikespeed_voBikeSpeedWork(UWORD source)
         bikespeed_stFreGetOut.uwCaputureNumCnt = 0;
         bikespeed_stFreGetOut.uwCaputure2Cnt = 0;
         bikespeed_stFreGetOut.uwCaputure1Cnt = 0;
-        bikespeed_stFreGetOut.bikespeed_fsm = BIKESPEED_IDLE;
+        bikespeed_stFreGetOut.bikespeed_fsm = BIKESPEED_ERROR;
+        bikespeed_stFreGetOut.blBikeSpeedSensorErrorFlg = TRUE;
         bikespeed_stFreGetOut.uwCaputureOverflowMinCnt = bikespeed_stFreGetCof.uwHfMinTimeCnt;
+        cp_stHistoryPara.uwBikeSpdSensorAlamTimes++;
     }
-
-    if (bikespeed_stFreGetOut.uwLPFFrequencyPu >= bikespeed_stFreGetCof.uwMaxBikeSpeedFre) // 100ms
+    else if (bikespeed_stFreGetOut.uwCaputureOverflowCnt > bikespeed_stFreGetOut.uwCaputureOverflowMinCnt) 
     {
         bikespeed_stFreGetOut.uwFrequencyPu = 0;
         bikespeed_stFreGetOut.blBikeSpeedCalStartState = FALSE;
@@ -179,20 +228,22 @@ static void bikespeed_voBikeSpeedWork(UWORD source)
         bikespeed_stFreGetOut.uwCaputureNumCnt = 0;
         bikespeed_stFreGetOut.uwCaputure2Cnt = 0;
         bikespeed_stFreGetOut.uwCaputure1Cnt = 0;
-        bikespeed_stFreGetOut.bikespeed_fsm = BIKESPEED_ERROR;
-        bikespeed_stFreGetOut.blBikeSpeedSensorErrorFlg = TRUE;
+        bikespeed_stFreGetOut.bikespeed_fsm = BIKESPEED_IDLE;
         bikespeed_stFreGetOut.uwCaputureOverflowMinCnt = bikespeed_stFreGetCof.uwHfMinTimeCnt;
-        cp_stHistoryPara.uwBikeSpdSensorAlamTimes++;
+    }
+    else 
+    {
+        bikespeed_stFreGetOut.uwFrequencyPu = (UWORD)bikespeed_pvt_FreqPu;
     }
 }
 
 /***************************************************************
- Function: bikespeed_voBikeSpeedError;
+ Function: bikespeed_voBikeSpeedError
  Description: bike speed error judge
- Call by: functions in main loop;
+ Call by: 
  Input Variables: N/A
  Output/Return Variables: N/A
- Subroutine Call: N/A;
+ Subroutine Call: N/A
  Reference: N/A
 ****************************************************************/
 static void bikespeed_voBikeSpeedError(UWORD source)
@@ -247,12 +298,12 @@ void bikespeed_voGetBikeSpeedPwrError(UWORD BikeSpeedPwrVolPu)
 }
 
 /***************************************************************
- Function: bikespeed_voBikeSpeedInit;
+ Function: bikespeed_voBikeSpeedInit
  Description: Bike speed initialization
- Call by: functions in main loop;
+ Call by: 
  Input Variables: N/A
  Output/Return Variables: N/A
- Subroutine Call: N/A;
+ Subroutine Call: N/A
  Reference: N/A
 ****************************************************************/
 void bikespeed_votempTripCal(void)
@@ -267,12 +318,12 @@ void bikespeed_votempTripCal(void)
 } 
 
 /***************************************************************
-  Function: bikespeed_voBikeSpeedInit;
+  Function: bikespeed_voBikeSpeedInit
   Description: Bike speed initialization
-  Call by: functions in main loop;
+  Call by: 
   Input Variables: N/A
   Output/Return Variables: N/A
-  Subroutine Call: N/A;
+  Subroutine Call: N/A
   Reference: N/A
  ****************************************************************/
 void bikespeed_voBikeSpeedInit(void)
@@ -295,10 +346,10 @@ void bikespeed_voBikeSpeedInit(void)
 /***************************************************************
  Function: bikespeed_voBikeSpeedCal;
  Description: bike speed FSM
- Call by: functions in main loop;
+ Call by: 
  Input Variables: N/A
  Output/Return Variables: N/A
- Subroutine Call: N/A;
+ Subroutine Call: N/A
  Reference: N/A
 ****************************************************************/
 void bikespeed_voBikeSpeedCal(UWORD source)
@@ -320,12 +371,12 @@ void bikespeed_voBikeSpeedCal(UWORD source)
 }
 
 /***************************************************************
- Function: bikespeedinput, motorspeedoutput;
+ Function: bikespeed_voPIInit
  Description:  
- Call by: ;
+ Call by: 
  Input Variables: N/A
  Output/Return Variables: N/A
- Subroutine Call: N/A;
+ Subroutine Call: N/A
  Reference: N/A
 ****************************************************************/
 void bikespeed_voPIInit(void)
@@ -334,13 +385,29 @@ void bikespeed_voPIInit(void)
     bikespeed_stPIOut.slIqRefPu = 0;
     bikespeed_stPIOut.swIqRefPu = 0;
 }
-
+/***************************************************************
+ Function: bikespeed_voPICoef
+ Description:  
+ Call by: 
+ Input Variables: N/A
+ Output/Return Variables: N/A
+ Subroutine Call: N/A
+ Reference: N/A
+****************************************************************/
 void bikespeed_voPICoef(void)
 {
      bikespeed_stPICof.uwKpPu = 25000 ;   //Q15
      bikespeed_stPICof.uwKiPu = 500 ;    //Q15
 }
-
+/***************************************************************
+ Function: bikespeed_voPI
+ Description:  
+ Call by: 
+ Input Variables: N/A
+ Output/Return Variables: N/A
+ Subroutine Call: N/A
+ Reference: N/A
+****************************************************************/
 void bikespeed_voPI(const BIKESPDPI_IN *in, BIKESPDPI_OUT *out)
 {
     SLONG  slIqMaxPu, slIqMinPu;  // Q30

+ 145 - 0
unit_test/test_bikespeed.cpp

@@ -0,0 +1,145 @@
+#include "gtest/gtest.h"
+#include <gtest/gtest.h>
+#include <tuple>
+#include "test_user.h"
+#include "hwsetup.h"
+#include "scope.h"
+
+class BikeSpeedTest : public testing::Test
+{
+protected:
+    static void SetUpTestSuite()
+    {
+        bikespeed_voBikeSpeedInit();
+    }
+    virtual void SetUp() override
+    {
+
+    }
+    virtual void TearDown() override
+    {
+
+    }
+};
+
+class BikeSpeedTest1 : public BikeSpeedTest, public testing::WithParamInterface<int>
+{};
+
+TEST_P(BikeSpeedTest1, FreCal)
+{
+    /* Coef Cal */
+    bikespeed_voBikeSpeedCof();
+    bikespeed_stFreGetCof.uwNumbersPulses = BIKESPEED_NUMBERS_PULSES;
+
+    int timerPrd = TIM1CLK_KHZ * 1000 / (1000 / 25);  // cnt = 18000, same as STM32
+    int timerCnt = 0;
+    int bikeSpeedSignal = 0, bikeSpeedCnt = 0, bikeSpeedSignalLast = 0;
+    int bikeSpeedPrd = GetParam();
+    int capValue = 0; 
+
+    /* BikeSpeed Freq Cal */
+    for(int i = 0; i < 100000000; i++)
+    {  
+        /* Input BikeSpeed Signal */
+        bikeSpeedCnt++;
+        if(bikeSpeedCnt <= (bikeSpeedPrd/10))   // 10% duty
+        {
+            bikeSpeedSignal = 0;
+        }
+        else 
+        {
+            bikeSpeedSignal = 1;
+            if(bikeSpeedCnt >= bikeSpeedPrd)
+            {
+                bikeSpeedCnt = 0;
+            }
+        }
+        
+        /* Timer */
+        timerCnt ++ ;
+        if(timerCnt >= timerPrd - 1)
+        {
+            timerCnt = 0;
+            testTimerIntFlg[TIMER1][TIMER_INT_FLAG_UP] = 1;
+        }
+
+        /* Capture: rising edge trigger*/
+        if(bikeSpeedSignal - bikeSpeedSignalLast == 1)    
+        {
+            testCh3CapValue[TIMER1] = timerCnt;
+            testTimerIntFlg[TIMER1][TIMER_INT_FLAG_CH3] = 1;
+        }
+        bikeSpeedSignalLast = bikeSpeedSignal;
+
+        /* Interrupt: update and capture */       
+        if(testTimerIntFlg[TIMER1][TIMER_INT_FLAG_UP])  
+        {
+            bikespeed_voBikeSpeedCal(1);
+            testTimerIntFlg[TIMER1][TIMER_INT_FLAG_UP] = 0;
+        }
+        else if(testTimerIntFlg[TIMER1][TIMER_INT_FLAG_CH3])
+        {
+            bikespeed_voBikeSpeedCal(3);
+            testTimerIntFlg[TIMER1][TIMER_INT_FLAG_CH3] = 0;
+        }      
+        //UdpScope::Send(0, bikespeed_stFreGetOut.uwFrequencyPu);       
+    }
+
+    double bikeSpeedFreqPu = (double)TIM1CLK_KHZ * 1000 * 1048576 / bikeSpeedPrd / FBASE / bikespeed_stFreGetCof.uwNumbersPulses;  // Q20
+
+    if(bikeSpeedFreqPu > bikespeed_stFreGetCof.uwMaxBikeSpeedFre || bikespeed_stFreGetOut.uwCaputureOverflowCnt > bikespeed_stFreGetOut.uwCaputureOverflowMinCnt)
+    {
+        EXPECT_NEAR(bikespeed_stFreGetOut.uwFrequencyPu, 0, 0.1);
+    }
+    else 
+    {
+        EXPECT_NEAR(bikespeed_stFreGetOut.uwFrequencyPu, bikeSpeedFreqPu, 2);
+    }
+}
+
+INSTANTIATE_TEST_SUITE_P(DiffBikeSpeedPeriod, BikeSpeedTest1,
+                         ::testing::Values(0, 500, 3000, 18002, 100000,1000000));
+
+TEST_F(BikeSpeedTest, FreCal2)
+{
+    /* Coef Cal */
+    bikespeed_voBikeSpeedCof();
+    bikespeed_stFreGetCof.uwNumbersPulses = BIKESPEED_NUMBERS_PULSES;
+
+    /* Test conditions */
+    bikespeed_stFreGetOut.bikespeed_fsm = BIKESPEED_WORK;
+    bikespeed_stFreGetOut.uwCaputureNumCnt = 1;
+    bikespeed_stFreGetOut.uwCaputure1Cnt = 0;
+    bikespeed_stFreGetOut.uwCaputureOverflowCnt = 3;
+
+    double overflowCnt = bikespeed_stFreGetOut.uwCaputureOverflowCnt;
+    double cap1Cnt = bikespeed_stFreGetOut.uwCaputure1Cnt;
+
+    testTimerIntFlg[TIMER1][TIMER_INT_FLAG_UP] = 1;
+    testCh3CapValue[TIMER1] = 17900;
+    testTimerIntFlg[TIMER1][TIMER_INT_FLAG_CH3] = 1;
+
+    /* Interrupt: update and capture */       
+    if(testTimerIntFlg[TIMER1][TIMER_INT_FLAG_UP])  
+    {
+        bikespeed_voBikeSpeedCal(1);
+        testTimerIntFlg[TIMER1][TIMER_INT_FLAG_UP] = 0;
+    }
+    else if(testTimerIntFlg[TIMER1][TIMER_INT_FLAG_CH3])
+    {
+        bikespeed_voBikeSpeedCal(3);
+        testTimerIntFlg[TIMER1][TIMER_INT_FLAG_CH3] = 0;
+    }        
+
+    double bikeSpeedFreqPu =  overflowCnt * 18000 + bikespeed_stFreGetOut.uwCaputure2Cnt - cap1Cnt;
+    bikeSpeedFreqPu = (double)TIM1CLK_KHZ * 1000 * 1048576 / bikeSpeedFreqPu / FBASE / bikespeed_stFreGetCof.uwNumbersPulses;  // Q20
+
+    if(bikeSpeedFreqPu > bikespeed_stFreGetCof.uwMaxBikeSpeedFre || bikespeed_stFreGetOut.uwCaputureOverflowCnt > bikespeed_stFreGetOut.uwCaputureOverflowMinCnt)
+    {
+        EXPECT_NEAR(bikespeed_stFreGetOut.uwFrequencyPu, 0, 0.1);
+    }
+    else 
+    {
+        EXPECT_NEAR(bikespeed_stFreGetOut.uwFrequencyPu, bikeSpeedFreqPu, 2);
+    }
+}

+ 10 - 2
unit_test/test_cadence.cpp

@@ -89,7 +89,7 @@ TEST_P(CadenceTest1, FreCal)
 
     double cadFreqPu = (double)TIM1CLK_KHZ * 1000 * 2 * 1048576 / cadencePrd / FBASE / cadence_stFreGetCof.uwNumbersPulses;  // Q20
 
-    if(cadFreqPu > cadence_stFreGetCof.uwMaxCadenceFre || cadence_stFreGetOut.uwCaputureOverflowCnt >= cadence_stFreGetCof.uwHfMaxTimeCnt || cadence_stFreGetOut.cadence_dir == 1)
+    if(cadFreqPu > cadence_stFreGetCof.uwMaxCadenceFre || cadence_stFreGetOut.uwCaputureOverflowCnt > cadence_stFreGetCof.uwHfMaxTimeCnt || cadence_stFreGetOut.cadence_dir == 1)
     {
         EXPECT_NEAR(cadence_stFreGetOut.uwFrequencyPu, 0, 0.1);
     }
@@ -113,6 +113,7 @@ TEST_F(CadenceTest, FreCal2)
     cadence_stFreGetOut.uwCaputureNumCnt = 1;
     cadence_stFreGetOut.uwCaputure1Cnt = 0;
     cadence_stFreGetOut.uwCaputureOverflowCnt = 0;
+    testGpioBValue[GPIOB] = 0;
 
     double overflowCnt = cadence_stFreGetOut.uwCaputureOverflowCnt;
     double cap1Cnt = cadence_stFreGetOut.uwCaputure1Cnt;
@@ -136,5 +137,12 @@ TEST_F(CadenceTest, FreCal2)
     double cadFreqPu =  overflowCnt * 18000 + cadence_stFreGetOut.uwCaputure2Cnt - cap1Cnt;
     cadFreqPu = (double)TIM1CLK_KHZ * 1000 * 2 * 1048576 / cadFreqPu / FBASE / cadence_stFreGetCof.uwNumbersPulses;  // Q20
 
-    EXPECT_NEAR(cadence_stFreGetOut.uwFrequencyPu, cadFreqPu, 2);
+    if(cadFreqPu > cadence_stFreGetCof.uwMaxCadenceFre || cadence_stFreGetOut.uwCaputureOverflowCnt > cadence_stFreGetCof.uwHfMaxTimeCnt || cadence_stFreGetOut.cadence_dir == 1)
+    {
+        EXPECT_NEAR(cadence_stFreGetOut.uwFrequencyPu, 0, 0.1);
+    }
+    else 
+    {
+        EXPECT_NEAR(cadence_stFreGetOut.uwFrequencyPu, cadFreqPu, 2);
+    }
 }

+ 1 - 0
unit_test/test_user.c

@@ -2,6 +2,7 @@
 
 int testTimerIntFlg[2][4];
 int testCh2CapValue[2];
+int testCh3CapValue[2];
 int testGpioBValue[2];
 
 int timer_interrupt_flag_get(int timer_periph, int interrupt)

+ 8 - 0
unit_test/test_user.h

@@ -1,4 +1,7 @@
 #include "Cadence.h"
+#include "bikespeed.h"
+
+
 
 #ifndef _TEST_USER_H_
 #define _TEST_USER_H_
@@ -14,12 +17,17 @@ extern "C" {
 #define TIMER_INT_FLAG_CH3 3
 
 #define GPIOB 1
+#define GPIOC 2
 
 #define TIMER_CH2CV(timex) testCh2CapValue[timex]
+#define TIMER_CH3CV(timex) testCh3CapValue[timex]
 #define GPIO_ISTAT(gpiox)  testGpioBValue[gpiox]
 
+#define abs(x)    ((x) >= 0 ? (x) : (-(x)))
+
 extern int testTimerIntFlg[2][4];
 extern int testCh2CapValue[2];
+extern int testCh3CapValue[2];
 extern int testGpioBValue[2];
 
 int  timer_interrupt_flag_get(int timer_periph, int interrupt);

+ 3 - 2
xmake.lua

@@ -6,8 +6,9 @@ target("unittest")
     set_kind("binary")
     set_languages("c++20")
 
-    add_files("unit_test/*.cpp","unit_test/tools/*.cpp","unit_test/tools/*.c")
-    add_files("User project/3.BasicFunction/Source/Cadence.c","unit_test/test_user.c","User project/4.BasicHardwSoftwLayer/2.BasicSoftwLayer/Source/CodePara.c")
+    add_files("unit_test/*.cpp","unit_test/tools/*.cpp","unit_test/tools/*.c", "unit_test/*.c")
+    add_files("User project/3.BasicFunction/Source/Cadence.c", "User project/4.BasicHardwSoftwLayer/2.BasicSoftwLayer/Source/CodePara.c")
+    add_files("User project/3.BasicFunction/Source/bikespeed.c")
 
     -- add_includedirs("Std project/CMSIS")
     -- add_includedirs("Std project/CMSIS/GD/GD32F30x/Inc_GD")