#include "Data_VSpeed\Data_VSpeed.h" #include "Application.h" static uint16_t DataVSpeedActual; static uint16_t DataVSpeedDisp; static uint16_t DataVSpeedHysteresis; static uint8_t DataVSpeedValid; // static uint16_t DataVSpeedDisp_Mile; static DataVSpeedSamplerStruct DataVSpeedSampler; static DataVSPeedDampingStruct DataVSPeedDamping; #define DATA_APPR_DIR_INC 0x01 #define DATA_APPR_DIR_DEC 0x02 /****************************************************************************** 函数名:Data_Vehicle_Speed_KL30_Init 功 能:车速数据KL30初始化 参 数:无 返回值:无 ****************************************************************************** 注 意:该函数KL30初始化被调用一次 ******************************************************************************/ void Data_Vehicle_Speed_KL30_Init(void) { DataVSpeedActual = 0; DataVSpeedDisp = 0; DataVSpeedHysteresis = 0; DataVSpeedValid = 1; DataVSpeedSampler.Cnt = 0; DataVSPeedDamping.Speed = 0; DataVSPeedDamping.Delta = 0; DataVSPeedDamping.Dir = DATA_APPR_DIR_INC; DataVSpeedSampler.Timer1 = 0; DataVSpeedSampler.Timer = 0; } /****************************************************************************** 函数名:Data_Vehicle_Speed_Wakeup_Init 功 能:车速数据唤醒初始化 参 数:无 返回值:无 ****************************************************************************** 注 意:该函数唤醒初始化被调用一次 ******************************************************************************/ void Data_Vehicle_Speed_Wakeup_Init(void) { DataVSpeedDisp = 0; DataVSpeedHysteresis = 0; DataVSPeedDamping.Speed = 0; DataVSPeedDamping.Delta = 0; DataVSPeedDamping.Dir = DATA_APPR_DIR_INC; DataVSpeedSampler.Timer1 = 0; DataVSpeedSampler.Timer = 0; } /****************************************************************************** 函数名:Data_Vehicle_Speed_Processing_Service 功 能:车速数据处理函数 参 数:无 返回值:无 ****************************************************************************** 注 意:该函数必须每20ms被调用一次 ******************************************************************************/ void Data_Vehicle_Speed_Processing_Service(void) { uint8_t i; uint16_t Delta; uint32_t VSpeed; uint32_t VSpeedCal; uint8_t ESC_VehicleSpeedState; uint32_t Vehicle_Speed; Vehicle_Speed = Get_CAN_CH0_ID_101_Sig_ECU_Vehicle_Speed( ); ESC_VehicleSpeedState = Get_CAN_CH0_ID_101_Sig_ECU_Vehicle_Speed_State( ); // 第1步:获取实际车速值及车速有效性 if( Common_Get_IG_Sts( ) == COMMON_POWER_ON ) { if (CAN_MSG_Status(&CAN_CH0_CanMsgOp, CAN_CH0_ID_CAN_0x101_Msg_Count) == CAN_SIG_LOST) { DataVSpeedValid = 0; DataVSpeedActual = 0; DataVSpeedSampler.Backup = 0; } else { if (ESC_VehicleSpeedState == 1) { DataVSpeedValid = 0; DataVSpeedActual = 0; DataVSpeedSampler.Backup = 0; } else { if ( DataVSpeedValid == 0 ) { DataVSpeedValid = 1; VSpeed = Vehicle_Speed; DataVSpeedActual = VSpeed * 10; } else { DataVSpeedSampler.Buffer [ DataVSpeedSampler.Cnt ] = Vehicle_Speed; i = DataVSpeedSampler.Cnt; while ( (i > 0) && (DataVSpeedSampler.Buffer [ i ] < DataVSpeedSampler.Buffer [ i - 1 ]) ) { VSpeed = DataVSpeedSampler.Buffer [ i ]; DataVSpeedSampler.Buffer [ i ] = DataVSpeedSampler.Buffer [ i - 1 ]; DataVSpeedSampler.Buffer [ i - 1 ] = VSpeed; i--; } DataVSpeedSampler.Cnt++; if ( DataVSpeedSampler.Cnt >= 3 ) { DataVSpeedSampler.Cnt = 0; VSpeed = DataVSpeedSampler.Buffer [ 1 ]; DataVSpeedActual = VSpeed * 10; } DataVSpeedSampler.Timer = 0; DataVSpeedSampler.Timer1 = 0; DataVSpeedSampler.Backup = DataVSpeedActual; DataVSpeedValid = 1; } } } } else { DataVSpeedValid = 0; DataVSpeedActual = 0; DataVSpeedSampler.Timer = 0; DataVSpeedSampler.Timer1 = 0; DataVSpeedSampler.Cnt = 0; DataVSpeedSampler.Backup = 0; } // 第2步:车速的阻尼处理 VSpeed = DataVSpeedActual; if ( VSpeed > DataVSPeedDamping.Speed ) // 实际值比当前显示值大时 { Delta = ( uint16_t )VSpeed - DataVSPeedDamping.Speed; if ( DataVSPeedDamping.Dir == DATA_APPR_DIR_INC ) // 显示值正在向实际值增加,则维持当前方向调节增加速度 { if ( DataVSPeedDamping.Delta < Delta ) // 当前增量小于显示值与实际值的差值,则提升增加的速度 { DataVSPeedDamping.Delta += DATA_VSPEED_INC_STEP; if ( DataVSPeedDamping.Delta > Delta ) DataVSPeedDamping.Delta = Delta; } else // 当前增量大于等于显示值与实际值的差值,保持增量与当前差值同步,增加的速度即逐步减小 DataVSPeedDamping.Delta = Delta; Delta = DataVSPeedDamping.Delta; Delta /= DATA_VSPEED_DAMPING_FACTOR; if ( Delta < DATA_VSPEED_APPR_SPEED_MIN ) Delta = DATA_VSPEED_APPR_SPEED_MIN; DataVSPeedDamping.Speed += Delta; if ( DataVSPeedDamping.Speed > VSpeed ) DataVSPeedDamping.Speed = ( uint16_t )VSpeed; } else // 显示值正在减小,则尽快减速至速度为最小时更换方向 { if ( DataVSPeedDamping.Delta > DATA_VSPEED_DEC_STEP ) DataVSPeedDamping.Delta -= DATA_VSPEED_DEC_STEP; else DataVSPeedDamping.Delta = 0; Delta = DataVSPeedDamping.Delta; Delta /= DATA_VSPEED_DAMPING_FACTOR; if ( Delta < DATA_VSPEED_APPR_SPEED_MIN ) // 已减速至最小速度 DataVSPeedDamping.Dir = DATA_APPR_DIR_INC; // 更换方向 else { if ( DataVSPeedDamping.Speed > Delta ) DataVSPeedDamping.Speed -= Delta; else DataVSPeedDamping.Speed = 0; } } } else if ( VSpeed < DataVSPeedDamping.Speed ) // 实际值比当前显示值小时 { Delta = DataVSPeedDamping.Speed - ( uint16_t )VSpeed; if ( DataVSPeedDamping.Dir == DATA_APPR_DIR_INC ) // 显示值仍在增加,则尽快减速至速度为最小时更换方向 { if ( DataVSPeedDamping.Delta > DATA_VSPEED_DEC_STEP ) DataVSPeedDamping.Delta -= DATA_VSPEED_DEC_STEP; else DataVSPeedDamping.Delta = 0; Delta = DataVSPeedDamping.Delta; Delta /= DATA_VSPEED_DAMPING_FACTOR; if ( Delta < DATA_VSPEED_APPR_SPEED_MIN ) // 已减速至最小速度 DataVSPeedDamping.Dir = DATA_APPR_DIR_DEC; // 更换方向 else { DataVSPeedDamping.Speed += Delta; if ( DataVSPeedDamping.Speed > 1990 ) DataVSPeedDamping.Speed = 1990; } } else // 显示值正在向实际值减小,则维持当前方向调节增加速度 { if ( DataVSPeedDamping.Delta < Delta ) // 当前(负)增量小于显示值与实际值的差值,则提升减小的速度 { DataVSPeedDamping.Delta += DATA_VSPEED_INC_STEP; if ( DataVSPeedDamping.Delta > Delta ) DataVSPeedDamping.Delta = Delta; } else // 当前(负)增量大于等于显示值与实际值的差值,保持(负)增量与当前差值同步,减小的速度即逐步减小 DataVSPeedDamping.Delta = Delta; Delta = DataVSPeedDamping.Delta; Delta /= DATA_VSPEED_DAMPING_FACTOR; if ( Delta < DATA_VSPEED_APPR_SPEED_MIN ) Delta = DATA_VSPEED_APPR_SPEED_MIN; if ( DataVSPeedDamping.Speed < VSpeed + Delta ) DataVSPeedDamping.Speed = ( uint16_t )VSpeed; else DataVSPeedDamping.Speed -= Delta; } } else // 实际值与当前显示值相等时 { Delta = DataVSPeedDamping.Delta; Delta /= DATA_VSPEED_DAMPING_FACTOR; if ( Delta > DATA_VSPEED_APPR_SPEED_MIN ) // 当前的速度不是最小,说明数值正在增加/减小中,则继续原过程 { if ( DataVSPeedDamping.Delta > DATA_VSPEED_DEC_STEP ) // 显示值越过了实际值,必然要先减速至最小速度,再改变方向返回实际值 DataVSPeedDamping.Delta -= DATA_VSPEED_DEC_STEP; else DataVSPeedDamping.Delta = 0; Delta = DataVSPeedDamping.Delta; Delta /= DATA_VSPEED_DAMPING_FACTOR; if ( DataVSPeedDamping.Dir == DATA_APPR_DIR_INC ) // 显示值当前是增加方向 { if ( Delta < DATA_VSPEED_APPR_SPEED_MIN ) // 已减速至最小速度 DataVSPeedDamping.Dir = DATA_APPR_DIR_DEC; // 更换方向 else { DataVSPeedDamping.Speed += Delta; if ( DataVSPeedDamping.Speed > 1990 ) DataVSPeedDamping.Speed = 1990; } } else // 显示值当前是减小方向 { if ( Delta < DATA_VSPEED_APPR_SPEED_MIN ) // 已减速至最小速度 DataVSPeedDamping.Dir = DATA_APPR_DIR_INC; // 更换方向 else { if ( DataVSPeedDamping.Speed > Delta ) DataVSPeedDamping.Speed -= Delta; else DataVSPeedDamping.Speed = 0; } } } } // 第3步:生成显示车速 if ( (DataVSPeedDamping.Speed >= DataVSpeedHysteresis) || (DataVSPeedDamping.Speed < DATA_VSPEED_HYSTERESIS) ) { DataVSpeedHysteresis = DataVSPeedDamping.Speed; } else { if ( DataVSpeedHysteresis - DataVSPeedDamping.Speed >= DATA_VSPEED_HYSTERESIS ) { DataVSpeedHysteresis = DataVSPeedDamping.Speed; } } VSpeedCal = ( uint32_t )DataVSpeedHysteresis; if ( DataVSpeedValid ) { VSpeedCal *= 107; VSpeedCal /= 100; VSpeedCal = VSpeedCal + 10; if(VSpeedCal > 1990) { VSpeedCal = 1990; } DataVSpeedDisp = ( uint16_t )VSpeedCal; } else { DataVSpeedDisp = 0; } } /*车速有效位:有效=1,无效=0*/ uint8_t Get_VechileSpeedValid(void) { return DataVSpeedValid; } /*真实的车速,精度10倍,*/ uint16_t Get_ActualVechileSpeed(void) { return DataVSpeedActual; } /*显示车速,精度10倍,取整,舍去小数点*/ uint16_t Get_DispVechileSpeed(void) { uint16_t Vspeed = 0; if(Get_Dis_KM_Unit() == 0) /* KM */ { if ( DataVSpeedDisp >= 1990 ) { DataVSpeedDisp = 1990; } Vspeed = DataVSpeedDisp; } else /* MILE */ { Vspeed = Data_Km_To_Mile(DataVSpeedDisp); if ( Vspeed >= 1230 ) { Vspeed = 1230; } } return Vspeed; } /*外发显示车速,精度10倍,取整,舍去小数点*/ uint16_t Get_DispVechileSpeed_TX(void) { uint16_t Vspeed = 0; if ( DataVSpeedDisp >= 1990 ) { DataVSpeedDisp = 1990; } Vspeed = DataVSpeedDisp; return Vspeed; }