Prechádzať zdrojové kódy

V5.1.0_20200615
1、调整3相电流有效值测量的函数;
2、无速度传感器时对车速的计算,改为结合踏频和电机转速同时判断,取大值,并且将车速更新到MC_SpeedSensorData.Speed_Data,解决指拨模式下无法限速;
3、缺相检测的阈值,由500调整为300;
4、指拨模式处理,解决滑行开机时第一次进入指拨模式将速比更新为较小值的问题;
5、指拨模式限速最大值调整为+20;
6、加入指拨模式四个档位的区别,主要是最高速;
7、指拨模式限流调整为采用PID_ConstantPower;
8、调整低力矩停机的延时,由1/4圈调整为1/3圈;
9、更改用户参数1中速度传感器配置,由是否支持无速度传感器改为速度信号来源,设置有三种,车轮信号、踏频、通信;
10、增加速度信号来自通信时的车速、里程、续航计算;
11、0x3708指令中,增加更新通信的轮速信号;
12、对ECU的通信超时判断由1s改为30s;
13、版本号:V5.1.0_20200615

dail.zhou 5 rokov pred
rodič
commit
d73c8cfef6

+ 1 - 1
Core/Inc/adc.h

@@ -118,7 +118,7 @@ extern uint16_t uw_current_offset;//ĸ
 
 extern void ADC_Start(void);
 extern void ADC_SensorData_Filt(uint16_t* p_ADC1_Result_Filt, uint16_t* p_ADC2_Result_Filt);
-extern void PhaseCurrent_CalRMSValue(uint16_t* ADC2_Filt, ADC_3ShuntCurrent_Struct_t* PhaseCurrent_RMS);
+extern void PhaseCurrent_CalRMSValue(ADC_3ShuntCurrent_Struct_t* ADC_3ShuntCurrent, ADC_3ShuntCurrent_Struct_t* PhaseCurrent_RMS);
 /* USER CODE END Prototypes */
 
 #ifdef __cplusplus

+ 18 - 18
Core/Src/adc.c

@@ -396,7 +396,7 @@ void HAL_ADCEx_InjectedConvCpltCallback(ADC_HandleTypeDef* hadc)
 	ADC_3ShuntCurrent.uw_phase_c = (int16_t)(ADC_3ShuntCurrent_OffSet.uw_phase_c_offset - ADC2_Result[ADC2_RANK_CURRENT_C]);
 	
 	///计算三相电流有效值
-	PhaseCurrent_CalRMSValue(ADC2_Result, &ADC_3ShuntCurrent_RMSValue);
+	PhaseCurrent_CalRMSValue(&ADC_3ShuntCurrent, &ADC_3ShuntCurrent_RMSValue);
 	
 	ADC2_ConvCpmplete_Flag = SET;
 }
@@ -511,50 +511,50 @@ void ADC_SensorData_Filt(uint16_t* p_ADC1_Result_Filt, uint16_t* p_ADC2_Result_F
 }
 
 //相电流有效值计算,有效值 = 最大值 * 0.707,运行频率15K
-void PhaseCurrent_CalRMSValue(uint16_t* ADC2_Result, ADC_3ShuntCurrent_Struct_t* PhaseCurrent_RMS)
+void PhaseCurrent_CalRMSValue(ADC_3ShuntCurrent_Struct_t* ADC_3ShuntCurrent, ADC_3ShuntCurrent_Struct_t* PhaseCurrent_RMS)
 {
-  static uint16_t	PhaseCurrentA_Max = 0;
-	static uint16_t PhaseCurrentB_Max = 0;
-	static uint16_t PhaseCurrentC_Max = 0;
-	static uint16_t Count = 0;
+  static int16_t	PhaseCurrentA_Max = 0;
+	static int16_t PhaseCurrentB_Max = 0;
+	static int16_t PhaseCurrentC_Max = 0;
+	static int16_t Count = 0;
 	int16_t DataTemp;
 	static int32_t PhaseCurrentA_FltSum = 0;
 	static int32_t PhaseCurrentB_FltSum = 0;
 	static int32_t PhaseCurrentC_FltSum = 0;
 	
 	//计算A相电流峰值
-	if(PhaseCurrentA_Max < ADC2_Result[ADC2_RANK_CURRENT_A])
+	if(PhaseCurrentA_Max < ADC_3ShuntCurrent->uw_phase_a)
 	{
-	  PhaseCurrentA_Max = ADC2_Result[ADC2_RANK_CURRENT_A];
+	  PhaseCurrentA_Max = ADC_3ShuntCurrent->uw_phase_a;
 	}
 	//计算B相电流峰值
-	if(PhaseCurrentB_Max < ADC2_Result[ADC2_RANK_CURRENT_B])
+	if(PhaseCurrentB_Max < ADC_3ShuntCurrent->uw_phase_b)
 	{
-	  PhaseCurrentB_Max = ADC2_Result[ADC2_RANK_CURRENT_B];
+	  PhaseCurrentB_Max = ADC_3ShuntCurrent->uw_phase_b;
 	}
 	//计算C相电流峰值
-	if(PhaseCurrentC_Max < ADC2_Result[ADC2_RANK_CURRENT_C])
+	if(PhaseCurrentC_Max < ADC_3ShuntCurrent->uw_phase_c)
 	{
-	  PhaseCurrentC_Max = ADC2_Result[ADC2_RANK_CURRENT_C];
+	  PhaseCurrentC_Max = ADC_3ShuntCurrent->uw_phase_c;
 	}
 	
 	Count++;
 	if(Count >= 500)
 	{
 	  //计算A相电流有效值
-		DataTemp = PhaseCurrentA_Max - ADC_3ShuntCurrent_OffSet.uw_phase_a_offset;
+		DataTemp = PhaseCurrentA_Max;
 		PhaseCurrentA_Max = 0;
-		PhaseCurrentA_FltSum += (((abs(DataTemp) * 724)) - PhaseCurrentA_FltSum) >> 4;
+		PhaseCurrentA_FltSum += (((abs(DataTemp) * 724)) - PhaseCurrentA_FltSum) >> 5;
 		PhaseCurrent_RMS->uw_phase_a = PhaseCurrentA_FltSum >> 10;
 		//计算B相电流有效值
-		DataTemp = PhaseCurrentB_Max - ADC_3ShuntCurrent_OffSet.uw_phase_b_offset;
+		DataTemp = PhaseCurrentB_Max;
 		PhaseCurrentB_Max = 0;
-		PhaseCurrentB_FltSum += (((abs(DataTemp) * 724)) - PhaseCurrentB_FltSum) >> 4;
+		PhaseCurrentB_FltSum += (((abs(DataTemp) * 724)) - PhaseCurrentB_FltSum) >> 5;
 		PhaseCurrent_RMS->uw_phase_b = PhaseCurrentB_FltSum >> 10;
 		//计算C相电流有效值
-		DataTemp = PhaseCurrentC_Max - ADC_3ShuntCurrent_OffSet.uw_phase_c_offset;
+		DataTemp = PhaseCurrentC_Max;
 		PhaseCurrentC_Max = 0;
-		PhaseCurrentC_FltSum += (((abs(DataTemp) * 724)) - PhaseCurrentC_FltSum) >> 4;
+		PhaseCurrentC_FltSum += (((abs(DataTemp) * 724)) - PhaseCurrentC_FltSum) >> 5;
 		PhaseCurrent_RMS->uw_phase_c = PhaseCurrentC_FltSum >> 10;
 		
 		Count = 0;

+ 16 - 4
Core/Src/main.c

@@ -238,13 +238,25 @@ int main(void)
 			MC_UartRxCheck_Process();
 			
 			//速度传感器采集及计算
-			if(MC_ConfigParam1.No_SpeedSensor_Flag != MC_SUPPORT_ENABLE)
+			if(MC_ConfigParam1.SpeedSignal == MC_SPEED_CADENCE_CAL) //0xAA, 根据踏频估算
 			{
-				SpeedSensor_Process(&MC_SpeedSensorData, &MC_RunInfo.BikeSpeed, MC_ConfigParam1.WheelSize + MC_ConfigParam1.WheelSizeAdj, (MC_ConfigParam1.SpeedSensorPoles == 0) ? 1: MC_ConfigParam1.SpeedSensorPoles);
+				if(MC_RunInfo.CadenceDir != MC_Cadence_Forward) //脚踏向后或停止时,采用电机转速
+				{
+					SpeedCal_ByCadence(MC_RunInfo.MotorSpeed / 11, &MC_SpeedSensorData.Speed_Data, MC_ConfigParam1.TeethNum_F, MC_ConfigParam1.TeethNum_B, MC_ConfigParam1.WheelSize + MC_ConfigParam1.WheelSizeAdj, &MC_RunInfo.BikeSpeed);			
+				}
+				else //脚踏向前时,取大值
+				{
+					SpeedCal_ByCadence((MC_RunInfo.MotorSpeed / 11 > MC_RunInfo.Cadence) ?  MC_RunInfo.MotorSpeed / 11 : MC_RunInfo.Cadence, &MC_SpeedSensorData.Speed_Data, MC_ConfigParam1.TeethNum_F, MC_ConfigParam1.TeethNum_B, MC_ConfigParam1.WheelSize + MC_ConfigParam1.WheelSizeAdj, &MC_RunInfo.BikeSpeed);			
+				}
+				
 			}
-			else
+			else if(MC_ConfigParam1.SpeedSignal == MC_SPEED_COMMUNICATION) //0xEE, 根据通信获取的车轮旋转周期
 			{
-				SpeedCal_ByCadence(MC_RunInfo.Cadence, MC_ConfigParam1.TeethNum_F, MC_ConfigParam1.TeethNum_B, MC_ConfigParam1.WheelSize + MC_ConfigParam1.WheelSizeAdj, &MC_RunInfo.BikeSpeed);
+			  SpeedCal_ByCommunication(&MC_SpeedSensorData, &MC_RunInfo.BikeSpeed, MC_ConfigParam1.WheelSize + MC_ConfigParam1.WheelSizeAdj);
+			}
+			else
+			{	
+				SpeedSensor_Process(&MC_SpeedSensorData, &MC_RunInfo.BikeSpeed, MC_ConfigParam1.WheelSize + MC_ConfigParam1.WheelSizeAdj, (MC_ConfigParam1.SpeedSensorPoles == 0) ? 1: MC_ConfigParam1.SpeedSensorPoles);
 			}
 			
 			//检测变速信号

BIN
MDK-ARM/bin/QD007A_CTL_APP_CRC.bin → MDK-ARM/bin/MC_VR7500_V5r1r0_20200615.bin


BIN
MDK-ARM/bin/QD007A_CTL_APP.bin


+ 3 - 2
User/Inc/speed_sensor.h

@@ -21,6 +21,7 @@ extern MC_SpeedSensorData_Struct_t MC_SpeedSensorData;
 extern uint16_t MC_Speed_Array[10];
 
 extern void SpeedSensor_GPIO_Init(void);
-extern void SpeedSensor_Process(MC_SpeedSensorData_Struct_t* MC_SpeedSensorData, uint16_t* AvgResult, uint8_t WheelSize, uint8_t Poles);
-extern void SpeedCal_ByCadence(uint16_t CadenceData, uint8_t T_Front, uint8_t T_Tail, uint16_t WheelSize, uint16_t* BikeSpeed);
+void SpeedSensor_Process(MC_SpeedSensorData_Struct_t* p_MC_SpeedSensorData, uint16_t* AvgResult, uint8_t WheelSize, uint8_t Poles);
+extern void SpeedCal_ByCadence(uint16_t CadenceData, uint16_t* SpeedData, uint8_t T_Front, uint8_t T_Tail, uint16_t WheelSize, uint16_t* BikeSpeed);
+extern void SpeedCal_ByCommunication(MC_SpeedSensorData_Struct_t* p_MC_SpeedSensorData, uint16_t* AvgResult, uint8_t WheelSize);
 #endif

+ 8 - 1
User/Inc/var.h

@@ -132,6 +132,13 @@ typedef enum MC_SUPPORTFLAG
 	MC_SUPPORT_DISABLE = (uint8_t)0x55  //不支持
 }MC_SupportFlag_Struct_t;
 
+typedef enum MC_SPEED_SIGNAL
+{
+  MC_SPEED_CADENCE_CAL = (uint8_t)0xAA,  //根据踏频估算
+	MC_SPEED_WHEEL_TRIG = (uint8_t)0x55,   //根据车轮信号触发
+	MC_SPEED_COMMUNICATION = (uint8_t)0xEE //根据通信数据,车轮旋转1圈的时间
+}MC_SpeedSignal_Struct_t;
+
 //用户配置参数1,占用空间32bytes
 typedef struct
 {
@@ -155,7 +162,7 @@ typedef struct
 	UserAdjParam_Struct_t UserAdjParam_SMART;    //用户微调助力比增益和加速度增益,地址偏移22
   uint8_t SpeedSensorPoles;                    //速度传感器极数,地址偏移24
 	uint8_t CadenceStarNum;                      //踏频启动信号个数,地址偏移25
-	MC_SupportFlag_Struct_t No_SpeedSensor_Flag; //0x55-不支持,0x-AA支持,地址偏移26
+	MC_SpeedSignal_Struct_t SpeedSignal;         //0x55-车轮触发,0x-AA踏频计算,0xEE-通讯获取车轮旋转周期,地址偏移26
 	int8_t WheelSizeAdj;                         //周长微调值,地址偏移27
 	uint8_t RS[4];//地址偏移28
 }MC_ConfigParam1_Struct_t;

+ 10 - 2
User/Src/can_process.c

@@ -8,6 +8,7 @@
 #include "tasks.h"
 #include "ctf_process.h"
 #include "log_save.h"
+#include "speed_sensor.h"
 
 /**********局部函数定义**********/
 uint8_t cd_ReadChar(CAN_Buf_TypeDef * ptCANRx, uint8_t ucNum)	 
@@ -224,10 +225,17 @@ void DataProcess(uint16_t ID, uint8_t Mode, uint16_t Cmd, uint8_t* Data)
 				}
 				case 0x3708://ECU控制指令
 				{
-				if(MC_WorkMode == MC_WorkMode_Run)
+			  	if(MC_WorkMode == MC_WorkMode_Run)
 					{
-					  memcpy(&MC_ControlCode.GearSt, Data, 2);
+					  //更新档位
+						memcpy(&MC_ControlCode.GearSt, Data, 2);
 					  Update_MC_ControlCode_Back();
+						//更新轮速,仅配置为通过通信获取车轮周期时更新
+						if(MC_ConfigParam1.SpeedSignal == MC_SPEED_COMMUNICATION)
+						{
+							MC_SpeedSensorData.DiffTime_ms = (Data[3] << 8) + Data[2];
+							MC_SpeedSensorData.IsTrigFlag = TRUE;
+						}
 					}			
 		      MC_RunInfo.GearSt = MC_ControlCode.GearSt;//当前助力档位更新
 					MC_RunInfo.LightSwitch = MC_ControlCode.LightSwitch;

+ 4 - 4
User/Src/fault_check.c

@@ -172,7 +172,7 @@ void MC_Fault_PhaseLine_Process(FlagStatus Foc_Flag, uint16_t BusCurrent, uint16
 	  if((Foc_Flag == SET) && (BusCurrent > 5000) && (MotorSpeed > 500))
 		{
 		  //A相电流
-			if(abs(Phase_Current.uw_phase_a) < 500)
+			if(abs(Phase_Current.uw_phase_a) < 300)
 			{
 			  if((HAL_GetTick() - TrigTimeCnt_PhaseA) > 3000)
 				{
@@ -194,7 +194,7 @@ void MC_Fault_PhaseLine_Process(FlagStatus Foc_Flag, uint16_t BusCurrent, uint16
 			  TrigTimeCnt_PhaseA = HAL_GetTick();
 			}
 			//B相电流
-			if(abs(Phase_Current.uw_phase_b) < 500)
+			if(abs(Phase_Current.uw_phase_b) < 300)
 			{
 			  if((HAL_GetTick() - TrigTimeCnt_PhaseB) > 3000)
 				{
@@ -216,7 +216,7 @@ void MC_Fault_PhaseLine_Process(FlagStatus Foc_Flag, uint16_t BusCurrent, uint16
 			  TrigTimeCnt_PhaseB = HAL_GetTick();
 			}
 			//C相电流
-			if(abs(Phase_Current.uw_phase_c) < 500)
+			if(abs(Phase_Current.uw_phase_c) < 300)
 			{
 			  if((HAL_GetTick() - TrigTimeCnt_PhaseC) > 3000)
 				{
@@ -987,7 +987,7 @@ void MC_Fault_CadenceSensor_Process(uint16_t Torque, uint16_t BikeSpeed, MC_Erro
 void MC_Fault_Check_Process(void)
 {	
 	//速度传感器故障检测
-	if((MC_WorkMode == MC_WorkMode_Run) && (MC_ConfigParam1.No_SpeedSensor_Flag != MC_SUPPORT_ENABLE))
+	if((MC_WorkMode == MC_WorkMode_Run) && (MC_ConfigParam1.SpeedSignal == MC_SPEED_WHEEL_TRIG))
 	{
 		MC_Fault_SpeedSensor_Process(MC_SpeedSensorData.IsStopFlag, MC_CadenceResult, MC_RunInfo.MotorSpeed, MC_CalParam.AssistRunMode, &MC_ErrorCode);
 	}

+ 110 - 48
User/Src/motor_control.c

@@ -247,29 +247,27 @@ MC_CalParam_Struct_t MC_AssistRunMode_Gas_Process(uint16_t SensorData, MC_GearSt
 
 	/*车轮速度使用原始数据,滤波后的数据有滞后,影响控制回路*/
 	wheelSpeed = (int16_t)MC_SpeedSensorData.Speed_Data;
+	
 	/*实时计算电机转速与车轮速的比值*/
 	SpdMotorDivWheel = 	(uint32_t)(MC_RunInfo.MotorSpeed * 100) / wheelSpeed ;
-	
 	Tmp = SpdMotorDivWheel;
-	SpdMotorDivWheelFlt += ((Tmp<<8) - SpdMotorDivWheelFlt) >> 6;
-	SpdMotorDivWheelFlted = SpdMotorDivWheelFlt>>8;
-	
+	SpdMotorDivWheelFlt += ((Tmp << 8) - SpdMotorDivWheelFlt) >> 6;
+	SpdMotorDivWheelFlted = SpdMotorDivWheelFlt >> 8;
 	
 	/*在电机转速与车轮速比值,与实际速比一致时,更新速比*/
-	if( ( MC_RunInfo.MotorSpeed > 100 ) && ( wheelSpeed > 0 ))
+	if(( MC_RunInfo.MotorSpeed > 100 ) && ( wheelSpeed > 0 ))
 	{
 		/*加速时,更新速比,比较法*/
 		if((wheelSpeed - wheelSpeedPre ) > 5)
 		{
-			if(( MC_RunInfo.MotorSpeed - DbSpdMotorPre )>0)
+			if(( MC_RunInfo.MotorSpeed - DbSpdMotorPre ) > 0)
 			{
 				SpdProportion = SpdMotorDivWheel ;
 			}
 			DbSpdMotorPre = MC_RunInfo.MotorSpeed;
 		}
 		wheelSpeedPre = wheelSpeed;
-		
-		
+			
 		/*求标准差,速比稳定后,更新速比*/
 		/*此处将数据保存到数组中,标准差计算,时间较长,放在主循环进行*/
 		if((SpdProportion_CAL_flag==0) && (MC_CalParam.Ref_Speed > 25))  //电机力矩控制量低于25时,认为是空载,此时不更新速比
@@ -292,24 +290,25 @@ MC_CalParam_Struct_t MC_AssistRunMode_Gas_Process(uint16_t SensorData, MC_GearSt
 			}
 		}
 	}
+	else
+	{
+	  wheelSpeedPre = wheelSpeed;
+		DbSpdMotorPre = MC_RunInfo.MotorSpeed;
+	}
 
 	/*电机最高速度,上位机配置参数*/
 	SpeedMax = MC_MotorParam.Rate_Speed;
 	Tmp = SensorData + 50 ;  //加50偏移量,确保能达到最大值2048
 	Tmp = Tmp > 2048 ? 2048 : Tmp; 
 	
-//			/*调试用,根据车速限速值,换算指拨对应的设定车速*/
-		  dbSpdWheelSet = (Tmp * MC_ConfigParam1.SpeedLimit * 10 )>> 11;	
-	//if(((int16_t)wheelSpeed - (int16_t)dbSpdWheelSet) < 100 )
-		//|| (dbSpdWheelSet < 50  )  )
-//			{
-	
+	/*调试用,根据车速限速值,换算指拨对应的设定车速*/
+	dbSpdWheelSet = (Tmp * MC_ConfigParam1.SpeedLimit * 10 )>> 11;	
+
 	/*电机转速设定,根据指拨大小、车轮限速值和速比,换算*/
 	SpeedSet = ((Tmp * MC_ConfigParam1.SpeedLimit  * SpdProportion) / 10  >> 11);			//(Tmp >> 11) * cd_Speedlimit * ( SpdProportion / 10)
-	//SpeedSet = ((Tmp * cd_MotorSpeed)  >> 11);	//调试
 	
 	//超过限速值,设定电机转速为0
-	if(wheelSpeed > (MC_ConfigParam1.SpeedLimit * 10 + 10))
+	if(wheelSpeed > (MC_ConfigParam1.SpeedLimit * 10 + 20))
 	{
 		SpeedSet = 0;
 	}
@@ -317,29 +316,29 @@ MC_CalParam_Struct_t MC_AssistRunMode_Gas_Process(uint16_t SensorData, MC_GearSt
 	SpeedSet = (SpeedSet > 0) ? SpeedSet : 0;
 	SpeedSet = (SpeedSet < SpeedMax) ? SpeedSet : SpeedMax;
 	
-	
-	switch (GearSt & 0x0F)//Help_mode:bit4: 0-力矩模式,1-踏频模式;低四位表示助力档位
+	//根据档位调整加速度
+	switch (GearSt & 0x0F)
 	{
 		case 0x01:
-			accStep = StepCalc(SpeedMax,1,6500);
+			accStep = StepCalc(SpeedMax, 1, 6500);
 			break;
 		case 0x02:
-			accStep = StepCalc(SpeedMax,1,6000);
+			accStep = StepCalc(SpeedMax, 1, 6000);
 			break;
 		case 0x03:
-			accStep = StepCalc(SpeedMax,1,5500);
+			accStep = StepCalc(SpeedMax, 1, 5500);
 			break;
 		case 0x04:
-			accStep = StepCalc(SpeedMax,1,5000);
+			accStep = StepCalc(SpeedMax, 1, 5000);
 			break;
 		default:
 			/*计算周期1ms, 加减速时间为 5.00s  加减速步进计算*/
-			accStep = StepCalc(SpeedMax,1,5000);
+			accStep = StepCalc(SpeedMax, 1, 5000);
 			break;
 	}
 	
 	/*减速步进*/
-	decStep = StepCalc(SpeedMax,1,1000);
+	decStep = StepCalc(SpeedMax, 1, 1000);
 
 	/* 跟踪启动 */
 	if(MC_CalParam.Foc_Flag  == RESET)			
@@ -353,24 +352,85 @@ MC_CalParam_Struct_t MC_AssistRunMode_Gas_Process(uint16_t SensorData, MC_GearSt
 	}
 		
 	/*速度指令的加减速处理*/
-	SpeedSetReal = accDecProcess(SpeedSet,accStep,decStep,&SpeedSetMiddle);  
+	#if 1  //根据档位设定最高速度
+	
+	switch(GearSt & 0x0F)
+	{
+	  case 0x01:
+			SpeedSetReal = accDecProcess((SpeedSet * 9) >> 4, accStep, decStep, &SpeedSetMiddle);  
+			break;
+		case 0x02:
+			SpeedSetReal = accDecProcess((SpeedSet * 11) >> 4, accStep, decStep, &SpeedSetMiddle);  
+			break;
+		case 0x03:
+			SpeedSetReal = accDecProcess((SpeedSet * 13) >> 4, accStep, decStep, &SpeedSetMiddle);  
+			break;
+		case 0x04:
+			SpeedSetReal = accDecProcess(SpeedSet, accStep, decStep, &SpeedSetMiddle);  
+			break;
+		default:
+			SpeedSetReal = accDecProcess(SpeedSet, accStep, decStep, &SpeedSetMiddle);  
+			break;
+	}
+	
+	#else
+	
+	SpeedSetReal = accDecProcess(SpeedSet, accStep, decStep, &SpeedSetMiddle);  
+	
+	#endif
 
-	/*母线电流限流*/
-	PID_IMax.hLower_Limit_Output= -(MC_AssisParam.Gear_TURBO.Upper_Iq / 2);   //Lower Limit for Output limitation
-	PID_IMax.hUpper_Limit_Output= 0;   //Upper Limit for Output limitation
-	PID_IMax.wLower_Limit_Integral = -((MC_AssisParam.Gear_TURBO.Upper_Iq / 2) << 10); // 放大1024
-	PID_IMax.wUpper_Limit_Integral = 0; // 放大1024
-	SpdMotorByIdc = PID_Regulator((MC_ConfigParam1.CurrentLimit * 1000) >> 7, MC_RunInfo.BusCurrent >> 7, &PID_ConstantPower); // 母线电流闭环
+	/*限制母线电流*/
+	#if 0 //根据档位设定最大电流,电流环在内环,不稳定
+	
+	static uint16_t CurrentLimitPresent;     //限流实际值,做升降速处理
+	uint16_t CurrentLimitSet;                //限流设置值,不同助力档位更新
+
+	switch(GearSt & 0x0F)
+	{
+	  case 0x01://ECO
+		{
+		  CurrentLimitSet = (uint32_t)(MC_AssisParam.Gear_ECO.CurrentMax_K * MC_ConfigParam1.CurrentLimit * 1000 >> 17);
+			CurrentLimitPresent = MC_DataSet_Linear_Process(CurrentLimitSet, CurrentLimitPresent, 5 ,1);
+			break;
+		}
+		case 0x02://NORM
+		{
+		  CurrentLimitSet = (uint32_t)(MC_AssisParam.Gear_NORM.CurrentMax_K * MC_ConfigParam1.CurrentLimit * 1000 >> 17);
+			CurrentLimitPresent = MC_DataSet_Linear_Process(CurrentLimitSet, CurrentLimitPresent, 5 ,1);
+			break;
+		}
+		case 0x03://SPORT
+		{
+		  CurrentLimitSet = (uint32_t)(MC_AssisParam.Gear_SPORT.CurrentMax_K * MC_ConfigParam1.CurrentLimit * 1000 >> 17);
+			CurrentLimitPresent = MC_DataSet_Linear_Process(CurrentLimitSet, CurrentLimitPresent, 5 ,1);
+			break;
+		}
+		case 0x04://TURBO			
+		{
+		  CurrentLimitSet = (uint32_t)(MC_AssisParam.Gear_TURBO.CurrentMax_K * MC_ConfigParam1.CurrentLimit * 1000 >> 17);
+			CurrentLimitPresent = MC_DataSet_Linear_Process(CurrentLimitSet, CurrentLimitPresent, 5 ,1);
+			break;
+		}
+		default://SMART
+		{
+		  CurrentLimitSet = (uint32_t)(MC_AssisParam.Gear_SMART.CurrentMax_K * MC_ConfigParam1.CurrentLimit * 1000 >> 17);
+			CurrentLimitPresent = MC_DataSet_Linear_Process(CurrentLimitSet, CurrentLimitPresent, 5 ,1);
+			break;
+		}
+	}
+	SpdMotorByIdc = PID_Regulator(CurrentLimitPresent, MC_RunInfo.BusCurrent >> 7, &PID_ConstantPower);
+	
+	#else
+	
+	SpdMotorByIdc = PID_Regulator((MC_ConfigParam1.CurrentLimit * 1000) >> 7, MC_RunInfo.BusCurrent >> 7, &PID_ConstantPower);
+	
+	#endif
 	
 	/* 电机速度闭环 */
-	/*最大力矩为4档的力矩参数*/
+	//最大力矩为4档的力矩参数
 	PID_MotorSpd.hLower_Limit_Output= -(MC_AssisParam.Gear_TURBO.Upper_Iq / 2);
 	PID_MotorSpd.hUpper_Limit_Output= (MC_AssisParam.Gear_TURBO.Upper_Iq / 2);
-//			PID_MotorSpd.wLower_Limit_Integral = -((ContrlParam.Gear_4st.Upper_Iq / 2) << 10); // 放大1024
-//			PID_MotorSpd.wUpper_Limit_Integral = ((ContrlParam.Gear_4st.Upper_Iq / 2) << 10); // 放大1024
-	TorQueBySpd = PID_Regulator(SpeedSetReal,	\
-															MC_RunInfo.MotorSpeed ,   \
-															&PID_MotorSpd); // 电机速度闭环输出
+	TorQueBySpd = PID_Regulator(SpeedSetReal, MC_RunInfo.MotorSpeed, &PID_MotorSpd);
 
 	TorQueBySpd += SpdMotorByIdc;
 	
@@ -394,6 +454,7 @@ MC_CalParam_Struct_t MC_AssistRunMode_Gas_Process(uint16_t SensorData, MC_GearSt
 	
 	uint16_t K_ByVoltage_Result = 1024;
 	uint16_t K_ByTemperature_Result = 1024;
+	
 	#endif
 	
 	//速度环控制量为0时停机,防止电机出现异响
@@ -409,7 +470,7 @@ MC_CalParam_Struct_t MC_AssistRunMode_Gas_Process(uint16_t SensorData, MC_GearSt
 	
 	Ref_Speed_Temp = ((int32_t)TorQueBySpd * K_ByVoltage_Result) >> 10;
 	Ref_Speed_Temp = ((int32_t)Ref_Speed_Temp * K_ByTemperature_Result) >> 10;
-	
+
 	p_MC_CalParam.Ref_Speed = (int16_t)(Ref_Speed_Temp);
 	p_MC_CalParam.Foc_Flag = SET;
 	p_MC_CalParam.AssistRunMode = MC_AssistRunMode_GAS;
@@ -1132,15 +1193,16 @@ MC_CalParam_Struct_t MC_AssistRunMode_Torque_compensation(uint16_t SenorData, MC
   }
   else
   {
-    if(MC_RunInfo.MotorSpeed > 200)
-    {
-			TorqueStopDelayTime = 163800 / MC_RunInfo.MotorSpeed;
-    }
-    else
-    {
-      TorqueStopDelayTime = 1200;
-    }
-    
+		if(MC_RunInfo.MotorSpeed > 200)
+		{
+		  TorqueStopDelayTime = 218400 / MC_RunInfo.MotorSpeed; //60s / (电机转速 / 4.55 / 2.4) / 3,曲柄1/3圈
+		}
+		else
+		{
+		  TorqueStopDelayTime = 1200;
+		}
+		TorqueStopDelayTime= (TorqueStopDelayTime < 500) ? 500 : TorqueStopDelayTime;
+		
     if((HAL_GetTick() - TorqueStopDelayTimeCnt) > TorqueStopDelayTime)//超时1200ms
     {
       MC_TorqueProcess_Param.MotorStopLock_Flag = SET;
@@ -1822,7 +1884,7 @@ void SpdProportion_calculate(void)
 		test_StandardDeviation = (int32_t)(SpdProportion_StandardDeviation );
 		SpdProportion_CAL_flag = 0;
 		/*更新速比*/
-		if(test_StandardDeviation < 20)
+		if(test_StandardDeviation < 30)
 		{
 			SpdProportion = test_SpdProportionAver;
 		}

+ 58 - 2
User/Src/speed_sensor.c

@@ -81,7 +81,7 @@ void SpeedSensor_Process(MC_SpeedSensorData_Struct_t* p_MC_SpeedSensorData, uint
 	}
 }
 
-void SpeedCal_ByCadence(uint16_t CadenceData, uint8_t T_Front, uint8_t T_Tail, uint16_t WheelSize, uint16_t* BikeSpeed)
+void SpeedCal_ByCadence(uint16_t CadenceData, uint16_t* SpeedData, uint8_t T_Front, uint8_t T_Tail, uint16_t WheelSize, uint16_t* BikeSpeed)
 {
   static uint32_t PeriodTimeCnt = 0;
 	static uint8_t FltCount = 0;
@@ -90,7 +90,8 @@ void SpeedCal_ByCadence(uint16_t CadenceData, uint8_t T_Front, uint8_t T_Tail, u
 	if((HAL_GetTick() - PeriodTimeCnt) >= 50)
 	{
 	  PeriodTimeCnt = HAL_GetTick();
-		FltSum += ((CadenceData * T_Front / T_Tail * WheelSize * 144) / 10000);//车速 = 踏频 * 2.4 * 前飞齿数 / 后飞齿数 * 60 / 1000 km/h,结果单位0.1km/h
+		*SpeedData = ((CadenceData * T_Front / T_Tail * WheelSize * 144) / 10000);//车速 = 踏频 * 2.4 * 前飞齿数 / 后飞齿数 * 60 / 1000 km/h,结果单位0.1km/h
+		FltSum += *SpeedData;
 		FltCount++;
 		if(FltCount >= 8)
 		{
@@ -100,3 +101,58 @@ void SpeedCal_ByCadence(uint16_t CadenceData, uint8_t T_Front, uint8_t T_Tail, u
 		}	
 	}
 }
+
+void SpeedCal_ByCommunication(MC_SpeedSensorData_Struct_t* p_MC_SpeedSensorData, uint16_t* AvgResult, uint8_t WheelSize)
+{
+  //车速计算
+	static uint32_t PeriodTimeCnt = 0;
+	static uint16_t FiltTemp[10];
+	
+	if((HAL_GetTick() - PeriodTimeCnt) >= 50)
+	{
+		//超时清零
+		static uint32_t ClearDelayTimeCnt = 0;
+		
+		if(p_MC_SpeedSensorData->IsTrigFlag == TRUE)
+		{
+			ClearDelayTimeCnt = HAL_GetTick();
+			p_MC_SpeedSensorData->IsTrigFlag = FALSE;
+		}
+		if((HAL_GetTick() - ClearDelayTimeCnt) > 4000) // 超时信号触发标志未更新,认为停车
+		{
+			p_MC_SpeedSensorData->IsStopFlag = TRUE;
+			p_MC_SpeedSensorData->DiffTime_ms = 0xFFFF;
+		}
+	  
+		//停止判断
+		if((p_MC_SpeedSensorData->DiffTime_ms & 0xFFFF) == 0xFFFF)
+		{
+		  p_MC_SpeedSensorData->IsStopFlag = TRUE;
+		}
+		else
+		{
+			p_MC_SpeedSensorData->IsStopFlag = FALSE;
+		}
+		
+		//车速计算
+		if(p_MC_SpeedSensorData->IsStopFlag == FALSE)
+		{
+		  if(p_MC_SpeedSensorData->DiffTime_ms == 0)
+			{
+				p_MC_SpeedSensorData->DiffTime_ms = 0xFFFFFFFF;
+			}
+			p_MC_SpeedSensorData->Speed_Data = (uint32_t)WheelSize * 360 / p_MC_SpeedSensorData->DiffTime_ms;//单位0.1km/h
+			
+			//滑动均值滤波
+			*AvgResult = MovingAverageFilter(p_MC_SpeedSensorData->Speed_Data, FiltTemp, sizeof(FiltTemp) >> 1);
+		}
+		else
+		{
+		  p_MC_SpeedSensorData->Speed_Data = 0;
+			*AvgResult = 0;
+			return;
+		}
+		
+		PeriodTimeCnt = HAL_GetTick();
+	}
+}

+ 23 - 14
User/Src/tasks.c

@@ -160,25 +160,34 @@ void MC_RunInfo_Update(void)
 		MC_RunInfo.RemainDistance = (DeviceOnLine_Status.Status_Bit.BMS_OffLine == 1) ? 0xEEEE : RemainDis.remainDistance;
 		
 		//骑行总里程计算
-		static uint32_t WheelTurnCount  = 0;
+		static uint32_t WheelTurnCount = 0;
     static FlagStatus RefreshFlag = RESET;
-		if(MC_ConfigParam1.No_SpeedSensor_Flag != MC_SUPPORT_ENABLE) //不支持无速度传感器
+		
+		if(MC_ConfigParam1.SpeedSignal == MC_SPEED_COMMUNICATION) //根据通信获取的车轮旋转周期计算
 		{
-			if((MC_SpeedSensorData.WheelTurnCount - WheelTurnCount) >= (10000 / (MC_ConfigParam1.WheelSize + MC_ConfigParam1.WheelSizeAdj))) //0.1km车轮所需圈数
-			{	 
-				RefreshFlag = SET;
-				WheelTurnCount = MC_SpeedSensorData.WheelTurnCount;
+		  static uint32_t WheelTurnCount_Temp = 0;
+			//运算周期是200ms,根据车轮旋转周期计算200ms内旋转的圈数,存在小数,放大100倍
+			if(MC_SpeedSensorData.IsStopFlag == FALSE)
+			{
+				WheelTurnCount_Temp += 20000 / MC_SpeedSensorData.DiffTime_ms;
+				MC_SpeedSensorData.WheelTurnCount = WheelTurnCount_Temp / 100;			
 			}
 		}
-		else //支持无速度传感器
+		else if(MC_ConfigParam1.SpeedSignal == MC_SPEED_CADENCE_CAL) //根据踏频计算
 		{
-	  	//车轮转过的圈数 = 踏频信号个数 / 120 * 2.4 * 前飞齿数 / 后飞齿数
-			if(((MC_CadenceResult.TrigCount - WheelTurnCount) * MC_ConfigParam1.TeethNum_F / MC_ConfigParam1.TeethNum_B / 50) >= (10000 / (MC_ConfigParam1.WheelSize + MC_ConfigParam1.WheelSizeAdj))) //0.1km车轮所需圈数
-			{	  
-				RefreshFlag = SET;
-				WheelTurnCount = MC_CadenceResult.TrigCount;
-			}
+		  //车轮转过的圈数 = 踏频信号个数 / 120 * 2.4 * 前飞齿数 / 后飞齿数
+			MC_SpeedSensorData.WheelTurnCount = MC_CadenceResult.TrigCount * MC_ConfigParam1.TeethNum_F / MC_ConfigParam1.TeethNum_B / 50;
+		}
+		else
+		{
+	  	//车轮转过的圈数在速度传感器中断已处理
 		}
+		if((MC_SpeedSensorData.WheelTurnCount - WheelTurnCount) >= (10000 / (MC_ConfigParam1.WheelSize + MC_ConfigParam1.WheelSizeAdj))) //0.1km车轮所需圈数
+		{	 
+			RefreshFlag = SET;
+			WheelTurnCount = MC_SpeedSensorData.WheelTurnCount;
+		}
+		
    if(RefreshFlag == SET)
    {
 			RefreshFlag = RESET;
@@ -554,7 +563,7 @@ void MC_CanRxCheck_Process(MC_SupportFlag_Struct_t NoPBU_Flag, MC_SupportFlag_St
 		//PBU通信状态检测
 		if(IsComOK_PBU.IsOK_Flag == TRUE)
 		{
-			if((HAL_GetTick() - IsComOK_PBU.OK_TrigTime) > 1000)  
+			if((HAL_GetTick() - IsComOK_PBU.OK_TrigTime) > 30000)  //防止中控异常重启,重启过程持续10+s  
 			{  
 				IsComOK_PBU.IsOK_Flag = FALSE;
 				*GearSt = MC_GearSt_OFF;

+ 3 - 3
User/Src/var.c

@@ -77,7 +77,7 @@ const MC_ConfigParam1_Struct_t MC_ConfigParam1_Default =
   {100,100},                                       //SMART
 	(uint8_t)1,                                      //速度传感器极数
 	(uint8_t)2,                                      //踏频启动信号个数
-	(MC_SupportFlag_Struct_t)MC_SUPPORT_DISABLE,     //无速度传感器支持,0x55-不支持,0x-AA支持	
+	(MC_SpeedSignal_Struct_t)MC_SPEED_WHEEL_TRIG,    //速度信号来源,0x55-车轮触发,0x-AA踏频估算,0x-EE通信获取车轮旋转周期	
 	(int8_t)0                                        //轮胎周长微调值                                        
 };
 
@@ -485,7 +485,7 @@ void Var_Init(void)
 		
 	//MC版本信息初始化,Mode和SN从EEPROM读取
   strncpy(MC_VerInfo.HW_Version, (char*)"QD007E.         ", 16);
-	strncpy(MC_VerInfo.FW_Version, (char*)"V5r0r2_20200426.", 16);
+	strncpy(MC_VerInfo.FW_Version, (char*)"V5r1r0_20200615.", 16);
 		
 	//电机型号
 	strncpy(MC_VerInfo.Mode, (char*)"VR7500K01.      ", 16);
@@ -496,7 +496,7 @@ void Var_Init(void)
 	//生产信息
 	strncpy(MC_MacInfo.Manufacturer, (char*)"TTIUM.  ", 8);  //生产信息
 	strncpy(MC_MacInfo.MacAddr, (char*)"WUHAN.  ", 8);
-	strncpy(MC_MacInfo.MacDate, (char*)"20191101", 8);
+	strncpy(MC_MacInfo.MacDate, (char*)"20200101", 8);
 		
 	//MCU ID读取
 	memcpy((uint8_t*)MC_CheckInfo.MAC_ID, (uint8_t*)(0x1FFFF7E8), 12);

+ 14 - 2
修改说明.txt

@@ -262,8 +262,20 @@ V5.0.2_20200426
 1、修改CAN错误中断回调处理,解决接入世豹电池当电池关闭CAN时无法接收数据;
 2、版本号:V5.0.2_20200426
 
-
-
+V5.1.0_20200615
+1、调整3相电流有效值测量的函数;
+2、无速度传感器时对车速的计算,改为结合踏频和电机转速同时判断,取大值,并且将车速更新到MC_SpeedSensorData.Speed_Data,解决指拨模式下无法限速;
+3、缺相检测的阈值,由500调整为300;
+4、指拨模式处理,解决滑行开机时第一次进入指拨模式将速比更新为较小值的问题;
+5、指拨模式限速最大值调整为+20;
+6、加入指拨模式四个档位的区别,主要是最高速;
+7、指拨模式限流调整为采用PID_ConstantPower;
+8、调整低力矩停机的延时,由1/4圈调整为1/3圈;
+9、更改用户参数1中速度传感器配置,由是否支持无速度传感器改为速度信号来源,设置有三种,车轮信号、踏频、通信;
+10、增加速度信号来自通信时的车速、里程、续航计算;
+11、0x3708指令中,增加更新通信的轮速信号;
+12、对ECU的通信超时判断由1s改为30s;
+13、版本号:V5.1.0_20200615