288 lines
5.8 KiB
C
288 lines
5.8 KiB
C
#include "Err_code.h"
|
|
#include <string.h>
|
|
#define Err_MAX_SingleEVENTS 10 //最大事件数 MAX_SingleEVENTS-1
|
|
void add_event(uint8_t event);
|
|
static uint32_t Err_front = 0;
|
|
uint32_t Err_rear = 0;
|
|
|
|
uint8_t Err_Code_BitMap[Err_Code_Max] = {0};
|
|
uint8_t event_queue[Err_MAX_SingleEVENTS];
|
|
|
|
const ErrCode_info ErrCode_info_Table[] = {
|
|
{0, "未定义故障"},
|
|
{1, "输入过压故障"},
|
|
{2, "输入欠压故障"},
|
|
{3, "直流继电器粘连故障"},
|
|
{4, "交流继电器粘连故障"},
|
|
{5, "输入过流"},
|
|
{6, "SOC 100%"},
|
|
{7, "单体电压过高"},
|
|
{8, "电芯温度过高"},
|
|
{9, "充电电流需求过低"},
|
|
{10, "充电需求电压为0"},
|
|
{11, "电池高温预警"},
|
|
{12, "SOC过高报警"},
|
|
{13, "BMS碰撞故障"},
|
|
{14, "BMS内部绝缘故障"},
|
|
{15, "BMS内部通信"},
|
|
{16, "BMS预充失败"},
|
|
{17, "BMS总电压检测故障"},
|
|
{18, "BMS电流检测故障"},
|
|
{19, "BMS温度检测故障"},
|
|
{20, "正极接触器故障"},
|
|
{21, "负极接触器故障"},
|
|
{22, "预充接触器故障"},
|
|
{23, "车载储能装置过充故障"},
|
|
{24, "交流充电口锁紧故障"},
|
|
{25, "单体电压检测故障"},
|
|
{26, "BMS外部绝缘故障"},
|
|
{27, "电池热失控"},
|
|
{28, "BMS禁止充电"},
|
|
{29, "BMS热管理加热异常"},
|
|
{30, "BMS热管理制冷异常"},
|
|
{31, "BMS均衡失效"},
|
|
{32, "单体电池欠压警告"},
|
|
{33, "VCU禁止充电"},
|
|
{34, "VCU工作模式异常"},
|
|
{36, "BMS通讯超时"},
|
|
{37, "充电桩通讯超时"},
|
|
{38, "车辆未上高压"},
|
|
{39, "充电桩中止报文(弃用)"},//有问题,莫名会清零,导致BST发送错误
|
|
{40, "CML 参数不合适"},
|
|
{41, "CCS 禁止充电"},
|
|
{42, "KL30低压故障"},
|
|
{43, "车载储能装置类型过压报警"},
|
|
{44, "车载储能装置类型欠压报警"},
|
|
{45, "SOC低报警"},
|
|
{46, "充电过流故障"},
|
|
{47, "充电桩中止报文"},
|
|
{48, "板载温度过高故障"},
|
|
{49, "直流枪座温度过高故障"},
|
|
{50, "KL30高压压故障"},
|
|
{51, "充电座温度降额故障"},
|
|
{52, "内部温度降额故障故障"},
|
|
{53, "CC/CC2控制继电器控制失效"},
|
|
{54, "CP/CC1控制继电器控制失效"},
|
|
{55, "超出定义故障"},
|
|
};
|
|
|
|
const struct Err_shine Fault_type_Table[Fault_typeSDDC_Len] = {
|
|
{0,7},
|
|
{7,2},
|
|
{9,3},
|
|
{12,2},
|
|
{14,2},
|
|
};
|
|
|
|
|
|
// 错误码信息表的大小
|
|
const size_t ErrCode_info_Table_Size = sizeof(ErrCode_info_Table) / sizeof(ErrCode_info);
|
|
|
|
|
|
static __inline uint8_t GetArr_NUM(uint8_t Err_NUM)
|
|
{
|
|
|
|
return Err_NUM/8;
|
|
|
|
}
|
|
|
|
|
|
static __inline uint8_t GetArr_Bit(uint8_t Err_NUM)
|
|
{
|
|
|
|
return Err_NUM%8;
|
|
|
|
}
|
|
|
|
|
|
bool Err_Set(uint8_t Err_NUM)
|
|
{
|
|
#ifdef __Err_Debug__
|
|
if(Err_NUM>=Err_Code_Max_NUM)//设置的Err_NUM大于最大允许故障码数量
|
|
return false;
|
|
#endif
|
|
if(Err_Read(Err_NUM) == false)
|
|
{
|
|
add_event(Err_NUM);
|
|
|
|
uint8_t Arr_Num = GetArr_NUM(Err_NUM);
|
|
uint8_t Bit_Num = GetArr_Bit(Err_NUM);
|
|
|
|
Err_Code_BitMap[Arr_Num] |= 1<< Bit_Num;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
|
|
void Find_FaultCode_Location(uint8_t Err_NUM)
|
|
{
|
|
for(uint8_t i=0;i<Err_MAX_SingleEVENTS;i++)
|
|
{
|
|
if(event_queue[i] == Err_NUM)
|
|
{
|
|
for(uint8_t j=i;j<(Err_MAX_SingleEVENTS-i)+i;j++)
|
|
{
|
|
event_queue[j]=event_queue[j+1];
|
|
}
|
|
Err_rear--;
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
bool Err_Clear(uint8_t Err_NUM)
|
|
{
|
|
#ifdef __Err_Debug__
|
|
if(Err_NUM>=Err_Code_Max_NUM)//设置的Err_NUM大于最大允许故障码数量
|
|
return false;
|
|
#endif
|
|
Find_FaultCode_Location(Err_NUM);
|
|
if(Err_Read(Err_NUM) == true)
|
|
{
|
|
uint8_t Arr_Num = GetArr_NUM(Err_NUM);
|
|
uint8_t Bit_Num = GetArr_Bit(Err_NUM);
|
|
|
|
Err_Code_BitMap[Arr_Num] &= 0<< Bit_Num;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool Err_Read(uint8_t Err_NUM)
|
|
{
|
|
uint8_t Arr_Num = GetArr_NUM(Err_NUM);
|
|
uint8_t Bit_Num = GetArr_Bit(Err_NUM);
|
|
|
|
uint8_t Err_State = Err_Code_BitMap[Arr_Num] & (1<< Bit_Num);
|
|
|
|
if(Err_State)
|
|
return true;//存在故障码
|
|
else
|
|
return false;
|
|
|
|
|
|
}
|
|
//是否有故障码
|
|
bool Err_Check()
|
|
{
|
|
for(uint8_t i = 0;i<Err_Code_Max;i++)
|
|
{
|
|
if(Err_Code_BitMap[i] != 0)
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
//遍历故障码,并通过串口输出
|
|
bool Err_Traverse()
|
|
{
|
|
for(uint8_t i = 0;i<Err_Code_Max;i++)
|
|
{
|
|
if(Err_Code_BitMap[i] != 0)
|
|
{
|
|
for(uint8_t j=0;j<8;j++)
|
|
{
|
|
if(Err_Code_BitMap[i]&(1<<j))
|
|
{
|
|
uint8_t ErrCode = i*8 + j;
|
|
printf("ErrCode is %d\r\n",ErrCode);
|
|
// uint8_t ErrLen = ARRAY_LENGTH(ErrCode_info_Table);
|
|
// for(uint8_t k=0;k<ErrLen;k++)
|
|
// {
|
|
// if(ErrCode_info_Table[k].index == ErrCode)
|
|
// {
|
|
// printf("Error Code InFo is %s\r\n",ErrCode_info_Table[k].data);
|
|
// }
|
|
//
|
|
// }
|
|
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
return true;
|
|
}
|
|
//查询是否存在分级故障
|
|
//return true 存在对应故障 false 没有对应故障
|
|
bool Err_ScanHierarchical_fault(enum Fault_typeSDDC Fault_type)
|
|
{
|
|
if(Fault_type >= Fault_typeSDDC_Len)
|
|
{
|
|
printf("ERR SACN Hierarchical ERR!!\r\n");
|
|
return true;
|
|
}
|
|
uint8_t Star_Arr = Fault_type_Table[Fault_type].Star_Num;//该数组被存放在flash中,提取到R3R4里面
|
|
uint8_t Arr_len = Fault_type_Table[Fault_type].Err_shine_len;
|
|
for(uint8_t i= 0;i<Arr_len;i++)
|
|
{
|
|
if(Err_Code_BitMap[Star_Arr+i] != 0)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
}
|
|
return false;
|
|
}
|
|
|
|
static bool is_queue_empty(void) {
|
|
return Err_front == Err_rear;
|
|
}
|
|
|
|
static bool is_queue_full() {
|
|
return Err_front == (Err_rear + 1) % Err_MAX_SingleEVENTS;
|
|
}
|
|
|
|
|
|
static void add_event(uint8_t event) {
|
|
// if (is_queue_full()) {
|
|
// printf("Code Event queue is full\n");
|
|
// return;
|
|
// }
|
|
|
|
event_queue[Err_rear] = event;
|
|
Err_rear = (Err_rear + 1) % Err_MAX_SingleEVENTS;
|
|
}
|
|
|
|
void ErrGetSequence(void)
|
|
{
|
|
while (!is_queue_empty())
|
|
{
|
|
printf("Err NUM is %d\r\n",event_queue[Err_front]);
|
|
Err_front = (Err_front + 1) % Err_MAX_SingleEVENTS;
|
|
}
|
|
}
|
|
|
|
void Print_Err(void)
|
|
{
|
|
for(uint8_t i=0;i<Err_MAX_SingleEVENTS;i++)
|
|
{
|
|
if(event_queue[i] > 0)
|
|
{
|
|
// ErrGetSequence();
|
|
uint8_t ErrLen = ARRAY_LENGTH(ErrCode_info_Table);
|
|
for(uint8_t k=0;k<ErrLen;k++)
|
|
{
|
|
if(ErrCode_info_Table[k].index == event_queue[i])
|
|
{
|
|
printf("Error Code InFo is %s-%d\r\n",ErrCode_info_Table[k].data,event_queue[i]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void ErrClearSequence(void)
|
|
{
|
|
memset(Err_Code_BitMap,0,Err_Code_Max);//清除全部故障码
|
|
memset(event_queue,0, Err_MAX_SingleEVENTS);
|
|
Err_front = 0;
|
|
Err_rear = 0;
|
|
}
|
|
|
|
|
|
|