soft_herewin.c 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. #include "soft_herewin.h"
  2. #include "string.h"
  3. #include "crc.h"
  4. #include "soft_can.h"
  5. #include "common.h"
  6. herewin_bms herewin_info;
  7. Connect_check Herewin_Link;
  8. #pragma pack(1)
  9. typedef struct
  10. {
  11. uint8_t herewin_buf[64]; //临时buf
  12. uint8_t message_num; //报文序号
  13. uint8_t message_total;//总帧数
  14. uint16_t byte_num; //有效字节数
  15. int last_frame_num; //最后一包有效字节数
  16. uint16_t crc; //和校验
  17. uint8_t i;
  18. bool crc_is_ok; //校验通过
  19. }herewin_can_info;
  20. #pragma pack()
  21. herewin_can_info can_info;
  22. void HerewinCanRecvHookFunction(uint32_t cellCanID, uint8_t data[], uint8_t len)
  23. {
  24. Herewin_Link.recv_time = HAL_GetTick();
  25. Herewin_Link.connect_status = COMP_NORMAL;
  26. uint8_t i = 0;
  27. uint8_t canid_pf = (cellCanID >> 16) & 0xff;
  28. switch (canid_pf)
  29. {
  30. //定值查询包
  31. case 0x81:
  32. if((data[0] == 8 )&& (0x80 == data[2]))
  33. {
  34. herewin_info.battery_num = data[4];
  35. }
  36. break;
  37. case 0x83:
  38. herewin_info.get_temp_flag = true;
  39. //电芯温度传感器只有三个,取前三个字节,传给APP取平均值
  40. memcpy(&herewin_info.battery_temp[0],&data[0],1);
  41. memcpy(&herewin_info.battery_temp[1],&data[1],1);
  42. memcpy(&herewin_info.battery_temp[2],&data[2],1);
  43. break;
  44. //单体电压
  45. case 0x85:
  46. can_info.message_num = data[0];
  47. //第一包
  48. if(can_info.message_num == 1)
  49. {
  50. memset(&can_info,0,sizeof(can_info));
  51. can_info.byte_num = data[2] + data[3] * 256;
  52. can_info.message_total = data[1];
  53. //算出最后一包的有效字节数
  54. can_info.last_frame_num = can_info.byte_num - 4 -(can_info.message_total - 2) * 7;
  55. memcpy(&can_info.herewin_buf[0],&data[4],4);
  56. for(i = 0;i < 4;i++)
  57. {
  58. can_info.crc += can_info.herewin_buf[i];
  59. }
  60. can_info.i += 4;
  61. }
  62. //最后一包 协议校验码是最后发,12S的电池校验会单独占一个字节发送
  63. //14s
  64. else if(can_info.message_num == can_info.message_total && can_info.last_frame_num <= 5
  65. && can_info.last_frame_num > 0 )
  66. {
  67. memcpy(&can_info.herewin_buf[can_info.i],&data[1],can_info.last_frame_num);
  68. for(i = 0;i < can_info.last_frame_num;i++)
  69. {
  70. can_info.crc += can_info.herewin_buf[can_info.i + i];
  71. }
  72. //校验
  73. if(can_info.crc == data[ 1 + can_info.last_frame_num] + 256 * data[ 2 + can_info.last_frame_num])
  74. {
  75. memcpy(&herewin_info.battery_vol[0],&can_info.herewin_buf[0],can_info.byte_num);
  76. }
  77. memset(&can_info,0,sizeof(can_info));
  78. }
  79. //12s电池 最后一包有效字节-1
  80. else if(can_info.message_num == can_info.message_total && can_info.last_frame_num <= 0 )
  81. {
  82. //最后一包只有1字节校验
  83. if(can_info.last_frame_num == -1)
  84. {
  85. memcpy(&can_info.herewin_buf[can_info.i],&data[1],1);
  86. can_info.crc -= can_info.herewin_buf[can_info.i - 1];
  87. //校验
  88. if(can_info.crc == can_info.herewin_buf[can_info.i - 1] + 256 * can_info.herewin_buf[can_info.i])
  89. {
  90. memcpy(&herewin_info.battery_vol[0],&can_info.herewin_buf[0],can_info.byte_num);
  91. }
  92. }
  93. //最后一包只有两字节校验
  94. else if(can_info.last_frame_num == 0)
  95. {
  96. memcpy(&can_info.herewin_buf[can_info.i],&data[1],2);
  97. //校验
  98. if(can_info.crc == can_info.herewin_buf[can_info.i] + 256 * can_info.herewin_buf[can_info.i + 1])
  99. {
  100. memcpy(&herewin_info.battery_vol[0],&can_info.herewin_buf[0],can_info.byte_num);
  101. }
  102. }
  103. memset(&can_info,0,sizeof(can_info));
  104. }
  105. else
  106. {
  107. memcpy(&can_info.herewin_buf[can_info.i],&data[1],7);
  108. for(i = 0;i < 7;i++)
  109. {
  110. can_info.crc += can_info.herewin_buf[can_info.i + i];
  111. }
  112. can_info.i += 7;
  113. }
  114. break;
  115. //电池循环次数查询
  116. case 0x87:
  117. memcpy(&herewin_info.circulation_num,&data[0],2);
  118. break;
  119. //充电请求
  120. case 0x22:
  121. memcpy(&herewin_info.re_vol,&data[0],2);
  122. memcpy(&herewin_info.re_ele,&data[2],2);
  123. memcpy(&herewin_info.max_vol,&data[4],2);
  124. memcpy(&herewin_info.power_status,&data[6],2);
  125. break;
  126. //告警信息
  127. case 0x24:
  128. memcpy(&herewin_info.alarm_info,&data[0],2);
  129. memcpy(&herewin_info.warn_info,&data[2],2);
  130. break;
  131. //电流 电压信息
  132. case 0x26:
  133. memcpy(&herewin_info.total_vol,&data[0],2);
  134. memcpy(&herewin_info.tolal_ele,&data[2],2);
  135. memcpy(&herewin_info.SOC_info,&data[4],1);
  136. memcpy(&herewin_info.SOH_info,&data[5],1);
  137. memcpy(&herewin_info.SOP_info,&data[6],2);
  138. break;
  139. default:
  140. break;
  141. }
  142. }
  143. /**
  144. * @brief 给海盈发送数据信息
  145. */
  146. //海盈电池收不到心跳包20分后停止主动发送数据 2000ms周期给海盈电池发送心跳包
  147. void send_msg_to_herewin(void)
  148. {
  149. static uint32_t herewin_heart_time = 0;
  150. static uint32_t herewin_vol_time = 0;
  151. static uint8_t heart_num_count = 0;
  152. if(Herewin_Link.connect_status == COMP_NORMAL)
  153. {
  154. //2000ms发送心跳包
  155. if(HAL_GetTick() - herewin_heart_time > 2000)
  156. {
  157. uint8_t heart_buf[8] = {0x00,0x00,0x00,0x01,
  158. 0x00,0x00,0x00,0x01};
  159. can_send_msg_normal(heart_buf, 8, HEREWIN_HEART_ID);
  160. herewin_heart_time = HAL_GetTick();
  161. }
  162. //1000ms发送单体电压请求 和单体温度请求 发送5次电芯个数
  163. if(HAL_GetTick() - herewin_vol_time > 1000)
  164. {
  165. uint8_t herewin_num = 8;
  166. can_send_msg_normal(0, 0, HEREWIN_VOL_ID);
  167. can_send_msg_normal(0, 0, HEREWIN_TEM_ID);
  168. //请求5次电芯个数 5次循环次数
  169. can_send_msg_normal(&herewin_num, 1, HEREWIN_SEARCH_ID);
  170. can_send_msg_normal(0, 0, HEREWIN_CIRCULATION_ID);
  171. herewin_vol_time = HAL_GetTick();
  172. }
  173. }
  174. else
  175. {
  176. //上电时先发送5次心跳包 防止电池休眠
  177. if(HAL_GetTick() - herewin_heart_time > 2000 && heart_num_count > 0)
  178. {
  179. uint8_t heart_buf[8] = {0x00,0x00,0x00,0x01,
  180. 0x00,0x00,0x00,0x01};
  181. can_send_msg_normal(heart_buf, 8, HEREWIN_HEART_ID);
  182. herewin_heart_time = HAL_GetTick();
  183. heart_num_count--;
  184. }
  185. }
  186. }