#include "soft_herewin.h" #include "string.h" #include "crc.h" #include "soft_can.h" #include "common.h" herewin_bms herewin_info; Connect_check Herewin_Link; #pragma pack(1) typedef struct { uint8_t herewin_buf[64]; //临时buf uint8_t message_num; //报文序号 uint8_t message_total;//总帧数 uint16_t byte_num; //有效字节数 int last_frame_num; //最后一包有效字节数 uint16_t crc; //和校验 uint8_t i; bool crc_is_ok; //校验通过 }herewin_can_info; #pragma pack() 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; } } /** * @brief 给海盈发送数据信息 */ //海盈电池收不到心跳包20分后停止主动发送数据 2000ms周期给海盈电池发送心跳包 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_normal(heart_buf, 8, HEREWIN_HEART_ID); herewin_heart_time = HAL_GetTick(); } //1000ms发送单体电压请求 和单体温度请求 发送5次电芯个数 if(HAL_GetTick() - herewin_vol_time > 1000) { uint8_t herewin_num = 8; can_send_msg_normal(0, 0, HEREWIN_VOL_ID); can_send_msg_normal(0, 0, HEREWIN_TEM_ID); //请求5次电芯个数 5次循环次数 can_send_msg_normal(&herewin_num, 1, HEREWIN_SEARCH_ID); can_send_msg_normal(0, 0, HEREWIN_CIRCULATION_ID); 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_normal(heart_buf, 8, HEREWIN_HEART_ID); herewin_heart_time = HAL_GetTick(); heart_num_count--; } } }