#include "Data_VSpeed.h" #include "Components.h" #include "CAN_CH0_CAN_Communication_Matrix.h" uint16_t DataVSpeedActual; uint16_t DataVSpeedDisp; uint16_t DataVSpeedHysteresis; 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_Wakeup_Init 功 能:车速数据KL30_Wakeup_Init 参 数:无 返回值:无 ****************************************************************************** 注 意:该函数KL30_Wakeup_Init被调用一次 ******************************************************************************/ void Data_Vehicle_Speed_KL30_Wakeup_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_VehicleSpeedvalid; uint32_t Vehicle_Speed; Vehicle_Speed = Get_CAN_CH0_ID_101_Sig_ECU_Vehicle_Speed(); //ESC_VehicleSpeedvalid = Get_CAN_CH0_ID_330_Sig_ESC_Vehicle_speed_valid( ); // 第1步:获取实际车速值及车速有效性 if( Common_Get_IG_Sts( ) == COMMON_POWER_ON ) { if ((CAN_MSG_Status(&CAN_CH0_CanMsgOp, CAN_CH0_ID_CH0_101_Msg_Count) == CAN_SIG_LOST) || (Vehicle_Speed > 0XFF)) { /* 先判断掉线 */ if (CAN_MSG_Status(&CAN_CH0_CanMsgOp, CAN_CH0_ID_CH0_101_Msg_Count) == CAN_SIG_LOST) { DataVSpeedValid = 0; DataVSpeedActual = 0; DataVSpeedSampler.Backup = 0; } #if 0 else if ( ESC_VehicleSpeedvalid == 1 )//发送can无效标志位 { if ( DataVSpeedSampler.Timer1 <= 10 ) /* 10帧无效 */ { if ( DataVSpeedValid )//判断车速是否有效,有效采集10次,车速等于上次值 { DataVSpeedSampler.Timer1++; DataVSpeedActual = DataVSpeedSampler.Backup; } else//无效,不采集,车速=0 { DataVSpeedSampler.Timer1 = 10; DataVSpeedActual = 0; DataVSpeedSampler.Backup = 0; } } else//不采集就,车速=0 { DataVSpeedValid = 0; DataVSpeedActual = 0; DataVSpeedSampler.Backup = 0; } } #endif else /* 收到无效值 */ { if ( DataVSpeedSampler.Timer <= 100 ) /* 100帧无效值 */ { if ( DataVSpeedValid ) { DataVSpeedSampler.Timer++; DataVSpeedActual = DataVSpeedSampler.Backup; } else { DataVSpeedSampler.Timer = 100; DataVSpeedActual = 0; DataVSpeedSampler.Backup = 0; } } else // 接收到100帧无效值 { DataVSpeedValid = 0; DataVSpeedActual = 0; DataVSpeedSampler.Backup = 0; } } } else //车速在线且有效 { if ( DataVSpeedValid == 0 ) { DataVSpeedValid = 1; VSpeed = Vehicle_Speed; // VSpeed *= 9; // VSpeed >>= 4; 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 ]; //VSpeed *= 9; //VSpeed >>= 4; DataVSpeedActual = VSpeed * 10; } DataVSpeedSampler.Timer = 0; DataVSpeedSampler.Timer1 = 0; DataVSpeedSampler.Backup = DataVSpeedActual; } } } 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 *= 105; VSpeedCal /= 100; if((VSpeedCal % 10) >= 5) { VSpeedCal += 5; /* 四舍五入 */ } 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_Unit() == 0) /* KM */ { if ( DataVSpeedDisp >= 1990 ) { DataVSpeedDisp = 1990; } Vspeed = DataVSpeedDisp; } else //if (Get_Dis_Unit() == 1) /* MILE */ { Vspeed = Data_Km_To_Mile(DataVSpeedDisp); if ( Vspeed >= 1230 ) { Vspeed = 1230; } } // else // { // ; // } return Vspeed; }