#include "soft_bms.h" #include "main.h" #include "soft_engine.h" #include "string.h" #include "stdio.h" #include "stdlib.h" #include "soft_crc.h" #include "common.h" #include "soft_device.h" #include "usart_data_handle.h" #include "soft_version.h" #include "soft_adc.h" #include "soft_can.h" #include "crc.h" #include "soft_timer.h" /************************************herewin******************************************/ /** * @file HerewinCanRecvHookFunction * @brief herewin bms 解析 * @param none * @details * @author Zhang Sir **/ herewin_bms herewin_info; Connect_check Herewin_Link; herewin_can_info can_info; void HerewinCanRecvHookFunction(uint32_t cellCanID, uint8_t data[], uint8_t len) { Herewin_Link.recv_time = HAL_GetTick(); Herewin_Link.connect_status = COMP_NORMAL; uint8_t i = 0; uint8_t canid_pf = (cellCanID >> 16) & 0xff; switch (canid_pf) { //定值查询包 case 0x81: if((data[0] == 8 )&& (0x80 == data[2])) { herewin_info.battery_num = data[4]; } break; case 0x83: herewin_info.get_temp_flag = true; //电芯温度传感器只有三个,取前三个字节,传给APP取平均值 memcpy(&herewin_info.battery_temp[0],&data[0],1); memcpy(&herewin_info.battery_temp[1],&data[1],1); memcpy(&herewin_info.battery_temp[2],&data[2],1); break; //单体电压 case 0x85: can_info.message_num = data[0]; //第一包 if(can_info.message_num == 1) { memset(&can_info,0,sizeof(can_info)); can_info.byte_num = data[2] + data[3] * 256; can_info.message_total = data[1]; //算出最后一包的有效字节数 can_info.last_frame_num = can_info.byte_num - 4 -(can_info.message_total - 2) * 7; memcpy(&can_info.herewin_buf[0],&data[4],4); for(i = 0;i < 4;i++) { can_info.crc += can_info.herewin_buf[i]; } can_info.i += 4; } //最后一包 协议校验码是最后发,12S的电池校验会单独占一个字节发送 //14s else if(can_info.message_num == can_info.message_total && can_info.last_frame_num <= 5 && can_info.last_frame_num > 0 ) { memcpy(&can_info.herewin_buf[can_info.i],&data[1],can_info.last_frame_num); for(i = 0;i < can_info.last_frame_num;i++) { can_info.crc += can_info.herewin_buf[can_info.i + i]; } //校验 if(can_info.crc == data[ 1 + can_info.last_frame_num] + 256 * data[ 2 + can_info.last_frame_num]) { memcpy(&herewin_info.battery_vol[0],&can_info.herewin_buf[0],can_info.byte_num); } memset(&can_info,0,sizeof(can_info)); } //12s电池 最后一包有效字节-1 else if(can_info.message_num == can_info.message_total && can_info.last_frame_num <= 0 ) { //最后一包只有1字节校验 if(can_info.last_frame_num == -1) { memcpy(&can_info.herewin_buf[can_info.i],&data[1],1); can_info.crc -= can_info.herewin_buf[can_info.i - 1]; //校验 if(can_info.crc == can_info.herewin_buf[can_info.i - 1] + 256 * can_info.herewin_buf[can_info.i]) { memcpy(&herewin_info.battery_vol[0],&can_info.herewin_buf[0],can_info.byte_num); } } //最后一包只有两字节校验 else if(can_info.last_frame_num == 0) { memcpy(&can_info.herewin_buf[can_info.i],&data[1],2); //校验 if(can_info.crc == can_info.herewin_buf[can_info.i] + 256 * can_info.herewin_buf[can_info.i + 1]) { memcpy(&herewin_info.battery_vol[0],&can_info.herewin_buf[0],can_info.byte_num); } } memset(&can_info,0,sizeof(can_info)); } else { memcpy(&can_info.herewin_buf[can_info.i],&data[1],7); for(i = 0;i < 7;i++) { can_info.crc += can_info.herewin_buf[can_info.i + i]; } can_info.i += 7; } break; //电池循环次数查询 case 0x87: memcpy(&herewin_info.circulation_num,&data[0],2); break; //充电请求 case 0x22: memcpy(&herewin_info.re_vol,&data[0],2); memcpy(&herewin_info.re_ele,&data[2],2); memcpy(&herewin_info.max_vol,&data[4],2); memcpy(&herewin_info.power_status,&data[6],2); break; //告警信息 case 0x24: memcpy(&herewin_info.alarm_info,&data[0],2); memcpy(&herewin_info.warn_info,&data[2],2); break; //电流 电压信息 case 0x26: memcpy(&herewin_info.total_vol,&data[0],2); memcpy(&herewin_info.tolal_ele,&data[2],2); memcpy(&herewin_info.SOC_info,&data[4],1); memcpy(&herewin_info.SOH_info,&data[5],1); memcpy(&herewin_info.SOP_info,&data[6],2); break; default: break; } } /** * @file send_msg_to_herewin * @brief herewin 发送信息 * @param none * @details 海盈电池收不到心跳包20分后停止主动发送数据 2000ms周期给海盈电池发送心跳包 * @author Zhang Sir **/ void send_msg_to_herewin(void) { static uint32_t herewin_heart_time = 0; static uint32_t herewin_vol_time = 0; static uint8_t heart_num_count = 0; if(Herewin_Link.connect_status == COMP_NORMAL) { //2000ms发送心跳包 if(HAL_GetTick() - herewin_heart_time > 2000) { uint8_t heart_buf[8] = {0x00,0x00,0x00,0x01, 0x00,0x00,0x00,0x01}; Can_Send_Msg_Func(CANID2, heart_buf, 8, HEREWIN_HEART_ID, CAN_ID_EXT); herewin_heart_time = HAL_GetTick(); } //1000ms发送单体电压请求 和单体温度请求 发送5次电芯个数 if(HAL_GetTick() - herewin_vol_time > 1000) { uint8_t herewin_num = 8; Can_Send_Msg_Func(CANID2, 0, 0, HEREWIN_VOL_ID, CAN_ID_EXT); Can_Send_Msg_Func(CANID2, 0, 0, HEREWIN_TEM_ID, CAN_ID_EXT); //请求5次电芯个数 5次循环次数 Can_Send_Msg_Func(CANID2, &herewin_num, 1, HEREWIN_SEARCH_ID, CAN_ID_EXT); Can_Send_Msg_Func(CANID2, 0, 0, HEREWIN_CIRCULATION_ID, CAN_ID_EXT); herewin_vol_time = HAL_GetTick(); } } else { //上电时先发送5次心跳包 防止电池休眠 if(HAL_GetTick() - herewin_heart_time > 2000 && heart_num_count > 0) { uint8_t heart_buf[8] = {0x00,0x00,0x00,0x01, 0x00,0x00,0x00,0x01}; Can_Send_Msg_Func(CANID2, heart_buf, 8, HEREWIN_HEART_ID, CAN_ID_EXT); herewin_heart_time = HAL_GetTick(); heart_num_count--; } } } /**************************************************************************************/ /************************************Okcell*******************************************/ /** * @file update_bms_data * @brief 更新电池信息 * @param none * @details * @author Zhang Sir **/ uint8_t group_num = 0; //电池组数 #define RESET_OKIDCODE_DELAY (3) unsigned char okcell_sha1_out[20] = {0}; //结构体指针类型 _OKCELL_DEVICE okcell_device1 = {.Okcell_Link.connect_status = COMP_NOEXIST, .Okcell_get_s = false, .okcell_inf.cell_D0.cell_d0[6] = 0}, okcell_device2 = {.Okcell_Link.connect_status = COMP_NOEXIST, .Okcell_get_s = false, .okcell_inf.cell_D0.cell_d0[6] = 0}; void OkcellCanRecvHookFunction(uint32_t cellCanID, uint8_t data[], uint8_t len) { _OKCELL_DEVICE *OKptr = NULL; //添加兼容两组电池 static uint8_t OKIdCode1counts = 0,OKIdCode2counts = 0; //判断是哪个电池的ID,通过ID来区分电池。并支持飞控不断电更换电池 if(cellCanID != okcell_device1.deviceCanID && cellCanID != okcell_device2.deviceCanID) { //分配给1号结构体 if(OKIdCode1counts == 0){ OKIdCode1counts = RESET_OKIDCODE_DELAY; OKptr = &okcell_device1; OKptr->deviceCanID = cellCanID; group_num = 1; } //分配给2号结构体 else if(OKIdCode2counts == 0) { OKIdCode2counts = RESET_OKIDCODE_DELAY; OKptr = &okcell_device2; OKptr->deviceCanID = cellCanID; group_num = 2; } //不分配结构体 else{ OKIdCode1counts>0 ? OKIdCode1counts-- : OKIdCode1counts; OKIdCode2counts>0 ? OKIdCode2counts-- : OKIdCode2counts; } } else if(cellCanID == okcell_device1.deviceCanID) { OKIdCode1counts = RESET_OKIDCODE_DELAY; OKptr = &okcell_device1; OKptr->deviceCanID = cellCanID; } else if(cellCanID == okcell_device2.deviceCanID) { OKIdCode2counts = RESET_OKIDCODE_DELAY; OKptr = &okcell_device2; OKptr->deviceCanID = cellCanID; } //如果指针找到了存放数据的结构体 if(OKptr != NULL) { //找到开头,开始接收 //strncmp比较字符串,遇到'\0'会结束,所以不适合用字数组比较 if(memcmp(data,"ZFKJ",4) == 0){ OKptr->Okcell_recv_index = 0; OKptr->Okcell_get_s = true; } //溢出检测 if(OKptr->Okcell_recv_index + len > OKCELL_MAXLEN) { memset(OKptr->Okcell_recv_buf,0,OKptr->Okcell_recv_index); OKptr->Okcell_recv_index = 0; OKptr->Okcell_get_s = false; } //接收到起始标志后开始存数组 if(OKptr->Okcell_get_s == true){ //复制数据 memcpy(&OKptr->Okcell_recv_buf[OKptr->Okcell_recv_index], data, len); OKptr->Okcell_recv_index += len; } //找到结尾,开始解析,不能用strstr if(OKptr->Okcell_get_s == true && findStrInArray(OKptr->Okcell_recv_buf, OKptr->Okcell_recv_index, "END") != 0) { OKptr->Okcell_get_s = false; unsigned char loadflag = OKptr->Okcell_recv_buf[7]; //负载标识为固定的OxBB if(loadflag == 0xBB) { unsigned char cellLoadLen = OKptr->Okcell_recv_buf[6]; //避免错误数据造成的数组溢出 if(cellLoadLen < OKCELL_MAXLEN-9) { unsigned int cellCheck = OKptr->Okcell_recv_buf[8+cellLoadLen]*256 + OKptr->Okcell_recv_buf[9+cellLoadLen]; //校验通过,测试没通过 if(((crc_ccitt(&OKptr->Okcell_recv_buf[8], cellLoadLen))&0xffff) == cellCheck) { unsigned short cellCmd = (OKptr->Okcell_recv_buf[4]<<8) + OKptr->Okcell_recv_buf[5]; OKptr->Okcell_Link.connect_status = COMP_NORMAL; //用于判断电池波特率锁定,实测只要给电池发送数据,电池收到后就会锁定波特率 //由于锁定波特率缺少反馈应答,5s内收到多于10包正确的数据则认为波特率锁定成功。 if(OKptr->cell_bps_lock_success == false) { OKptr->recv_celldata_counts++; if(OKptr->recv_celldata_counts == 1){ OKptr->recv_celldata_time = HAL_GetTick(); } else if(OKptr->recv_celldata_counts >= 10) { OKptr->recv_celldata_counts = 0; uint32_t timeperiod = HAL_GetTick() - OKptr->recv_celldata_time; if(timeperiod < 5000000) { OKptr->cell_bps_lock_success = true; } } } //更新电池数据到来时间 OKptr->Okcell_Link.recv_time = HAL_GetTick(); switch(cellCmd) { case 0x0000: //stm32为小段模式,OKCELL发送过来的数据为大端模式,不能使用memcpy //memcpy(&cell_D0,&Okcell_recv_buf[8],cellLoadLen); //避免电池厂家私自增加协议造成的数组溢出 if(cellLoadLen <= sizeof(_CELL_D0)) { for(unsigned char i=0; iokcell_inf.cell_D0.cell_d0[i] = (OKptr->Okcell_recv_buf[8 + i*2] << 8) + OKptr->Okcell_recv_buf[9 + i*2]; } } break; case 0x0300: //cell_inf1.cell_D3.cell_d3[4] = (Okcell_recv_buf[16] << 8) + Okcell_recv_buf[17]; //避免电池厂家私自增加协议造成的数组溢出 if(cellLoadLen <= sizeof(_CELL_D3)) { for(unsigned char i=0; iokcell_inf.cell_D3.cell_d3[i] = (OKptr->Okcell_recv_buf[8 + i*2] << 8) + OKptr->Okcell_recv_buf[9 + i*2]; } } break; case 0x8200://SHA1加密文密码查询 //避免电池厂家私自增加协议造成的数组溢出 if(cellLoadLen <= sizeof(_CELL_P2)) { for(unsigned char i=0; iokcell_inf.cell_P2.cell_p2[i] = OKptr->Okcell_recv_buf[8 + i]; } } if(memcmp(OKptr->okcell_inf.cell_P2.cell_p2, okcell_sha1_out, sizeof(_CELL_P2)) == 0) { //收到了正确密文 OKptr->get_cellEncryption = true; } break; case 0x8300://获取电池编号 OKptr->get_cellNumber = true; //避免电池厂家私自增加协议造成的数组溢出 if(cellLoadLen <= sizeof(_CELL_P3)) { for(uint8_t i=0; iokcell_inf.cell_P3.cell_p3[i] = OKptr->Okcell_recv_buf[8 + i]; } } break; default: break; } } } } //清理buff memset(OKptr->Okcell_recv_buf,0,OKptr->Okcell_recv_index); //包数完整重新计数 OKptr->Okcell_recv_index = 0; } } } struct OkCell_P80 okcell_p80; struct OkCell_P82 okcell_p82; struct OkCell_P83 okcell_p83; uint32_t time_okcell_p80 = 0; uint32_t time_okcell_p82 = 0; uint32_t time_okcell_p83 = 0; bool send_okcell_p80data = false; bool send_okcell_p82data = false; bool send_okcell_p83data = false; void send_msg_to_okcell(void) { //自动锁定波特率,正方电池开机自动循环500K/1M发送数据。正方电池缺少一个波特率锁定的反馈应答 //电池开机会自动1M/500k切换波特率给飞控发信息,所以不用用是否连接来判断。 if(/*okcell_device1.okcell_link_status == COMP_NOEXIST &&*/ send_okcell_p80data == false && okcell_device1.cell_bps_lock_success == false && HAL_GetTick() < 30000 && HAL_GetTick() - time_okcell_p80 > 250) { time_okcell_p80 = HAL_GetTick(); okcell_p80.ok_s[0] = 'Z'; okcell_p80.ok_s[1] = 'F'; okcell_p80.ok_s[2] = 'K'; okcell_p80.ok_s[3] = 'J'; okcell_p80.ok_cmd[0] = 0x80; okcell_p80.ok_cmd[1] = 0x00; okcell_p80.ok_len = 1; okcell_p80.ok_flag = 0xbb; okcell_p80.ok_data = 0x79; short OKcellCRC = crc_ccitt((uint8_t *)&okcell_p80.ok_data,okcell_p80.ok_len); okcell_p80.ok_crc[0] = (OKcellCRC>>8) & 0xff; okcell_p80.ok_crc[1] = OKcellCRC & 0xff; okcell_p80.ok_e[0] = 'E'; okcell_p80.ok_e[1] = 'N'; okcell_p80.ok_e[2] = 'D'; send_okcell_p80data = true; } if(send_okcell_p80data == true){ send_okcell_p80data =false; Can_Send_Msg_Func(CANID2, (unsigned char *)&okcell_p80, sizeof(okcell_p80), CAN_OKCELL_SEND_ID, CAN_ID_EXT); } if(send_okcell_p82data == true){ send_okcell_p82data =false; Can_Send_Msg_Func(CANID2, (unsigned char *)&okcell_p82, sizeof(okcell_p82), okcell_device1.deviceCanID, CAN_ID_EXT); } //获取电池编号 if(okcell_device1.Okcell_Link.connect_status == COMP_NORMAL && okcell_device1.cell_bps_lock_success == true && okcell_device1.get_cellNumber == false && send_okcell_p83data == false && HAL_GetTick() - time_okcell_p83 > 1000) { time_okcell_p83 = HAL_GetTick(); okcell_p83.ok_s[0] = 'Z'; okcell_p83.ok_s[1] = 'F'; okcell_p83.ok_s[2] = 'K'; okcell_p83.ok_s[3] = 'J'; okcell_p83.ok_cmd[0] = 0x83; okcell_p83.ok_cmd[1] = 0x00; okcell_p83.ok_len = 0; okcell_p83.ok_flag = 0xbb; okcell_p83.ok_crc[0] = 0xff; okcell_p83.ok_crc[1] = 0xff; okcell_p83.ok_e[0] = 'E'; okcell_p83.ok_e[1] = 'N'; okcell_p83.ok_e[2] = 'D'; send_okcell_p83data = true; } if(send_okcell_p83data == true){ send_okcell_p83data =false; Can_Send_Msg_Func(CANID2, (unsigned char *)&okcell_p83, sizeof(okcell_p83), okcell_device1.deviceCanID, CAN_ID_EXT); } } /**************************************************************************************/ /************************************VKBMS*******************************************/ /** * @file Send_VKbms_info * @brief VK智能电池协议飞控端发送 * @param none * @details * @author Zhang Sir **/ uint8_t bms_step = 0; void send_msg_to_VKbms(void) { static uint8_t change_dev = 1; Vkbms_Device *ptr = NULL; //处理 有问题,如果不是同时上电,后上电的电池2无法读取电池设备信息。 static uint32_t bms_heart_time = 0;; unsigned int can_id = 0; uint8_t len = 0, msg_id = 0,i = 0; uint8_t bms_can_buf[8] = {0}; uint16_t crc = 0; if(change_dev == 1) { change_dev = 2; ptr = &Device1; } else if(change_dev == 2) { change_dev = 1; ptr = &Device2; } if(ptr->Vkbms_Link.connect_status != COMP_NORMAL) return; //握手应答 if(ptr->ack_to_bms == true) { msg_id = 0x01; can_id = msg_id << 20 | 0x7 << 17 | ptr->source_id << 11 | 0x1 << 5 | 0x1 << 4 | 0x1 << 3 | 1; len = 2; bms_can_buf[0] = 0x56; bms_can_buf[1] = 0x31; Can_Send_Msg_Func(CANID2, bms_can_buf, len, can_id, CAN_ID_EXT); ptr->ack_to_bms = false; } if(ptr->get_bms3_ack == false) { len = 0; msg_id = 0x03;//canid 4083768 3E5039 can_id = msg_id << 20 | 0x7 << 17 | ptr->source_id << 11 | 0x1 << 5 | 0x1 << 4 | 0x1 << 3 | 1; Can_Send_Msg_Func(CANID2, bms_can_buf, len, can_id, CAN_ID_EXT); } else if(ptr->get_bms4_ack == false) { len = 0; msg_id = 0x04; //canid 5132344 4E5039 can_id = msg_id << 20 | 0x7 << 17 | ptr->source_id << 11 | 0x1 << 5 | 0x1 << 4 | 0x1 << 3 | 1; Can_Send_Msg_Func(CANID2, bms_can_buf, len, can_id, CAN_ID_EXT); } else if(ptr->get_bms5_ack == false) { len = 0; msg_id = 0x05;//canid 6180920 5E5039 can_id = msg_id << 20 | 0x7 << 17 | ptr->source_id << 11 | 0x1 << 5 | 0x1 << 4 | 0x1 << 3 | 1; Can_Send_Msg_Func(CANID2, bms_can_buf, len, can_id, CAN_ID_EXT); } if(start_msg.key_to_bms == true) { msg_id = 0x07; crc = Get_Crc16(&start_msg.key_data[0],20); memcpy(&bms_can_buf[0],&crc,2); memcpy(&bms_can_buf[2],&start_msg.key_data[i],6); can_id = msg_id << 20 | 0x7 << 17 | ptr->source_id << 11 | 0x1 << 5 | 0x1 << 4 | 0x0 << 3 | 1; Can_Send_Msg_Func(CANID2, &bms_can_buf[0], 8, can_id, CAN_ID_EXT); i += 6; can_id = msg_id << 20 | 0x7 << 17 | ptr->source_id << 11 | 0x1 << 5 | 0x0 << 4 | 0x0 << 3 | 2; Can_Send_Msg_Func(CANID2, &start_msg.key_data[i], 8, can_id, CAN_ID_EXT); i += 8; can_id = msg_id << 20 | 0x7 << 17 | ptr->source_id << 11 | 0x1 << 5 | 0x0 << 4 | 0x1 << 3 | 3; Can_Send_Msg_Func(CANID2, &start_msg.key_data[i], 6, can_id, CAN_ID_EXT); } //开启mos else if(start_msg.mos_status == true) { msg_id = 0x08; can_id = msg_id << 20 | 0x7 << 17 | ptr->source_id << 11 | 0x1 << 5 | 0x1 << 4 | 0x1 << 3 | 1; bms_can_buf[0] = 0x01; Can_Send_Msg_Func(CANID2, bms_can_buf, 1, can_id, CAN_ID_EXT); } else if(utc_time != 0 && utc_send_time > 0 ) { msg_id = 0x09; can_id = msg_id << 20 | 0x7 << 17 | ptr->source_id << 11 | 0x1 << 5 | 0x1 << 4 | 0x1 << 3 | 1; memcpy(&bms_can_buf[0],&utc_time,4); Can_Send_Msg_Func(CANID2, bms_can_buf, 4, can_id, CAN_ID_EXT); utc_send_time--; } else if(HAL_GetTick() - bms_heart_time > 500)//实时信息应答包 { msg_id = 0x02; can_id = msg_id << 20 | 0x7 << 17 | ptr->source_id << 11 | 0x1 << 5 | 0x1 << 4 | 0x1 << 3 | 1; Can_Send_Msg_Func(CANID2, bms_can_buf, 0, can_id, CAN_ID_EXT); bms_heart_time = HAL_GetTick(); } // if(Device1.Vkbms_Link.connect_status == COMP_NORMAL || Device2.Vkbms_Link.connect_status == COMP_NORMAL) // { // static uint8_t bsm_step_num = 6; // static uint32_t bms_heart_time = 0;; // unsigned int can_id = 0; // uint8_t len = 0, msg_id = 0,i = 0; // uint8_t bms_can_buf[8] = {0}; // uint16_t crc = 0; // //上电握手 // if(Device1.ack_to_bms == true || Device2.ack_to_bms == true) // { // msg_id = 0x01; // if(Device1.ack_to_bms == true) // { // can_id = msg_id << 20 | 0x7 << 17 | Device1.source_id << 11 | 0x1 << 5 | 0x1 << 4 | 0x1 << 3 | 1; // Device1.ack_to_bms = false; // } // else if (Device2.ack_to_bms == true) // { // can_id = msg_id << 20 | 0x7 << 17 | Device2.source_id << 11 | 0x1 << 5 | 0x1 << 4 | 0x1 << 3 | 1; // Device2.ack_to_bms = false; // } // len = 2; // bms_can_buf[0] = 0x56; // bms_can_buf[1] = 0x31; // Can_Send_Msg_Func(CANID2, bms_can_buf, len, can_id, CAN_ID_EXT); // } // //读取电池信息 // if(bms_step <= 2) // { // //上电发送的信息 // switch (bms_step) // { // case 0: // if(bsm_step_num > 0) // { // len = 0; // msg_id = 0x03;//canid 4083768 3E5038 // can_id = msg_id << 20 | 0x7 << 17 | Device1.source_id << 11 | 0x1 << 5 | 0x1 << 4 | 0x1 << 3 | 1; // Can_Send_Msg_Func(CANID2, bms_can_buf, len, can_id, CAN_ID_EXT); // if(Device2.Vkbms_Link.connect_status == COMP_NORMAL) // { // can_id = msg_id << 20 | 0x7 << 17 | Device2.source_id << 11 | 0x1 << 5 | 0x1 << 4 | 0x1 << 3 | 1; // Can_Send_Msg_Func(CANID2, bms_can_buf, len, can_id, CAN_ID_EXT); // } // bsm_step_num--; // } // else // { // bsm_step_num = 5; // bms_step = 1; // } // break; // case 1: // if(bsm_step_num > 0) // { // len = 0; // msg_id = 0x04; //canid 5132344 4E5038 // can_id = msg_id << 20 | 0x7 << 17 | Device1.source_id << 11 | 0x1 << 5 | 0x1 << 4 | 0x1 << 3 | 1; // Can_Send_Msg_Func(CANID2, bms_can_buf, len, can_id, CAN_ID_EXT); // if(Device2.Vkbms_Link.connect_status == COMP_NORMAL) // { // can_id = msg_id << 20 | 0x7 << 17 | Device2.source_id << 11 | 0x1 << 5 | 0x1 << 4 | 0x1 << 3 | 1; // Can_Send_Msg_Func(CANID2, bms_can_buf, len, can_id, CAN_ID_EXT); // } // bsm_step_num--; // } // else // { // bsm_step_num = 5; // bms_step = 2; // } // break; // case 2: // if(bsm_step_num > 0) // { // len = 0; // msg_id = 0x05;//canid 6180920 5E5038 // can_id = msg_id << 20 | 0x7 << 17 | Device1.source_id << 11 | 0x1 << 5 | 0x1 << 4 | 0x1 << 3 | 1; // Can_Send_Msg_Func(CANID2, bms_can_buf, len, can_id, CAN_ID_EXT); // if(Device2.Vkbms_Link.connect_status == COMP_NORMAL) // { // can_id = msg_id << 20 | 0x7 << 17 | Device2.source_id << 11 | 0x1 << 5 | 0x1 << 4 | 0x1 << 3 | 1; // Can_Send_Msg_Func(CANID2, bms_can_buf, len, can_id, CAN_ID_EXT); // } // bsm_step_num--; // } // else // { // bsm_step_num = 5; // bms_step = 3; // } // break; // default: // break; // } // } // //秘钥匹配 // else if(start_msg.key_to_bms == true && bsm_step_num > 0 && bms_step == 3 ) //上个if语句发完再发 // { // msg_id = 0x07; // crc = Get_Crc16(&start_msg.key_data[0],20); // memcpy(&bms_can_buf[0],&crc,2); // memcpy(&bms_can_buf[2],&start_msg.key_data[i],6); // can_id = msg_id << 20 | 0x7 << 17 | Device1.source_id << 11 | 0x1 << 5 | 0x1 << 4 | 0x0 << 3 | 1; // Can_Send_Msg_Func(CANID2, bms_can_buf, len, can_id, CAN_ID_EXT); // i += 6; // can_id = msg_id << 20 | 0x7 << 17 | Device1.source_id << 11 | 0x1 << 5 | 0x0 << 4 | 0x0 << 3 | 2; // Can_Send_Msg_Func(CANID2, start_msg.key_data, len, can_id, CAN_ID_EXT); // i += 8; // can_id = msg_id << 20 | 0x7 << 17 | Device1.source_id << 11 | 0x1 << 5 | 0x0 << 4 | 0x1 << 3 | 3; // Can_Send_Msg_Func(CANID2, start_msg.key_data, len, can_id, CAN_ID_EXT); // bsm_step_num--; // if(bsm_step_num == 0) // { // bsm_step_num = 5; // bms_step = 4; // } // } // //开启mos // else if(start_msg.mos_status == true && bsm_step_num > 0 && (bms_step == 4 || start_msg.mos_status == true)) // { // msg_id = 0x08; // can_id = msg_id << 20 | 0x7 << 17 | Device1.source_id << 11 | 0x1 << 5 | 0x1 << 4 | 0x1 << 3 | 1; // bms_can_buf[0] = 0x01; // Can_Send_Msg_Func(CANID2, bms_can_buf, len, can_id, CAN_ID_EXT); // bsm_step_num--; // } // else if(HAL_GetTick() - bms_heart_time > 1000) // { // msg_id = 0x02; // can_id = msg_id << 20 | 0x7 << 17 | Device1.source_id << 11 | 0x1 << 5 | 0x1 << 4 | 0x1 << 3 | 1; // Can_Send_Msg_Func(CANID2, bms_can_buf, 0, can_id, CAN_ID_EXT); // if(Device2.Vkbms_Link.connect_status == COMP_NORMAL) // { // can_id = msg_id << 20 | 0x7 << 17 | Device2.source_id << 11 | 0x1 << 5 | 0x1 << 4 | 0x1 << 3 | 1; // Can_Send_Msg_Func(CANID2, bms_can_buf, 0, can_id, CAN_ID_EXT); // } // bms_heart_time = HAL_GetTick(); // } // } } /** * @file BMSCanRecvHookFunction * @brief VK智能电池协议 * @param none * @details * @author Zhang Sir **/ uint16_t bms_test = 0; uint16_t bms_re = 0; uint8_t fmu_send_vkbms_msgid = 0; void BMSCanRecvHookFunction(uint32_t CanID, uint8_t data[], uint8_t len) { uint32_t source_id = 0, msg_id = 0; uint8_t bms_SOF = 0, bms_EOF = 0, frame_num = 0; static uint32_t bms1_source_id = 0; static uint32_t pack_msg_id = 0; Vkbms_Device *Bmspointer = NULL; msg_id = (CanID & VK_MSG_MASK_ID) >> 20; source_id = (CanID & VK_SRC_MASK_ID) >> 5; bms_SOF = (CanID >> 4) & 0x1; bms_EOF = (CanID >> 3) & 0x1; frame_num = CanID & 0x7; if(source_id == bms1_source_id || bms1_source_id == 0) { bms1_source_id = source_id; Bmspointer = &Device1; Bmspointer->source_id = source_id; } else { Bmspointer = &Device2; Bmspointer->source_id = source_id; } Bmspointer->Vkbms_Link.connect_status = COMP_NORMAL; Bmspointer->Vkbms_Link.recv_time = HAL_GetTick(); //单帧 if(bms_SOF == 1 && bms_EOF == 1) { memcpy(&Bmspointer->bms_can_buf[0],&data[0],len); } //多帧 帧头 else if(bms_SOF == 1 && bms_EOF == 0) { Bmspointer->mul_frame_i = 0; Bmspointer->mul_frame_num = 2; Bmspointer->if_mul_frame = true; Bmspointer->recv_mul_freme_complete = false; memcpy(&Bmspointer->bms_can_buf[Bmspointer->mul_frame_i],&data[0],len); Bmspointer->mul_frame_i += len; pack_msg_id = msg_id; } // 中间帧 else if(Bmspointer->if_mul_frame == true && bms_SOF == 0 && bms_EOF == 0 && pack_msg_id == msg_id) { if(Bmspointer->mul_frame_num == frame_num || ( Bmspointer->mul_frame_num == 0 && frame_num == 1) /*&& ((Bmspointer->mul_frame_i + len) <= sizeof(vkbms2))*/ ) { memcpy(&Bmspointer->bms_can_buf[Bmspointer->mul_frame_i],&data[0],len); if(( Bmspointer->mul_frame_num == 0 && frame_num == 1)) { Bmspointer->mul_frame_num++; } Bmspointer->mul_frame_i += len; Bmspointer->mul_frame_num++; if(Bmspointer->mul_frame_num >= 8) { Bmspointer->mul_frame_num = 0; } } else { Bmspointer->if_mul_frame = false; } } //帧尾 else if(bms_SOF == 0 && bms_EOF == 1 && Bmspointer->if_mul_frame == true && pack_msg_id == msg_id) { memcpy(&Bmspointer->bms_can_buf[Bmspointer->mul_frame_i],&data[0],len); Bmspointer->mul_frame_i += len; Bmspointer->if_mul_frame = false; //bms_test = Get_Crc16(&Bmspointer->bms_can_buf[2], Bmspointer->mul_frame_i - 2); //bms_re = Bmspointer->bms_can_buf[0] + (Bmspointer->bms_can_buf[1] << 8); if(Get_Crc16(&Bmspointer->bms_can_buf[2], Bmspointer->mul_frame_i - 2) == (Bmspointer->bms_can_buf[0] + (Bmspointer->bms_can_buf[1] << 8))) { Bmspointer->recv_mul_freme_complete = true; } } switch (msg_id) { case 0X01: if(Bmspointer->bms_can_buf[0] == 0x56 && Bmspointer->bms_can_buf[1] == 0x31) { Bmspointer->ack_to_bms = true; Bmspointer->source_id = source_id; } break; case 0X02: if(Bmspointer->recv_mul_freme_complete == true) { memcpy(&Bmspointer->vk_bms2.voltage, &Bmspointer->bms_can_buf[2], sizeof(vkbms2)); Bmspointer->recv_mul_freme_complete = false; } break; case 0X03: if(Bmspointer->recv_mul_freme_complete == true) { memcpy(&Bmspointer->vk_bms3.bms_company_info, &Bmspointer->bms_can_buf[2], sizeof(vkbms3)); Bmspointer->recv_mul_freme_complete = false; Bmspointer->get_bms3_ack = true; } break; case 0X04: memcpy(&Bmspointer->vk_bms4.capacity, &Bmspointer->bms_can_buf[0], sizeof(vkbms4)); Bmspointer->recv_mul_freme_complete = false; Bmspointer->get_bms4_ack = true; break; case 0X05: if(Bmspointer->recv_mul_freme_complete == true) { memcpy(&Bmspointer->vk_bms5.health_percent, &Bmspointer->bms_can_buf[2], sizeof(vkbms5)); Bmspointer->recv_mul_freme_complete = false; Bmspointer->get_bms5_ack = true; } break; //秘钥是否匹配 case 0x07: start_msg.key_to_bms = false; if(Bmspointer->bms_can_buf[0] == 0) { start_msg.mos_status = true; start_msg.Id_content = 1; } else { start_msg.Id_content = 2; } start_msg.Id = 3; start_msg.key_info_checking = true; break; case 0x08: start_msg.Id = 4; start_msg.Id_content = Bmspointer->bms_can_buf[0]; start_msg.key_info_checking = true; break; default: break; } } /**************************************************************************************/ /************************************tattu*******************************************/ #pragma pack(1) typedef struct { unsigned char canid_prio :5; unsigned short canid_msgid :16; unsigned char canid_som :1; unsigned char canid_srcid :7; /*unsigned char canid_desid:7; unsigned char canid_rnr:1;*/ }_TATTU_CANID; #pragma pack() _TATTU_DEVICE tattu_device1 = {.Tattu_Link.connect_status = COMP_NOEXIST}, tattu_device2 = {.Tattu_Link.connect_status = COMP_NOEXIST}; void TattuCanRecvHookFunction(uint32_t ttuCanID, uint8_t data[], uint8_t len) { //获取数据中的最后一位 _TATTU_DEVICE *taptr = NULL; uint8_t can_msgid = 0; can_msgid = ttuCanID & 0x7f; if(can_msgid == 0x16) { taptr = &tattu_device1; } else { taptr = &tattu_device2; } memcpy(&taptr->ttu_tailbyte, &data[len - 1], sizeof(uint8_t)); //找到开头 if(taptr->ttu_tailbyte.tail_start == 1){ taptr->Tattu_recv_index = 0; taptr->Tattu_get_s = true; } //溢出检测 if(taptr->Tattu_recv_index + len > TATTU_MAXLEN) { memset(taptr->Tattu_recv_buf,0,taptr->Tattu_recv_index); taptr->Tattu_recv_index = 0; taptr->Tattu_get_s = false; } //获取到正确的开始位则接收数据 if(taptr->Tattu_get_s == true){ //复制有效数据,最后一个字节不是有效数据 memcpy(&taptr->Tattu_recv_buf[taptr->Tattu_recv_index], data, len-1); taptr->Tattu_recv_index += (len-1); } //找到结尾,开始解析 if(taptr->Tattu_get_s == true && taptr->ttu_tailbyte.tail_end == 1) { taptr->Tattu_get_s = false; taptr->Tattu_Link.connect_status = COMP_NORMAL; //更新电池数据到来时间 taptr->Tattu_Link.recv_time = HAL_GetTick(); //如果是单帧完整数据 if(taptr->ttu_tailbyte.tail_start == 1 || taptr->Tattu_recv_index <= 7) { //单帧数据不需要校验 } //多帧拼包 else { //CRC校验,验证通过,暂不开启 CCITT_CRC16Init(&taptr->Tattu_recv_buf[2],taptr->Tattu_recv_index-2); if(CCITT_CRC16 == (taptr->Tattu_recv_buf[0] + (taptr->Tattu_recv_buf[1]<<8))) { //避免电池单方面增加协议造成溢出,格式电池12s跟14s兼容有问题,飞控自己做处理 //后两个字节是自己添加的用来识别电池串数 if(taptr->Tattu_recv_index-2 <= (sizeof(_TATTU_INFO)-2)) { //stm32为小段模式,TATTU发送过来的数据为小端模式,可直接使用memcpy //12S if(taptr->Tattu_recv_index-2 == (sizeof(_TATTU_INFO)-2-4-16)) { taptr->ttu_inf.tattu_cnum = 12; //前12s信息 memcpy(&taptr->ttu_inf,&taptr->Tattu_recv_buf[2],40); //后边信息 memcpy(&taptr->ttu_inf.tattu_descapa,&taptr->Tattu_recv_buf[40+2],8); } //添加序列号后的12s else if(taptr->Tattu_recv_index-2 == (sizeof(_TATTU_INFO)-2-4)) { taptr->ttu_inf.tattu_cnum = 12; //前12s信息 memcpy(&taptr->ttu_inf,&taptr->Tattu_recv_buf[2],40); //后边信息 memcpy(&taptr->ttu_inf.tattu_descapa,&taptr->Tattu_recv_buf[40+2],24); } //14s else if(taptr->Tattu_recv_index-2 == (sizeof(_TATTU_INFO)-2-16) || taptr->Tattu_recv_index-2 == (sizeof(_TATTU_INFO)-2)) { taptr->ttu_inf.tattu_cnum = 14; //14s信息 memcpy(&taptr->ttu_inf,&taptr->Tattu_recv_buf[2],taptr->Tattu_recv_index-2); } }else{ //清空电池信息数据 memset(&taptr->ttu_inf, 0, sizeof(_TATTU_INFO)); } } } //清理buff memset(taptr->Tattu_recv_buf,0,taptr->Tattu_recv_index); //包数完整重新计数 taptr->Tattu_recv_index = 0; } } /* 格氏电池的CRC校验 */ #define CRC_CCITT_INIT 0xFFFF #define CRC_CCITT_POLY 0x1021U uint16_t CCITT_CRC16 = 0; void CCITT_CRC16Init(uint8_t const *bytes, uint16_t len) { CCITT_CRC16 = CRC_CCITT_INIT; CCITT_CRC_ARRAY(bytes, len); } void CCITT_CRCStep(uint8_t byte) { uint32_t j; CCITT_CRC16 ^= ((uint16_t)byte << 8); for (j = 0; j < 8; j++) { CCITT_CRC16=(CCITT_CRC16 & 0x8000U)?((CCITT_CRC16 << 1) ^ CRC_CCITT_POLY):(CCITT_CRC16 << 1); } } void CCITT_CRC_ARRAY(uint8_t const * bytes, uint16_t len) { while (len--) CCITT_CRCStep(*bytes++); } /**************************************************************************************/ Vkbms_Device Device1 = {.Vkbms_Link.connect_status = COMP_NOEXIST}; Vkbms_Device Device2 = {.Vkbms_Link.connect_status = COMP_NOEXIST}; uint8_t bms_group_num = 0; //电池组数 struct BMS_DATA bms_data = {.bms_ss = 0xFFFF}, bms_data2 = {.bms_ss = 0xFFFF}; /** * @file update_bms_data * @brief 更新电池信息 * @param none * @details * @author Zhang Sir **/ void update_bms_data( void ) { //正方电池 Check_dev_link(&okcell_device1.Okcell_Link,5000,(char *)&okcell_device1.okcell_inf,sizeof(_CELL_INF)); Check_dev_link(&okcell_device2.Okcell_Link,5000,(char *)&okcell_device2.okcell_inf,sizeof(_CELL_INF)); //格式电池 Check_dev_link(&tattu_device1.Tattu_Link,5000,(char *)&tattu_device1.ttu_inf,sizeof(_TATTU_INFO)); Check_dev_link(&tattu_device2.Tattu_Link,5000,(char *)&tattu_device2.ttu_inf,sizeof(_TATTU_INFO)); //海盈电池 Check_dev_link(&Herewin_Link,5000,(char *)&herewin_info,sizeof(herewin_bms)); //VK电池 Check_dev_link(&Device1.Vkbms_Link,5000,(char *)&Device1,sizeof(Vkbms_Device)); Check_dev_link(&Device2.Vkbms_Link,5000,(char *)&Device2,sizeof(Vkbms_Device)); if ( okcell_device1.Okcell_Link.connect_status == COMP_NORMAL || okcell_device2.Okcell_Link.connect_status == COMP_NORMAL ) { Dev.Bms_Link.connect_status = COMP_NORMAL; //第一组电池 if ( okcell_device1.Okcell_Link.connect_status == COMP_NORMAL ) { bms_data.bms_cycle = okcell_device1.okcell_inf.cell_D3.cell_d3[4]; if(okcell_device1.okcell_inf.cell_D0.cell_d0[6] >= 18) //正方超18S电池10mv发送 { bms_data.bms_volt = okcell_device1.okcell_inf.cell_D0.cell_d0[0]; } else { bms_data.bms_volt = okcell_device1.okcell_inf.cell_D0.cell_d0[0] / 10; } bms_data.bms_temp = okcell_device1.okcell_inf.cell_D0.cell_d0[2]; bms_data.bms_vs = okcell_device1.okcell_inf.cell_D0.cell_d0[3]; //正方电池只关心飞控对接异常不让解锁,不关心异常5 bms_data.bms_ss = ( ( okcell_device1.okcell_inf.cell_D0.cell_d0[5] >> 8 ) != 5 ) ? ( okcell_device1.okcell_inf.cell_D0.cell_d0[5] >> 8 ) : 0; bms_data.bms_num = okcell_device1.okcell_inf.cell_D0.cell_d0[6]; bms_data.bms_v1 = okcell_device1.okcell_inf.cell_D0.cell_d0[7]; bms_data.bms_v2 = okcell_device1.okcell_inf.cell_D0.cell_d0[8]; bms_data.bms_v3 = okcell_device1.okcell_inf.cell_D0.cell_d0[9]; bms_data.bms_v4 = okcell_device1.okcell_inf.cell_D0.cell_d0[10]; bms_data.bms_v5 = okcell_device1.okcell_inf.cell_D0.cell_d0[11]; bms_data.bms_v6 = okcell_device1.okcell_inf.cell_D0.cell_d0[12]; bms_data.bms_v7 = okcell_device1.okcell_inf.cell_D0.cell_d0[13]; bms_data.bms_v8 = okcell_device1.okcell_inf.cell_D0.cell_d0[14]; bms_data.bms_v9 = okcell_device1.okcell_inf.cell_D0.cell_d0[15]; bms_data.bms_v10 = okcell_device1.okcell_inf.cell_D0.cell_d0[16]; bms_data.bms_v11 = okcell_device1.okcell_inf.cell_D0.cell_d0[17]; bms_data.bms_v12 = okcell_device1.okcell_inf.cell_D0.cell_d0[18]; bms_data.bms_v13 = okcell_device1.okcell_inf.cell_D0.cell_d0[19]; bms_data.bms_v14 = okcell_device1.okcell_inf.cell_D0.cell_d0[20]; bms_data.bms_v15 = okcell_device1.okcell_inf.cell_D0.cell_d0[21]; bms_data.bms_v16 = okcell_device1.okcell_inf.cell_D0.cell_d0[22]; bms_data.bms_v17 = okcell_device1.okcell_inf.cell_D0.cell_d0[23]; bms_data.bms_v18 = okcell_device1.okcell_inf.cell_D0.cell_d0[24]; bms_data.bms_v19 = okcell_device1.okcell_inf.cell_D0.cell_d0[25]; bms_data.bms_v20 = okcell_device1.okcell_inf.cell_D0.cell_d0[26]; bms_data.bms_v21 = okcell_device1.okcell_inf.cell_D0.cell_d0[27]; bms_data.bms_v22 = okcell_device1.okcell_inf.cell_D0.cell_d0[28]; bms_data.bms_v23 = okcell_device1.okcell_inf.cell_D0.cell_d0[29]; bms_data.bms_v24 = okcell_device1.okcell_inf.cell_D0.cell_d0[30]; bms_data.bms_v25 = okcell_device1.okcell_inf.cell_D0.cell_d0[31]; bms_data.bms_v26 = okcell_device1.okcell_inf.cell_D0.cell_d0[32]; bms_data.bms_ids[0] = okcell_device1.okcell_inf.cell_P3.cell_p3[0]; bms_data.bms_ids[1] = okcell_device1.okcell_inf.cell_P3.cell_p3[1]; for(int i = 1; i< 11; i++){ // bms_data.bms_ids[2*i] = ((okcell_device1.okcell_inf.cell_P3.cell_p3[2 + i] >> 4) & 0xf) + '0'; // bms_data.bms_ids[2*i+1] = (okcell_device1.okcell_inf.cell_P3.cell_p3[2 + i] & 0xf )+ '0'; bms_data.bms_ids[2*i] = ((okcell_device1.okcell_inf.cell_P3.cell_p3[1 + i] >> 4) & 0xf) + '0'; bms_data.bms_ids[2*i+1] = (okcell_device1.okcell_inf.cell_P3.cell_p3[1 + i] & 0xf )+ '0'; } //memcpy( bms_data.bms_ids, "okcell", 6 ); bms_data.bms_ac = okcell_device1.okcell_inf.cell_D0.cell_d0[1]; bms_data.serial_num = FAC_OKCELL; //注册 if(StrArrayNull( &bms_data.bms_ids[0], sizeof( bms_data.bms_ids ) ) == false && dev_bms1.regist.sn == false) regist_dev_info(&dev_bms1,DEVICE_BMS1,false,(char *)bms_data.bms_ids,32,NULL,0,NULL,0,"okcell1",8); } else { memset( &bms_data, 0, sizeof( bms_data ) ); } //第二组电池 if ( okcell_device2.Okcell_Link.connect_status == COMP_NORMAL ) { bms_data2.bms_cycle = okcell_device2.okcell_inf.cell_D3.cell_d3[4]; if(okcell_device2.okcell_inf.cell_D0.cell_d0[6] >= 18) { bms_data2.bms_volt = okcell_device2.okcell_inf.cell_D0.cell_d0[0]; } else { bms_data2.bms_volt = okcell_device2.okcell_inf.cell_D0.cell_d0[0] / 10; } bms_data2.bms_temp = okcell_device2.okcell_inf.cell_D0.cell_d0[2]; bms_data2.bms_vs = okcell_device2.okcell_inf.cell_D0.cell_d0[3]; //正方电池只关心飞控对接异常不让解锁,不关心异常5 bms_data2.bms_ss = ( ( okcell_device2.okcell_inf.cell_D0.cell_d0[5] >> 8 ) != 5 ) ? ( okcell_device2.okcell_inf.cell_D0.cell_d0[5] >> 8 ) : 0; bms_data2.bms_num = okcell_device2.okcell_inf.cell_D0.cell_d0[6]; bms_data2.bms_v1 = okcell_device2.okcell_inf.cell_D0.cell_d0[7]; bms_data2.bms_v2 = okcell_device2.okcell_inf.cell_D0.cell_d0[8]; bms_data2.bms_v3 = okcell_device2.okcell_inf.cell_D0.cell_d0[9]; bms_data2.bms_v4 = okcell_device2.okcell_inf.cell_D0.cell_d0[10]; bms_data2.bms_v5 = okcell_device2.okcell_inf.cell_D0.cell_d0[11]; bms_data2.bms_v6 = okcell_device2.okcell_inf.cell_D0.cell_d0[12]; bms_data2.bms_v7 = okcell_device2.okcell_inf.cell_D0.cell_d0[13]; bms_data2.bms_v8 = okcell_device2.okcell_inf.cell_D0.cell_d0[14]; bms_data2.bms_v9 = okcell_device2.okcell_inf.cell_D0.cell_d0[15]; bms_data2.bms_v10 = okcell_device2.okcell_inf.cell_D0.cell_d0[16]; bms_data2.bms_v11 = okcell_device2.okcell_inf.cell_D0.cell_d0[17]; bms_data2.bms_v12 = okcell_device2.okcell_inf.cell_D0.cell_d0[18]; bms_data2.bms_v13 = okcell_device2.okcell_inf.cell_D0.cell_d0[19]; bms_data2.bms_v14 = okcell_device2.okcell_inf.cell_D0.cell_d0[20]; bms_data2.bms_v15 = okcell_device2.okcell_inf.cell_D0.cell_d0[21]; bms_data2.bms_v16 = okcell_device2.okcell_inf.cell_D0.cell_d0[22]; bms_data2.bms_v17 = okcell_device2.okcell_inf.cell_D0.cell_d0[23]; bms_data2.bms_v18 = okcell_device2.okcell_inf.cell_D0.cell_d0[24]; bms_data2.bms_v19 = okcell_device2.okcell_inf.cell_D0.cell_d0[25]; bms_data2.bms_v20 = okcell_device2.okcell_inf.cell_D0.cell_d0[26]; bms_data2.bms_v21 = okcell_device2.okcell_inf.cell_D0.cell_d0[27]; bms_data2.bms_v22 = okcell_device2.okcell_inf.cell_D0.cell_d0[28]; bms_data2.bms_v23 = okcell_device2.okcell_inf.cell_D0.cell_d0[29]; bms_data2.bms_v24 = okcell_device2.okcell_inf.cell_D0.cell_d0[30]; bms_data2.bms_v25 = okcell_device2.okcell_inf.cell_D0.cell_d0[31]; bms_data2.bms_v26 = okcell_device2.okcell_inf.cell_D0.cell_d0[32]; bms_data2.bms_ids[0] = okcell_device1.okcell_inf.cell_P3.cell_p3[0]; bms_data2.bms_ids[1] = okcell_device1.okcell_inf.cell_P3.cell_p3[1]; for(int i = 1; i< 11; i++){ bms_data2.bms_ids[2*i] = ((okcell_device2.okcell_inf.cell_P3.cell_p3[1 + i] >> 4) & 0xf) + '0'; bms_data2.bms_ids[2*i+1] = (okcell_device2.okcell_inf.cell_P3.cell_p3[1 + i] & 0xf )+ '0'; } //memcpy( bms_data2.bms_ids, "okcell2", 7 ); bms_data2.bms_ac = okcell_device2.okcell_inf.cell_D0.cell_d0[1]; bms_data2.serial_num = FAC_OKCELL; if(StrArrayNull( &bms_data2.bms_ids[0], sizeof( bms_data2.bms_ids ) ) == false && dev_bms2.regist.sn == false) regist_dev_info(&dev_bms2,DEVICE_BMS2,false,(char *)bms_data2.bms_ids,32,NULL,0,NULL,0,"okcell2",8); } else { memset( &bms_data2, 0, sizeof( bms_data2 ) ); } } else if(tattu_device1.Tattu_Link.connect_status == COMP_NORMAL || tattu_device2.Tattu_Link.connect_status == COMP_NORMAL) { Dev.Bms_Link.connect_status = COMP_NORMAL; if(tattu_device1.Tattu_Link.connect_status == COMP_NORMAL) { group_num = 1; bms_data.bms_cycle = tattu_device1.ttu_inf.tattu_cycle; bms_data.bms_volt = tattu_device1.ttu_inf.tattu_volt /10; bms_data.bms_temp = tattu_device1.ttu_inf.tattu_temp * 10; bms_data.bms_vs = tattu_device1.ttu_inf.tattu_perc; bms_data.bms_ss = 0;//ttu_inf.def_info[24] & 0xc00;//格式电池只关心部分报警不让解锁 bms_data.bms_num = tattu_device1.ttu_inf.tattu_cnum; bms_data.bms_v1 = tattu_device1.ttu_inf.tattu_v1; bms_data.bms_v2 = tattu_device1.ttu_inf.tattu_v2; bms_data.bms_v3 = tattu_device1.ttu_inf.tattu_v3; bms_data.bms_v4 = tattu_device1.ttu_inf.tattu_v4; bms_data.bms_v5 = tattu_device1.ttu_inf.tattu_v5; bms_data.bms_v6 = tattu_device1.ttu_inf.tattu_v6; bms_data.bms_v7 = tattu_device1.ttu_inf.tattu_v7; bms_data.bms_v8 = tattu_device1.ttu_inf.tattu_v8; bms_data.bms_v9 = tattu_device1.ttu_inf.tattu_v9; bms_data.bms_v10 = tattu_device1.ttu_inf.tattu_v10; bms_data.bms_v11 = tattu_device1.ttu_inf.tattu_v11; bms_data.bms_v12 = tattu_device1.ttu_inf.tattu_v12; bms_data.bms_v13 = tattu_device1.ttu_inf.tattu_v13; bms_data.bms_v14 = tattu_device1.ttu_inf.tattu_v14; memcpy(bms_data.bms_ids,&tattu_device1.ttu_inf.tuattu_id[0],16); //memcpy(bms_data.bms_ids, "Tattu1", 6); bms_data.bms_ac = tattu_device1.ttu_inf.tattu_cur; bms_data.serial_num = FAC_TATTU; if(StrArrayNull( &bms_data.bms_ids[0], sizeof( bms_data.bms_ids ) ) == false && dev_bms1.regist.sn == false) regist_dev_info(&dev_bms1,DEVICE_BMS1,false,(char *)bms_data.bms_ids,16,NULL,0,NULL,0,"tattu1",7); } else { memset( &bms_data, 0, sizeof(bms_data)); } if(tattu_device2.Tattu_Link.connect_status == COMP_NORMAL) { group_num = 2; bms_data2.bms_cycle = tattu_device2.ttu_inf.tattu_cycle; bms_data2.bms_volt = tattu_device2.ttu_inf.tattu_volt / 10; bms_data2.bms_temp = tattu_device2.ttu_inf.tattu_temp * 10; bms_data2.bms_vs = tattu_device2.ttu_inf.tattu_perc; bms_data2.bms_ss = 0;//ttu_inf.def_info[24] & 0xc00;//格式电池只关心部分报警不让解锁 bms_data2.bms_num = tattu_device2.ttu_inf.tattu_cnum; bms_data2.bms_v1 = tattu_device2.ttu_inf.tattu_v1; bms_data2.bms_v2 = tattu_device2.ttu_inf.tattu_v2; bms_data2.bms_v3 = tattu_device2.ttu_inf.tattu_v3; bms_data2.bms_v4 = tattu_device2.ttu_inf.tattu_v4; bms_data2.bms_v5 = tattu_device2.ttu_inf.tattu_v5; bms_data2.bms_v6 = tattu_device2.ttu_inf.tattu_v6; bms_data2.bms_v7 = tattu_device2.ttu_inf.tattu_v7; bms_data2.bms_v8 = tattu_device2.ttu_inf.tattu_v8; bms_data2.bms_v9 = tattu_device2.ttu_inf.tattu_v9; bms_data2.bms_v10 = tattu_device2.ttu_inf.tattu_v10; bms_data2.bms_v11 = tattu_device2.ttu_inf.tattu_v11; bms_data2.bms_v12 = tattu_device2.ttu_inf.tattu_v12; bms_data2.bms_v13 = tattu_device2.ttu_inf.tattu_v13; bms_data2.bms_v14 = tattu_device2.ttu_inf.tattu_v14; memcpy(bms_data2.bms_ids,&tattu_device2.ttu_inf.tuattu_id[0],16); //memcpy(bms_data2.bms_ids, "Tattu2", 6); bms_data2.bms_ac = tattu_device2.ttu_inf.tattu_cur; bms_data2.serial_num = FAC_TATTU; if(StrArrayNull( &bms_data2.bms_ids[0], sizeof( bms_data2.bms_ids ) ) == false && dev_bms2.regist.sn == false) regist_dev_info(&dev_bms2,DEVICE_BMS2,false,(char *)bms_data2.bms_ids,16,NULL,0,NULL,0,"tattu2",7); } else { memset( &bms_data2, 0, sizeof( bms_data2 ) ); } } else if ( Herewin_Link.connect_status == COMP_NORMAL ) { Dev.Bms_Link.connect_status = COMP_NORMAL; group_num = 1; bms_data.bms_cycle = herewin_info.circulation_num; bms_data.bms_volt = herewin_info.total_vol; if(herewin_info.get_temp_flag == true) bms_data.bms_temp = ( ( herewin_info.battery_temp[0] + herewin_info.battery_temp[1] + herewin_info.battery_temp[2] ) / 3 - 40 ) * 10; bms_data.bms_vs = herewin_info.SOC_info; bms_data.bms_ss = herewin_info.warn_info; bms_data.bms_num = herewin_info.battery_num; bms_data.bms_v1 = herewin_info.battery_vol[0]; bms_data.bms_v2 = herewin_info.battery_vol[1]; bms_data.bms_v3 = herewin_info.battery_vol[2]; bms_data.bms_v4 = herewin_info.battery_vol[3]; bms_data.bms_v5 = herewin_info.battery_vol[4]; bms_data.bms_v6 = herewin_info.battery_vol[5]; bms_data.bms_v7 = herewin_info.battery_vol[6]; bms_data.bms_v8 = herewin_info.battery_vol[7]; bms_data.bms_v9 = herewin_info.battery_vol[8]; bms_data.bms_v10 = herewin_info.battery_vol[9]; bms_data.bms_v11 = herewin_info.battery_vol[10]; bms_data.bms_v12 = herewin_info.battery_vol[11]; bms_data.bms_v13 = herewin_info.battery_vol[12]; bms_data.bms_v14 = herewin_info.battery_vol[13]; memcpy( bms_data.bms_ids, "herewin", 7 ); bms_data.bms_ac = herewin_info.tolal_ele; bms_data.serial_num = FAC_HEREWIN; if(dev_bms1.regist.dev == false) regist_dev_info(&dev_bms1,DEVICE_BMS1,false,NULL,0,NULL,0,NULL,0,"herewin",8); } else if(Device1.Vkbms_Link.connect_status == COMP_NORMAL || Device2.Vkbms_Link.connect_status == COMP_NORMAL) { Dev.Bms_Link.connect_status = COMP_NORMAL; //第一组电池 if ( Device1.Vkbms_Link.connect_status == COMP_NORMAL ) { group_num = 1; bms_data.bms_cycle = Device1.vk_bms5.circulation_time; bms_data.bms_volt = Device1.vk_bms2.voltage; bms_data.bms_temp = Device1.vk_bms2.tempture; bms_data.bms_vs = Device1.vk_bms2.persent / 10; bms_data.bms_ss = Device1.vk_bms2.warn_flag; bms_data.bms_num = Device1.vk_bms2.bms_num; memcpy(&bms_data.bms_v1,&Device1.vk_bms2.bms_v1,26 * 2); memcpy(&bms_data.bms_ids[0],&Device1.vk_bms3.bms_id[0],20); // bms_data.bms_ids[0] = Device1.vk_bms3.bms_id[0]; // bms_data.bms_ids[1] = Device1.vk_bms3.bms_id[1]; // for(int i = 1; i< 11; i++){ // bms_data.bms_ids[2*i] = ((Device1.vk_bms3.bms_id[1 + i] >> 4) & 0xf) + '0'; // bms_data.bms_ids[2*i+1] = (Device1.vk_bms3.bms_id[1 + i] & 0xf )+ '0'; // } bms_data.bms_ac = (short)(Device1.vk_bms2.current / 10); bms_data.serial_num = FAC_VK_BMS; // if( Device1.vk_bms3.bms_type_info[0] == 'S' && Device1.vk_bms3.bms_type_info[0] == 'H' // && Device1.vk_bms3.bms_type_info[0] == 'A' && Device1.vk_bms3.bms_type_info[0] == '1') // { // bms_data.serial_num = 11; //??? // } //厂家还没加 if(StrArrayNull( &bms_data.bms_ids[0], sizeof( bms_data.bms_ids ) ) == false && dev_bms1.regist.sn == false) regist_dev_info(&dev_bms1,DEVICE_BMS1,false,(char *)bms_data.bms_ids,32,NULL,0,NULL,0,"vk",3); } else { memset( &Device1, 0, sizeof( Device1 ) ); } //第二组电池 if ( Device2.Vkbms_Link.connect_status == COMP_NORMAL ) { group_num = 2; bms_data2.bms_cycle = Device2.vk_bms5.circulation_time; bms_data2.bms_volt = Device2.vk_bms2.voltage; bms_data2.bms_temp = Device2.vk_bms2.tempture; bms_data2.bms_vs = Device2.vk_bms2.persent / 10; bms_data2.bms_ss = Device2.vk_bms2.warn_flag; bms_data2.bms_num = Device2.vk_bms2.bms_num; memcpy(&bms_data2.bms_v1,&Device2.vk_bms2.bms_v1,26 * 2); memcpy(&bms_data2.bms_ids[0],&Device2.vk_bms3.bms_id[0],20); bms_data2.bms_ac = (short)(Device2.vk_bms2.current / 10); bms_data2.serial_num = FAC_VK_BMS; // if( Device2.vk_bms3.bms_type_info[0] == 'S' && Device2.vk_bms3.bms_type_info[0] == 'H' // && Device2.vk_bms3.bms_type_info[0] == 'A' && Device2.vk_bms3.bms_type_info[0] == '1') // { // bms_data2.serial_num = 11; //??? // } if(StrArrayNull( &bms_data2.bms_ids[0], sizeof( bms_data2.bms_ids ) ) == false && dev_bms2.regist.sn == false) regist_dev_info(&dev_bms2,DEVICE_BMS2,false,(char *)bms_data2.bms_ids,32,NULL,0,NULL,0,"vk",3); } else { memset( &bms_data2, 0, sizeof( bms_data2 ) ); } } else { if ( Dev.Bms_Link.connect_status == COMP_NORMAL ) { Dev.Bms_Link.connect_status = COMP_LOST; //memset(&bms_data, 0, sizeof(bms_data)); //状态未置异常 bms_data.bms_ss = 0xFFFF; } } } /** * @file bms_function * @brief 智能电池检测函数 * @param none * @details * @author Zhang Sir **/ void bms_function() { static uint32_t bms_time = 0; static uint32_t bms_5hz_time = 0; if(Check_Timer_Ready(&bms_time,_10_HZ_)) { update_bms_data(); send_msg_to_VKbms(); } if(Check_Timer_Ready(&bms_5hz_time,_5_HZ_)) { //给智能电池发送上电信息 //send_msg_to_okcell(); send_msg_to_herewin(); } }