soft_bms.c 59 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493
  1. #include "soft_bms.h"
  2. #include "main.h"
  3. #include "soft_engine.h"
  4. #include "string.h"
  5. #include "stdio.h"
  6. #include "stdlib.h"
  7. #include "soft_crc.h"
  8. #include "common.h"
  9. #include "soft_device.h"
  10. #include "usart_data_handle.h"
  11. #include "soft_version.h"
  12. #include "soft_adc.h"
  13. #include "soft_can.h"
  14. #include "crc.h"
  15. #include "soft_timer.h"
  16. /************************************herewin******************************************/
  17. /**
  18. * @file HerewinCanRecvHookFunction
  19. * @brief herewin bms 解析
  20. * @param none
  21. * @details
  22. * @author Zhang Sir
  23. **/
  24. herewin_bms herewin_info;
  25. Connect_check Herewin_Link;
  26. herewin_can_info can_info;
  27. void HerewinCanRecvHookFunction(uint32_t cellCanID, uint8_t data[], uint8_t len)
  28. {
  29. Herewin_Link.recv_time = HAL_GetTick();
  30. Herewin_Link.connect_status = COMP_NORMAL;
  31. uint8_t i = 0;
  32. uint8_t canid_pf = (cellCanID >> 16) & 0xff;
  33. switch (canid_pf)
  34. {
  35. //定值查询包
  36. case 0x81:
  37. if((data[0] == 8 )&& (0x80 == data[2]))
  38. {
  39. herewin_info.battery_num = data[4];
  40. }
  41. break;
  42. case 0x83:
  43. herewin_info.get_temp_flag = true;
  44. //电芯温度传感器只有三个,取前三个字节,传给APP取平均值
  45. memcpy(&herewin_info.battery_temp[0],&data[0],1);
  46. memcpy(&herewin_info.battery_temp[1],&data[1],1);
  47. memcpy(&herewin_info.battery_temp[2],&data[2],1);
  48. break;
  49. //单体电压
  50. case 0x85:
  51. can_info.message_num = data[0];
  52. //第一包
  53. if(can_info.message_num == 1)
  54. {
  55. memset(&can_info,0,sizeof(can_info));
  56. can_info.byte_num = data[2] + data[3] * 256;
  57. can_info.message_total = data[1];
  58. //算出最后一包的有效字节数
  59. can_info.last_frame_num = can_info.byte_num - 4 -(can_info.message_total - 2) * 7;
  60. memcpy(&can_info.herewin_buf[0],&data[4],4);
  61. for(i = 0;i < 4;i++)
  62. {
  63. can_info.crc += can_info.herewin_buf[i];
  64. }
  65. can_info.i += 4;
  66. }
  67. //最后一包 协议校验码是最后发,12S的电池校验会单独占一个字节发送
  68. //14s
  69. else if(can_info.message_num == can_info.message_total && can_info.last_frame_num <= 5
  70. && can_info.last_frame_num > 0 )
  71. {
  72. memcpy(&can_info.herewin_buf[can_info.i],&data[1],can_info.last_frame_num);
  73. for(i = 0;i < can_info.last_frame_num;i++)
  74. {
  75. can_info.crc += can_info.herewin_buf[can_info.i + i];
  76. }
  77. //校验
  78. if(can_info.crc == data[ 1 + can_info.last_frame_num] + 256 * data[ 2 + can_info.last_frame_num])
  79. {
  80. memcpy(&herewin_info.battery_vol[0],&can_info.herewin_buf[0],can_info.byte_num);
  81. }
  82. memset(&can_info,0,sizeof(can_info));
  83. }
  84. //12s电池 最后一包有效字节-1
  85. else if(can_info.message_num == can_info.message_total && can_info.last_frame_num <= 0 )
  86. {
  87. //最后一包只有1字节校验
  88. if(can_info.last_frame_num == -1)
  89. {
  90. memcpy(&can_info.herewin_buf[can_info.i],&data[1],1);
  91. can_info.crc -= can_info.herewin_buf[can_info.i - 1];
  92. //校验
  93. if(can_info.crc == can_info.herewin_buf[can_info.i - 1] + 256 * can_info.herewin_buf[can_info.i])
  94. {
  95. memcpy(&herewin_info.battery_vol[0],&can_info.herewin_buf[0],can_info.byte_num);
  96. }
  97. }
  98. //最后一包只有两字节校验
  99. else if(can_info.last_frame_num == 0)
  100. {
  101. memcpy(&can_info.herewin_buf[can_info.i],&data[1],2);
  102. //校验
  103. if(can_info.crc == can_info.herewin_buf[can_info.i] + 256 * can_info.herewin_buf[can_info.i + 1])
  104. {
  105. memcpy(&herewin_info.battery_vol[0],&can_info.herewin_buf[0],can_info.byte_num);
  106. }
  107. }
  108. memset(&can_info,0,sizeof(can_info));
  109. }
  110. else
  111. {
  112. memcpy(&can_info.herewin_buf[can_info.i],&data[1],7);
  113. for(i = 0;i < 7;i++)
  114. {
  115. can_info.crc += can_info.herewin_buf[can_info.i + i];
  116. }
  117. can_info.i += 7;
  118. }
  119. break;
  120. //电池循环次数查询
  121. case 0x87:
  122. memcpy(&herewin_info.circulation_num,&data[0],2);
  123. break;
  124. //充电请求
  125. case 0x22:
  126. memcpy(&herewin_info.re_vol,&data[0],2);
  127. memcpy(&herewin_info.re_ele,&data[2],2);
  128. memcpy(&herewin_info.max_vol,&data[4],2);
  129. memcpy(&herewin_info.power_status,&data[6],2);
  130. break;
  131. //告警信息
  132. case 0x24:
  133. memcpy(&herewin_info.alarm_info,&data[0],2);
  134. memcpy(&herewin_info.warn_info,&data[2],2);
  135. break;
  136. //电流 电压信息
  137. case 0x26:
  138. memcpy(&herewin_info.total_vol,&data[0],2);
  139. memcpy(&herewin_info.tolal_ele,&data[2],2);
  140. memcpy(&herewin_info.SOC_info,&data[4],1);
  141. memcpy(&herewin_info.SOH_info,&data[5],1);
  142. memcpy(&herewin_info.SOP_info,&data[6],2);
  143. break;
  144. default:
  145. break;
  146. }
  147. }
  148. /**
  149. * @file send_msg_to_herewin
  150. * @brief herewin 发送信息
  151. * @param none
  152. * @details 海盈电池收不到心跳包20分后停止主动发送数据 2000ms周期给海盈电池发送心跳包
  153. * @author Zhang Sir
  154. **/
  155. void send_msg_to_herewin(void)
  156. {
  157. static uint32_t herewin_heart_time = 0;
  158. static uint32_t herewin_vol_time = 0;
  159. static uint8_t heart_num_count = 0;
  160. if(Herewin_Link.connect_status == COMP_NORMAL)
  161. {
  162. //2000ms发送心跳包
  163. if(HAL_GetTick() - herewin_heart_time > 2000)
  164. {
  165. uint8_t heart_buf[8] = {0x00,0x00,0x00,0x01,
  166. 0x00,0x00,0x00,0x01};
  167. Can_Send_Msg_Func(CANID2, heart_buf, 8, HEREWIN_HEART_ID, CAN_ID_EXT);
  168. herewin_heart_time = HAL_GetTick();
  169. }
  170. //1000ms发送单体电压请求 和单体温度请求 发送5次电芯个数
  171. if(HAL_GetTick() - herewin_vol_time > 1000)
  172. {
  173. uint8_t herewin_num = 8;
  174. Can_Send_Msg_Func(CANID2, 0, 0, HEREWIN_VOL_ID, CAN_ID_EXT);
  175. Can_Send_Msg_Func(CANID2, 0, 0, HEREWIN_TEM_ID, CAN_ID_EXT);
  176. //请求5次电芯个数 5次循环次数
  177. Can_Send_Msg_Func(CANID2, &herewin_num, 1, HEREWIN_SEARCH_ID, CAN_ID_EXT);
  178. Can_Send_Msg_Func(CANID2, 0, 0, HEREWIN_CIRCULATION_ID, CAN_ID_EXT);
  179. herewin_vol_time = HAL_GetTick();
  180. }
  181. }
  182. else
  183. {
  184. //上电时先发送5次心跳包 防止电池休眠
  185. if(HAL_GetTick() - herewin_heart_time > 2000 && heart_num_count > 0)
  186. {
  187. uint8_t heart_buf[8] = {0x00,0x00,0x00,0x01,
  188. 0x00,0x00,0x00,0x01};
  189. Can_Send_Msg_Func(CANID2, heart_buf, 8, HEREWIN_HEART_ID, CAN_ID_EXT);
  190. herewin_heart_time = HAL_GetTick();
  191. heart_num_count--;
  192. }
  193. }
  194. }
  195. /**************************************************************************************/
  196. /************************************Okcell*******************************************/
  197. /**
  198. * @file update_bms_data
  199. * @brief 更新电池信息
  200. * @param none
  201. * @details
  202. * @author Zhang Sir
  203. **/
  204. uint8_t group_num = 0; //电池组数
  205. #define RESET_OKIDCODE_DELAY (3)
  206. unsigned char okcell_sha1_out[20] = {0};
  207. //结构体指针类型
  208. _OKCELL_DEVICE okcell_device1 = {.Okcell_Link.connect_status = COMP_NOEXIST,
  209. .Okcell_get_s = false,
  210. .okcell_inf.cell_D0.cell_d0[6] = 0},
  211. okcell_device2 = {.Okcell_Link.connect_status = COMP_NOEXIST,
  212. .Okcell_get_s = false,
  213. .okcell_inf.cell_D0.cell_d0[6] = 0};
  214. void OkcellCanRecvHookFunction(uint32_t cellCanID, uint8_t data[], uint8_t len)
  215. {
  216. _OKCELL_DEVICE *OKptr = NULL;
  217. //添加兼容两组电池
  218. static uint8_t OKIdCode1counts = 0,OKIdCode2counts = 0;
  219. //判断是哪个电池的ID,通过ID来区分电池。并支持飞控不断电更换电池
  220. if(cellCanID != okcell_device1.deviceCanID && cellCanID != okcell_device2.deviceCanID)
  221. {
  222. //分配给1号结构体
  223. if(OKIdCode1counts == 0){
  224. OKIdCode1counts = RESET_OKIDCODE_DELAY;
  225. OKptr = &okcell_device1;
  226. OKptr->deviceCanID = cellCanID;
  227. group_num = 1;
  228. }
  229. //分配给2号结构体
  230. else if(OKIdCode2counts == 0) {
  231. OKIdCode2counts = RESET_OKIDCODE_DELAY;
  232. OKptr = &okcell_device2;
  233. OKptr->deviceCanID = cellCanID;
  234. group_num = 2;
  235. }
  236. //不分配结构体
  237. else{
  238. OKIdCode1counts>0 ? OKIdCode1counts-- : OKIdCode1counts;
  239. OKIdCode2counts>0 ? OKIdCode2counts-- : OKIdCode2counts;
  240. }
  241. }
  242. else if(cellCanID == okcell_device1.deviceCanID)
  243. {
  244. OKIdCode1counts = RESET_OKIDCODE_DELAY;
  245. OKptr = &okcell_device1;
  246. OKptr->deviceCanID = cellCanID;
  247. }
  248. else if(cellCanID == okcell_device2.deviceCanID)
  249. {
  250. OKIdCode2counts = RESET_OKIDCODE_DELAY;
  251. OKptr = &okcell_device2;
  252. OKptr->deviceCanID = cellCanID;
  253. }
  254. //如果指针找到了存放数据的结构体
  255. if(OKptr != NULL)
  256. {
  257. //找到开头,开始接收
  258. //strncmp比较字符串,遇到'\0'会结束,所以不适合用字数组比较
  259. if(memcmp(data,"ZFKJ",4) == 0){
  260. OKptr->Okcell_recv_index = 0;
  261. OKptr->Okcell_get_s = true;
  262. }
  263. //溢出检测
  264. if(OKptr->Okcell_recv_index + len > OKCELL_MAXLEN)
  265. {
  266. memset(OKptr->Okcell_recv_buf,0,OKptr->Okcell_recv_index);
  267. OKptr->Okcell_recv_index = 0;
  268. OKptr->Okcell_get_s = false;
  269. }
  270. //接收到起始标志后开始存数组
  271. if(OKptr->Okcell_get_s == true){
  272. //复制数据
  273. memcpy(&OKptr->Okcell_recv_buf[OKptr->Okcell_recv_index], data, len);
  274. OKptr->Okcell_recv_index += len;
  275. }
  276. //找到结尾,开始解析,不能用strstr
  277. if(OKptr->Okcell_get_s == true && findStrInArray(OKptr->Okcell_recv_buf, OKptr->Okcell_recv_index, "END") != 0)
  278. {
  279. OKptr->Okcell_get_s = false;
  280. unsigned char loadflag = OKptr->Okcell_recv_buf[7];
  281. //负载标识为固定的OxBB
  282. if(loadflag == 0xBB)
  283. {
  284. unsigned char cellLoadLen = OKptr->Okcell_recv_buf[6];
  285. //避免错误数据造成的数组溢出
  286. if(cellLoadLen < OKCELL_MAXLEN-9)
  287. {
  288. unsigned int cellCheck = OKptr->Okcell_recv_buf[8+cellLoadLen]*256 + OKptr->Okcell_recv_buf[9+cellLoadLen];
  289. //校验通过,测试没通过
  290. if(((crc_ccitt(&OKptr->Okcell_recv_buf[8], cellLoadLen))&0xffff) == cellCheck)
  291. {
  292. unsigned short cellCmd = (OKptr->Okcell_recv_buf[4]<<8) + OKptr->Okcell_recv_buf[5];
  293. OKptr->Okcell_Link.connect_status = COMP_NORMAL;
  294. //用于判断电池波特率锁定,实测只要给电池发送数据,电池收到后就会锁定波特率
  295. //由于锁定波特率缺少反馈应答,5s内收到多于10包正确的数据则认为波特率锁定成功。
  296. if(OKptr->cell_bps_lock_success == false)
  297. {
  298. OKptr->recv_celldata_counts++;
  299. if(OKptr->recv_celldata_counts == 1){
  300. OKptr->recv_celldata_time = HAL_GetTick();
  301. }
  302. else if(OKptr->recv_celldata_counts >= 10)
  303. {
  304. OKptr->recv_celldata_counts = 0;
  305. uint32_t timeperiod = HAL_GetTick() - OKptr->recv_celldata_time;
  306. if(timeperiod < 5000000)
  307. {
  308. OKptr->cell_bps_lock_success = true;
  309. }
  310. }
  311. }
  312. //更新电池数据到来时间
  313. OKptr->Okcell_Link.recv_time = HAL_GetTick();
  314. switch(cellCmd)
  315. {
  316. case 0x0000:
  317. //stm32为小段模式,OKCELL发送过来的数据为大端模式,不能使用memcpy
  318. //memcpy(&cell_D0,&Okcell_recv_buf[8],cellLoadLen);
  319. //避免电池厂家私自增加协议造成的数组溢出
  320. if(cellLoadLen <= sizeof(_CELL_D0))
  321. {
  322. for(unsigned char i=0; i<cellLoadLen/2; i++)
  323. {
  324. OKptr->okcell_inf.cell_D0.cell_d0[i] = (OKptr->Okcell_recv_buf[8 + i*2] << 8) + OKptr->Okcell_recv_buf[9 + i*2];
  325. }
  326. }
  327. break;
  328. case 0x0300:
  329. //cell_inf1.cell_D3.cell_d3[4] = (Okcell_recv_buf[16] << 8) + Okcell_recv_buf[17];
  330. //避免电池厂家私自增加协议造成的数组溢出
  331. if(cellLoadLen <= sizeof(_CELL_D3))
  332. {
  333. for(unsigned char i=0; i<cellLoadLen/2; i++)
  334. {
  335. OKptr->okcell_inf.cell_D3.cell_d3[i] = (OKptr->Okcell_recv_buf[8 + i*2] << 8) + OKptr->Okcell_recv_buf[9 + i*2];
  336. }
  337. }
  338. break;
  339. case 0x8200://SHA1加密文密码查询
  340. //避免电池厂家私自增加协议造成的数组溢出
  341. if(cellLoadLen <= sizeof(_CELL_P2))
  342. {
  343. for(unsigned char i=0; i<cellLoadLen; i++)
  344. {
  345. OKptr->okcell_inf.cell_P2.cell_p2[i] = OKptr->Okcell_recv_buf[8 + i];
  346. }
  347. }
  348. if(memcmp(OKptr->okcell_inf.cell_P2.cell_p2, okcell_sha1_out, sizeof(_CELL_P2)) == 0)
  349. {
  350. //收到了正确密文
  351. OKptr->get_cellEncryption = true;
  352. }
  353. break;
  354. case 0x8300://获取电池编号
  355. OKptr->get_cellNumber = true;
  356. //避免电池厂家私自增加协议造成的数组溢出
  357. if(cellLoadLen <= sizeof(_CELL_P3))
  358. {
  359. for(uint8_t i=0; i<cellLoadLen; i++)
  360. {
  361. OKptr->okcell_inf.cell_P3.cell_p3[i] = OKptr->Okcell_recv_buf[8 + i];
  362. }
  363. }
  364. break;
  365. default:
  366. break;
  367. }
  368. }
  369. }
  370. }
  371. //清理buff
  372. memset(OKptr->Okcell_recv_buf,0,OKptr->Okcell_recv_index);
  373. //包数完整重新计数
  374. OKptr->Okcell_recv_index = 0;
  375. }
  376. }
  377. }
  378. struct OkCell_P80 okcell_p80;
  379. struct OkCell_P82 okcell_p82;
  380. struct OkCell_P83 okcell_p83;
  381. uint32_t time_okcell_p80 = 0;
  382. uint32_t time_okcell_p82 = 0;
  383. uint32_t time_okcell_p83 = 0;
  384. bool send_okcell_p80data = false;
  385. bool send_okcell_p82data = false;
  386. bool send_okcell_p83data = false;
  387. void send_msg_to_okcell(void)
  388. {
  389. //自动锁定波特率,正方电池开机自动循环500K/1M发送数据。正方电池缺少一个波特率锁定的反馈应答
  390. //电池开机会自动1M/500k切换波特率给飞控发信息,所以不用用是否连接来判断。
  391. if(/*okcell_device1.okcell_link_status == COMP_NOEXIST &&*/ send_okcell_p80data == false &&
  392. okcell_device1.cell_bps_lock_success == false && HAL_GetTick() < 30000 &&
  393. HAL_GetTick() - time_okcell_p80 > 250)
  394. {
  395. time_okcell_p80 = HAL_GetTick();
  396. okcell_p80.ok_s[0] = 'Z';
  397. okcell_p80.ok_s[1] = 'F';
  398. okcell_p80.ok_s[2] = 'K';
  399. okcell_p80.ok_s[3] = 'J';
  400. okcell_p80.ok_cmd[0] = 0x80;
  401. okcell_p80.ok_cmd[1] = 0x00;
  402. okcell_p80.ok_len = 1;
  403. okcell_p80.ok_flag = 0xbb;
  404. okcell_p80.ok_data = 0x79;
  405. short OKcellCRC = crc_ccitt((uint8_t *)&okcell_p80.ok_data,okcell_p80.ok_len);
  406. okcell_p80.ok_crc[0] = (OKcellCRC>>8) & 0xff;
  407. okcell_p80.ok_crc[1] = OKcellCRC & 0xff;
  408. okcell_p80.ok_e[0] = 'E';
  409. okcell_p80.ok_e[1] = 'N';
  410. okcell_p80.ok_e[2] = 'D';
  411. send_okcell_p80data = true;
  412. }
  413. if(send_okcell_p80data == true){
  414. send_okcell_p80data =false;
  415. Can_Send_Msg_Func(CANID2, (unsigned char *)&okcell_p80, sizeof(okcell_p80), CAN_OKCELL_SEND_ID, CAN_ID_EXT);
  416. }
  417. if(send_okcell_p82data == true){
  418. send_okcell_p82data =false;
  419. Can_Send_Msg_Func(CANID2, (unsigned char *)&okcell_p82, sizeof(okcell_p82), okcell_device1.deviceCanID, CAN_ID_EXT);
  420. }
  421. //获取电池编号
  422. if(okcell_device1.Okcell_Link.connect_status == COMP_NORMAL && okcell_device1.cell_bps_lock_success == true &&
  423. okcell_device1.get_cellNumber == false &&
  424. send_okcell_p83data == false && HAL_GetTick() - time_okcell_p83 > 1000)
  425. {
  426. time_okcell_p83 = HAL_GetTick();
  427. okcell_p83.ok_s[0] = 'Z';
  428. okcell_p83.ok_s[1] = 'F';
  429. okcell_p83.ok_s[2] = 'K';
  430. okcell_p83.ok_s[3] = 'J';
  431. okcell_p83.ok_cmd[0] = 0x83;
  432. okcell_p83.ok_cmd[1] = 0x00;
  433. okcell_p83.ok_len = 0;
  434. okcell_p83.ok_flag = 0xbb;
  435. okcell_p83.ok_crc[0] = 0xff;
  436. okcell_p83.ok_crc[1] = 0xff;
  437. okcell_p83.ok_e[0] = 'E';
  438. okcell_p83.ok_e[1] = 'N';
  439. okcell_p83.ok_e[2] = 'D';
  440. send_okcell_p83data = true;
  441. }
  442. if(send_okcell_p83data == true){
  443. send_okcell_p83data =false;
  444. Can_Send_Msg_Func(CANID2, (unsigned char *)&okcell_p83, sizeof(okcell_p83), okcell_device1.deviceCanID, CAN_ID_EXT);
  445. }
  446. }
  447. /**************************************************************************************/
  448. /************************************VKBMS*******************************************/
  449. /**
  450. * @file Send_VKbms_info
  451. * @brief VK智能电池协议飞控端发送
  452. * @param none
  453. * @details
  454. * @author Zhang Sir
  455. **/
  456. uint8_t bms_step = 0;
  457. void send_msg_to_VKbms(void)
  458. {
  459. static uint8_t change_dev = 1;
  460. Vkbms_Device *ptr = NULL;
  461. //处理 有问题,如果不是同时上电,后上电的电池2无法读取电池设备信息。
  462. static uint32_t bms_heart_time = 0;;
  463. unsigned int can_id = 0;
  464. uint8_t len = 0, msg_id = 0,i = 0;
  465. uint8_t bms_can_buf[8] = {0};
  466. uint16_t crc = 0;
  467. if(change_dev == 1)
  468. {
  469. change_dev = 2;
  470. ptr = &Device1;
  471. }
  472. else if(change_dev == 2)
  473. {
  474. change_dev = 1;
  475. ptr = &Device2;
  476. }
  477. if(ptr->Vkbms_Link.connect_status != COMP_NORMAL)
  478. return;
  479. //握手应答
  480. if(ptr->ack_to_bms == true)
  481. {
  482. msg_id = 0x01;
  483. can_id = msg_id << 20 | 0x7 << 17 | ptr->source_id << 11 | 0x1 << 5 | 0x1 << 4 | 0x1 << 3 | 1;
  484. len = 2;
  485. bms_can_buf[0] = 0x56;
  486. bms_can_buf[1] = 0x31;
  487. Can_Send_Msg_Func(CANID2, bms_can_buf, len, can_id, CAN_ID_EXT);
  488. ptr->ack_to_bms = false;
  489. }
  490. if(ptr->get_bms3_ack == false)
  491. {
  492. len = 0;
  493. msg_id = 0x03;//canid 4083768 3E5039
  494. can_id = msg_id << 20 | 0x7 << 17 | ptr->source_id << 11 | 0x1 << 5 | 0x1 << 4 | 0x1 << 3 | 1;
  495. Can_Send_Msg_Func(CANID2, bms_can_buf, len, can_id, CAN_ID_EXT);
  496. }
  497. else if(ptr->get_bms4_ack == false)
  498. {
  499. len = 0;
  500. msg_id = 0x04; //canid 5132344 4E5039
  501. can_id = msg_id << 20 | 0x7 << 17 | ptr->source_id << 11 | 0x1 << 5 | 0x1 << 4 | 0x1 << 3 | 1;
  502. Can_Send_Msg_Func(CANID2, bms_can_buf, len, can_id, CAN_ID_EXT);
  503. }
  504. else if(ptr->get_bms5_ack == false)
  505. {
  506. len = 0;
  507. msg_id = 0x05;//canid 6180920 5E5039
  508. can_id = msg_id << 20 | 0x7 << 17 | ptr->source_id << 11 | 0x1 << 5 | 0x1 << 4 | 0x1 << 3 | 1;
  509. Can_Send_Msg_Func(CANID2, bms_can_buf, len, can_id, CAN_ID_EXT);
  510. }
  511. if(start_msg.key_to_bms == true)
  512. {
  513. msg_id = 0x07;
  514. crc = Get_Crc16(&start_msg.key_data[0],20);
  515. memcpy(&bms_can_buf[0],&crc,2);
  516. memcpy(&bms_can_buf[2],&start_msg.key_data[i],6);
  517. can_id = msg_id << 20 | 0x7 << 17 | ptr->source_id << 11 | 0x1 << 5 | 0x1 << 4 | 0x0 << 3 | 1;
  518. Can_Send_Msg_Func(CANID2, &bms_can_buf[0], 8, can_id, CAN_ID_EXT);
  519. i += 6;
  520. can_id = msg_id << 20 | 0x7 << 17 | ptr->source_id << 11 | 0x1 << 5 | 0x0 << 4 | 0x0 << 3 | 2;
  521. Can_Send_Msg_Func(CANID2, &start_msg.key_data[i], 8, can_id, CAN_ID_EXT);
  522. i += 8;
  523. can_id = msg_id << 20 | 0x7 << 17 | ptr->source_id << 11 | 0x1 << 5 | 0x0 << 4 | 0x1 << 3 | 3;
  524. Can_Send_Msg_Func(CANID2, &start_msg.key_data[i], 6, can_id, CAN_ID_EXT);
  525. }
  526. //开启mos
  527. else if(start_msg.mos_status == true)
  528. {
  529. msg_id = 0x08;
  530. can_id = msg_id << 20 | 0x7 << 17 | ptr->source_id << 11 | 0x1 << 5 | 0x1 << 4 | 0x1 << 3 | 1;
  531. bms_can_buf[0] = 0x01;
  532. Can_Send_Msg_Func(CANID2, bms_can_buf, 1, can_id, CAN_ID_EXT);
  533. }
  534. else if(utc_time != 0 && utc_send_time > 0 )
  535. {
  536. msg_id = 0x09;
  537. can_id = msg_id << 20 | 0x7 << 17 | ptr->source_id << 11 | 0x1 << 5 | 0x1 << 4 | 0x1 << 3 | 1;
  538. memcpy(&bms_can_buf[0],&utc_time,4);
  539. Can_Send_Msg_Func(CANID2, bms_can_buf, 4, can_id, CAN_ID_EXT);
  540. utc_send_time--;
  541. }
  542. else if(HAL_GetTick() - bms_heart_time > 500)//实时信息应答包
  543. {
  544. msg_id = 0x02;
  545. can_id = msg_id << 20 | 0x7 << 17 | ptr->source_id << 11 | 0x1 << 5 | 0x1 << 4 | 0x1 << 3 | 1;
  546. Can_Send_Msg_Func(CANID2, bms_can_buf, 0, can_id, CAN_ID_EXT);
  547. bms_heart_time = HAL_GetTick();
  548. }
  549. // if(Device1.Vkbms_Link.connect_status == COMP_NORMAL || Device2.Vkbms_Link.connect_status == COMP_NORMAL)
  550. // {
  551. // static uint8_t bsm_step_num = 6;
  552. // static uint32_t bms_heart_time = 0;;
  553. // unsigned int can_id = 0;
  554. // uint8_t len = 0, msg_id = 0,i = 0;
  555. // uint8_t bms_can_buf[8] = {0};
  556. // uint16_t crc = 0;
  557. // //上电握手
  558. // if(Device1.ack_to_bms == true || Device2.ack_to_bms == true)
  559. // {
  560. // msg_id = 0x01;
  561. // if(Device1.ack_to_bms == true)
  562. // {
  563. // can_id = msg_id << 20 | 0x7 << 17 | Device1.source_id << 11 | 0x1 << 5 | 0x1 << 4 | 0x1 << 3 | 1;
  564. // Device1.ack_to_bms = false;
  565. // }
  566. // else if (Device2.ack_to_bms == true)
  567. // {
  568. // can_id = msg_id << 20 | 0x7 << 17 | Device2.source_id << 11 | 0x1 << 5 | 0x1 << 4 | 0x1 << 3 | 1;
  569. // Device2.ack_to_bms = false;
  570. // }
  571. // len = 2;
  572. // bms_can_buf[0] = 0x56;
  573. // bms_can_buf[1] = 0x31;
  574. // Can_Send_Msg_Func(CANID2, bms_can_buf, len, can_id, CAN_ID_EXT);
  575. // }
  576. // //读取电池信息
  577. // if(bms_step <= 2)
  578. // {
  579. // //上电发送的信息
  580. // switch (bms_step)
  581. // {
  582. // case 0:
  583. // if(bsm_step_num > 0)
  584. // {
  585. // len = 0;
  586. // msg_id = 0x03;//canid 4083768 3E5038
  587. // can_id = msg_id << 20 | 0x7 << 17 | Device1.source_id << 11 | 0x1 << 5 | 0x1 << 4 | 0x1 << 3 | 1;
  588. // Can_Send_Msg_Func(CANID2, bms_can_buf, len, can_id, CAN_ID_EXT);
  589. // if(Device2.Vkbms_Link.connect_status == COMP_NORMAL)
  590. // {
  591. // can_id = msg_id << 20 | 0x7 << 17 | Device2.source_id << 11 | 0x1 << 5 | 0x1 << 4 | 0x1 << 3 | 1;
  592. // Can_Send_Msg_Func(CANID2, bms_can_buf, len, can_id, CAN_ID_EXT);
  593. // }
  594. // bsm_step_num--;
  595. // }
  596. // else
  597. // {
  598. // bsm_step_num = 5;
  599. // bms_step = 1;
  600. // }
  601. // break;
  602. // case 1:
  603. // if(bsm_step_num > 0)
  604. // {
  605. // len = 0;
  606. // msg_id = 0x04; //canid 5132344 4E5038
  607. // can_id = msg_id << 20 | 0x7 << 17 | Device1.source_id << 11 | 0x1 << 5 | 0x1 << 4 | 0x1 << 3 | 1;
  608. // Can_Send_Msg_Func(CANID2, bms_can_buf, len, can_id, CAN_ID_EXT);
  609. // if(Device2.Vkbms_Link.connect_status == COMP_NORMAL)
  610. // {
  611. // can_id = msg_id << 20 | 0x7 << 17 | Device2.source_id << 11 | 0x1 << 5 | 0x1 << 4 | 0x1 << 3 | 1;
  612. // Can_Send_Msg_Func(CANID2, bms_can_buf, len, can_id, CAN_ID_EXT);
  613. // }
  614. // bsm_step_num--;
  615. // }
  616. // else
  617. // {
  618. // bsm_step_num = 5;
  619. // bms_step = 2;
  620. // }
  621. // break;
  622. // case 2:
  623. // if(bsm_step_num > 0)
  624. // {
  625. // len = 0;
  626. // msg_id = 0x05;//canid 6180920 5E5038
  627. // can_id = msg_id << 20 | 0x7 << 17 | Device1.source_id << 11 | 0x1 << 5 | 0x1 << 4 | 0x1 << 3 | 1;
  628. // Can_Send_Msg_Func(CANID2, bms_can_buf, len, can_id, CAN_ID_EXT);
  629. // if(Device2.Vkbms_Link.connect_status == COMP_NORMAL)
  630. // {
  631. // can_id = msg_id << 20 | 0x7 << 17 | Device2.source_id << 11 | 0x1 << 5 | 0x1 << 4 | 0x1 << 3 | 1;
  632. // Can_Send_Msg_Func(CANID2, bms_can_buf, len, can_id, CAN_ID_EXT);
  633. // }
  634. // bsm_step_num--;
  635. // }
  636. // else
  637. // {
  638. // bsm_step_num = 5;
  639. // bms_step = 3;
  640. // }
  641. // break;
  642. // default:
  643. // break;
  644. // }
  645. // }
  646. // //秘钥匹配
  647. // else if(start_msg.key_to_bms == true && bsm_step_num > 0 && bms_step == 3 ) //上个if语句发完再发
  648. // {
  649. // msg_id = 0x07;
  650. // crc = Get_Crc16(&start_msg.key_data[0],20);
  651. // memcpy(&bms_can_buf[0],&crc,2);
  652. // memcpy(&bms_can_buf[2],&start_msg.key_data[i],6);
  653. // can_id = msg_id << 20 | 0x7 << 17 | Device1.source_id << 11 | 0x1 << 5 | 0x1 << 4 | 0x0 << 3 | 1;
  654. // Can_Send_Msg_Func(CANID2, bms_can_buf, len, can_id, CAN_ID_EXT);
  655. // i += 6;
  656. // can_id = msg_id << 20 | 0x7 << 17 | Device1.source_id << 11 | 0x1 << 5 | 0x0 << 4 | 0x0 << 3 | 2;
  657. // Can_Send_Msg_Func(CANID2, start_msg.key_data, len, can_id, CAN_ID_EXT);
  658. // i += 8;
  659. // can_id = msg_id << 20 | 0x7 << 17 | Device1.source_id << 11 | 0x1 << 5 | 0x0 << 4 | 0x1 << 3 | 3;
  660. // Can_Send_Msg_Func(CANID2, start_msg.key_data, len, can_id, CAN_ID_EXT);
  661. // bsm_step_num--;
  662. // if(bsm_step_num == 0)
  663. // {
  664. // bsm_step_num = 5;
  665. // bms_step = 4;
  666. // }
  667. // }
  668. // //开启mos
  669. // else if(start_msg.mos_status == true && bsm_step_num > 0 && (bms_step == 4 || start_msg.mos_status == true))
  670. // {
  671. // msg_id = 0x08;
  672. // can_id = msg_id << 20 | 0x7 << 17 | Device1.source_id << 11 | 0x1 << 5 | 0x1 << 4 | 0x1 << 3 | 1;
  673. // bms_can_buf[0] = 0x01;
  674. // Can_Send_Msg_Func(CANID2, bms_can_buf, len, can_id, CAN_ID_EXT);
  675. // bsm_step_num--;
  676. // }
  677. // else if(HAL_GetTick() - bms_heart_time > 1000)
  678. // {
  679. // msg_id = 0x02;
  680. // can_id = msg_id << 20 | 0x7 << 17 | Device1.source_id << 11 | 0x1 << 5 | 0x1 << 4 | 0x1 << 3 | 1;
  681. // Can_Send_Msg_Func(CANID2, bms_can_buf, 0, can_id, CAN_ID_EXT);
  682. // if(Device2.Vkbms_Link.connect_status == COMP_NORMAL)
  683. // {
  684. // can_id = msg_id << 20 | 0x7 << 17 | Device2.source_id << 11 | 0x1 << 5 | 0x1 << 4 | 0x1 << 3 | 1;
  685. // Can_Send_Msg_Func(CANID2, bms_can_buf, 0, can_id, CAN_ID_EXT);
  686. // }
  687. // bms_heart_time = HAL_GetTick();
  688. // }
  689. // }
  690. }
  691. /**
  692. * @file BMSCanRecvHookFunction
  693. * @brief VK智能电池协议
  694. * @param none
  695. * @details
  696. * @author Zhang Sir
  697. **/
  698. uint16_t bms_test = 0;
  699. uint16_t bms_re = 0;
  700. uint8_t fmu_send_vkbms_msgid = 0;
  701. void BMSCanRecvHookFunction(uint32_t CanID, uint8_t data[], uint8_t len)
  702. {
  703. uint32_t source_id = 0, msg_id = 0;
  704. uint8_t bms_SOF = 0, bms_EOF = 0, frame_num = 0;
  705. static uint32_t bms1_source_id = 0;
  706. static uint32_t pack_msg_id = 0;
  707. Vkbms_Device *Bmspointer = NULL;
  708. msg_id = (CanID & VK_MSG_MASK_ID) >> 20;
  709. source_id = (CanID & VK_SRC_MASK_ID) >> 5;
  710. bms_SOF = (CanID >> 4) & 0x1;
  711. bms_EOF = (CanID >> 3) & 0x1;
  712. frame_num = CanID & 0x7;
  713. if(source_id == bms1_source_id || bms1_source_id == 0)
  714. {
  715. bms1_source_id = source_id;
  716. Bmspointer = &Device1;
  717. Bmspointer->source_id = source_id;
  718. }
  719. else
  720. {
  721. Bmspointer = &Device2;
  722. Bmspointer->source_id = source_id;
  723. }
  724. Bmspointer->Vkbms_Link.connect_status = COMP_NORMAL;
  725. Bmspointer->Vkbms_Link.recv_time = HAL_GetTick();
  726. //单帧
  727. if(bms_SOF == 1 && bms_EOF == 1)
  728. {
  729. memcpy(&Bmspointer->bms_can_buf[0],&data[0],len);
  730. }
  731. //多帧 帧头
  732. else if(bms_SOF == 1 && bms_EOF == 0)
  733. {
  734. Bmspointer->mul_frame_i = 0;
  735. Bmspointer->mul_frame_num = 2;
  736. Bmspointer->if_mul_frame = true;
  737. Bmspointer->recv_mul_freme_complete = false;
  738. memcpy(&Bmspointer->bms_can_buf[Bmspointer->mul_frame_i],&data[0],len);
  739. Bmspointer->mul_frame_i += len;
  740. pack_msg_id = msg_id;
  741. }
  742. // 中间帧
  743. else if(Bmspointer->if_mul_frame == true && bms_SOF == 0 && bms_EOF == 0 && pack_msg_id == msg_id)
  744. {
  745. if(Bmspointer->mul_frame_num == frame_num || ( Bmspointer->mul_frame_num == 0 && frame_num == 1)
  746. /*&& ((Bmspointer->mul_frame_i + len) <= sizeof(vkbms2))*/ )
  747. {
  748. memcpy(&Bmspointer->bms_can_buf[Bmspointer->mul_frame_i],&data[0],len);
  749. if(( Bmspointer->mul_frame_num == 0 && frame_num == 1))
  750. {
  751. Bmspointer->mul_frame_num++;
  752. }
  753. Bmspointer->mul_frame_i += len;
  754. Bmspointer->mul_frame_num++;
  755. if(Bmspointer->mul_frame_num >= 8)
  756. {
  757. Bmspointer->mul_frame_num = 0;
  758. }
  759. }
  760. else
  761. {
  762. Bmspointer->if_mul_frame = false;
  763. }
  764. }
  765. //帧尾
  766. else if(bms_SOF == 0 && bms_EOF == 1 && Bmspointer->if_mul_frame == true && pack_msg_id == msg_id)
  767. {
  768. memcpy(&Bmspointer->bms_can_buf[Bmspointer->mul_frame_i],&data[0],len);
  769. Bmspointer->mul_frame_i += len;
  770. Bmspointer->if_mul_frame = false;
  771. //bms_test = Get_Crc16(&Bmspointer->bms_can_buf[2], Bmspointer->mul_frame_i - 2);
  772. //bms_re = Bmspointer->bms_can_buf[0] + (Bmspointer->bms_can_buf[1] << 8);
  773. if(Get_Crc16(&Bmspointer->bms_can_buf[2], Bmspointer->mul_frame_i - 2) == (Bmspointer->bms_can_buf[0] + (Bmspointer->bms_can_buf[1] << 8)))
  774. {
  775. Bmspointer->recv_mul_freme_complete = true;
  776. }
  777. }
  778. switch (msg_id)
  779. {
  780. case 0X01:
  781. if(Bmspointer->bms_can_buf[0] == 0x56 && Bmspointer->bms_can_buf[1] == 0x31)
  782. {
  783. Bmspointer->ack_to_bms = true;
  784. Bmspointer->source_id = source_id;
  785. }
  786. break;
  787. case 0X02:
  788. if(Bmspointer->recv_mul_freme_complete == true)
  789. {
  790. memcpy(&Bmspointer->vk_bms2.voltage, &Bmspointer->bms_can_buf[2], sizeof(vkbms2));
  791. Bmspointer->recv_mul_freme_complete = false;
  792. }
  793. break;
  794. case 0X03:
  795. if(Bmspointer->recv_mul_freme_complete == true)
  796. {
  797. memcpy(&Bmspointer->vk_bms3.bms_company_info, &Bmspointer->bms_can_buf[2], sizeof(vkbms3));
  798. Bmspointer->recv_mul_freme_complete = false;
  799. Bmspointer->get_bms3_ack = true;
  800. }
  801. break;
  802. case 0X04:
  803. memcpy(&Bmspointer->vk_bms4.capacity, &Bmspointer->bms_can_buf[0], sizeof(vkbms4));
  804. Bmspointer->recv_mul_freme_complete = false;
  805. Bmspointer->get_bms4_ack = true;
  806. break;
  807. case 0X05:
  808. if(Bmspointer->recv_mul_freme_complete == true)
  809. {
  810. memcpy(&Bmspointer->vk_bms5.health_percent, &Bmspointer->bms_can_buf[2], sizeof(vkbms5));
  811. Bmspointer->recv_mul_freme_complete = false;
  812. Bmspointer->get_bms5_ack = true;
  813. }
  814. break;
  815. //秘钥是否匹配
  816. case 0x07:
  817. start_msg.key_to_bms = false;
  818. if(Bmspointer->bms_can_buf[0] == 0)
  819. {
  820. start_msg.mos_status = true;
  821. start_msg.Id_content = 1;
  822. }
  823. else
  824. {
  825. start_msg.Id_content = 2;
  826. }
  827. start_msg.Id = 3;
  828. start_msg.key_info_checking = true;
  829. break;
  830. case 0x08:
  831. start_msg.Id = 4;
  832. start_msg.Id_content = Bmspointer->bms_can_buf[0];
  833. start_msg.key_info_checking = true;
  834. break;
  835. default:
  836. break;
  837. }
  838. }
  839. /**************************************************************************************/
  840. /************************************tattu*******************************************/
  841. #pragma pack(1)
  842. typedef struct
  843. {
  844. unsigned char canid_prio :5;
  845. unsigned short canid_msgid :16;
  846. unsigned char canid_som :1;
  847. unsigned char canid_srcid :7;
  848. /*unsigned char canid_desid:7;
  849. unsigned char canid_rnr:1;*/
  850. }_TATTU_CANID;
  851. #pragma pack()
  852. _TATTU_DEVICE tattu_device1 = {.Tattu_Link.connect_status = COMP_NOEXIST},
  853. tattu_device2 = {.Tattu_Link.connect_status = COMP_NOEXIST};
  854. void TattuCanRecvHookFunction(uint32_t ttuCanID, uint8_t data[], uint8_t len)
  855. {
  856. //获取数据中的最后一位
  857. _TATTU_DEVICE *taptr = NULL;
  858. uint8_t can_msgid = 0;
  859. can_msgid = ttuCanID & 0x7f;
  860. if(can_msgid == 0x16)
  861. {
  862. taptr = &tattu_device1;
  863. }
  864. else
  865. {
  866. taptr = &tattu_device2;
  867. }
  868. memcpy(&taptr->ttu_tailbyte, &data[len - 1], sizeof(uint8_t));
  869. //找到开头
  870. if(taptr->ttu_tailbyte.tail_start == 1){
  871. taptr->Tattu_recv_index = 0;
  872. taptr->Tattu_get_s = true;
  873. }
  874. //溢出检测
  875. if(taptr->Tattu_recv_index + len > TATTU_MAXLEN)
  876. {
  877. memset(taptr->Tattu_recv_buf,0,taptr->Tattu_recv_index);
  878. taptr->Tattu_recv_index = 0;
  879. taptr->Tattu_get_s = false;
  880. }
  881. //获取到正确的开始位则接收数据
  882. if(taptr->Tattu_get_s == true){
  883. //复制有效数据,最后一个字节不是有效数据
  884. memcpy(&taptr->Tattu_recv_buf[taptr->Tattu_recv_index], data, len-1);
  885. taptr->Tattu_recv_index += (len-1);
  886. }
  887. //找到结尾,开始解析
  888. if(taptr->Tattu_get_s == true && taptr->ttu_tailbyte.tail_end == 1)
  889. {
  890. taptr->Tattu_get_s = false;
  891. taptr->Tattu_Link.connect_status = COMP_NORMAL;
  892. //更新电池数据到来时间
  893. taptr->Tattu_Link.recv_time = HAL_GetTick();
  894. //如果是单帧完整数据
  895. if(taptr->ttu_tailbyte.tail_start == 1 || taptr->Tattu_recv_index <= 7)
  896. {
  897. //单帧数据不需要校验
  898. }
  899. //多帧拼包
  900. else
  901. {
  902. //CRC校验,验证通过,暂不开启
  903. CCITT_CRC16Init(&taptr->Tattu_recv_buf[2],taptr->Tattu_recv_index-2);
  904. if(CCITT_CRC16 == (taptr->Tattu_recv_buf[0] + (taptr->Tattu_recv_buf[1]<<8)))
  905. {
  906. //避免电池单方面增加协议造成溢出,格式电池12s跟14s兼容有问题,飞控自己做处理
  907. //后两个字节是自己添加的用来识别电池串数
  908. if(taptr->Tattu_recv_index-2 <= (sizeof(_TATTU_INFO)-2))
  909. {
  910. //stm32为小段模式,TATTU发送过来的数据为小端模式,可直接使用memcpy
  911. //12S
  912. if(taptr->Tattu_recv_index-2 == (sizeof(_TATTU_INFO)-2-4-16))
  913. {
  914. taptr->ttu_inf.tattu_cnum = 12;
  915. //前12s信息
  916. memcpy(&taptr->ttu_inf,&taptr->Tattu_recv_buf[2],40);
  917. //后边信息
  918. memcpy(&taptr->ttu_inf.tattu_descapa,&taptr->Tattu_recv_buf[40+2],8);
  919. }
  920. //添加序列号后的12s
  921. else if(taptr->Tattu_recv_index-2 == (sizeof(_TATTU_INFO)-2-4))
  922. {
  923. taptr->ttu_inf.tattu_cnum = 12;
  924. //前12s信息
  925. memcpy(&taptr->ttu_inf,&taptr->Tattu_recv_buf[2],40);
  926. //后边信息
  927. memcpy(&taptr->ttu_inf.tattu_descapa,&taptr->Tattu_recv_buf[40+2],24);
  928. }
  929. //14s
  930. else if(taptr->Tattu_recv_index-2 == (sizeof(_TATTU_INFO)-2-16) || taptr->Tattu_recv_index-2 == (sizeof(_TATTU_INFO)-2))
  931. {
  932. taptr->ttu_inf.tattu_cnum = 14;
  933. //14s信息
  934. memcpy(&taptr->ttu_inf,&taptr->Tattu_recv_buf[2],taptr->Tattu_recv_index-2);
  935. }
  936. }else{
  937. //清空电池信息数据
  938. memset(&taptr->ttu_inf, 0, sizeof(_TATTU_INFO));
  939. }
  940. }
  941. }
  942. //清理buff
  943. memset(taptr->Tattu_recv_buf,0,taptr->Tattu_recv_index);
  944. //包数完整重新计数
  945. taptr->Tattu_recv_index = 0;
  946. }
  947. }
  948. /*
  949. 格氏电池的CRC校验
  950. */
  951. #define CRC_CCITT_INIT 0xFFFF
  952. #define CRC_CCITT_POLY 0x1021U
  953. uint16_t CCITT_CRC16 = 0;
  954. void CCITT_CRC16Init(uint8_t const *bytes, uint16_t len)
  955. {
  956. CCITT_CRC16 = CRC_CCITT_INIT;
  957. CCITT_CRC_ARRAY(bytes, len);
  958. }
  959. void CCITT_CRCStep(uint8_t byte)
  960. {
  961. uint32_t j;
  962. CCITT_CRC16 ^= ((uint16_t)byte << 8);
  963. for (j = 0; j < 8; j++)
  964. {
  965. CCITT_CRC16=(CCITT_CRC16 & 0x8000U)?((CCITT_CRC16 << 1) ^ CRC_CCITT_POLY):(CCITT_CRC16 << 1);
  966. }
  967. }
  968. void CCITT_CRC_ARRAY(uint8_t const * bytes, uint16_t len)
  969. {
  970. while (len--) CCITT_CRCStep(*bytes++);
  971. }
  972. /**************************************************************************************/
  973. Vkbms_Device Device1 = {.Vkbms_Link.connect_status = COMP_NOEXIST};
  974. Vkbms_Device Device2 = {.Vkbms_Link.connect_status = COMP_NOEXIST};
  975. uint8_t bms_group_num = 0; //电池组数
  976. struct BMS_DATA bms_data = {.bms_ss = 0xFFFF}, bms_data2 = {.bms_ss = 0xFFFF};
  977. /**
  978. * @file update_bms_data
  979. * @brief 更新电池信息
  980. * @param none
  981. * @details
  982. * @author Zhang Sir
  983. **/
  984. void update_bms_data( void )
  985. {
  986. //正方电池
  987. Check_dev_link(&okcell_device1.Okcell_Link,5000,(char *)&okcell_device1.okcell_inf,sizeof(_CELL_INF));
  988. Check_dev_link(&okcell_device2.Okcell_Link,5000,(char *)&okcell_device2.okcell_inf,sizeof(_CELL_INF));
  989. //格式电池
  990. Check_dev_link(&tattu_device1.Tattu_Link,5000,(char *)&tattu_device1.ttu_inf,sizeof(_TATTU_INFO));
  991. Check_dev_link(&tattu_device2.Tattu_Link,5000,(char *)&tattu_device2.ttu_inf,sizeof(_TATTU_INFO));
  992. //海盈电池
  993. Check_dev_link(&Herewin_Link,5000,(char *)&herewin_info,sizeof(herewin_bms));
  994. //VK电池
  995. Check_dev_link(&Device1.Vkbms_Link,5000,(char *)&Device1,sizeof(Vkbms_Device));
  996. Check_dev_link(&Device2.Vkbms_Link,5000,(char *)&Device2,sizeof(Vkbms_Device));
  997. if ( okcell_device1.Okcell_Link.connect_status == COMP_NORMAL || okcell_device2.Okcell_Link.connect_status == COMP_NORMAL )
  998. {
  999. Dev.Bms_Link.connect_status = COMP_NORMAL;
  1000. //第一组电池
  1001. if ( okcell_device1.Okcell_Link.connect_status == COMP_NORMAL )
  1002. {
  1003. bms_data.bms_cycle = okcell_device1.okcell_inf.cell_D3.cell_d3[4];
  1004. if(okcell_device1.okcell_inf.cell_D0.cell_d0[6] >= 18) //正方超18S电池10mv发送
  1005. {
  1006. bms_data.bms_volt = okcell_device1.okcell_inf.cell_D0.cell_d0[0];
  1007. }
  1008. else
  1009. {
  1010. bms_data.bms_volt = okcell_device1.okcell_inf.cell_D0.cell_d0[0] / 10;
  1011. }
  1012. bms_data.bms_temp = okcell_device1.okcell_inf.cell_D0.cell_d0[2];
  1013. bms_data.bms_vs = okcell_device1.okcell_inf.cell_D0.cell_d0[3];
  1014. //正方电池只关心飞控对接异常不让解锁,不关心异常5
  1015. 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;
  1016. bms_data.bms_num = okcell_device1.okcell_inf.cell_D0.cell_d0[6];
  1017. bms_data.bms_v1 = okcell_device1.okcell_inf.cell_D0.cell_d0[7];
  1018. bms_data.bms_v2 = okcell_device1.okcell_inf.cell_D0.cell_d0[8];
  1019. bms_data.bms_v3 = okcell_device1.okcell_inf.cell_D0.cell_d0[9];
  1020. bms_data.bms_v4 = okcell_device1.okcell_inf.cell_D0.cell_d0[10];
  1021. bms_data.bms_v5 = okcell_device1.okcell_inf.cell_D0.cell_d0[11];
  1022. bms_data.bms_v6 = okcell_device1.okcell_inf.cell_D0.cell_d0[12];
  1023. bms_data.bms_v7 = okcell_device1.okcell_inf.cell_D0.cell_d0[13];
  1024. bms_data.bms_v8 = okcell_device1.okcell_inf.cell_D0.cell_d0[14];
  1025. bms_data.bms_v9 = okcell_device1.okcell_inf.cell_D0.cell_d0[15];
  1026. bms_data.bms_v10 = okcell_device1.okcell_inf.cell_D0.cell_d0[16];
  1027. bms_data.bms_v11 = okcell_device1.okcell_inf.cell_D0.cell_d0[17];
  1028. bms_data.bms_v12 = okcell_device1.okcell_inf.cell_D0.cell_d0[18];
  1029. bms_data.bms_v13 = okcell_device1.okcell_inf.cell_D0.cell_d0[19];
  1030. bms_data.bms_v14 = okcell_device1.okcell_inf.cell_D0.cell_d0[20];
  1031. bms_data.bms_v15 = okcell_device1.okcell_inf.cell_D0.cell_d0[21];
  1032. bms_data.bms_v16 = okcell_device1.okcell_inf.cell_D0.cell_d0[22];
  1033. bms_data.bms_v17 = okcell_device1.okcell_inf.cell_D0.cell_d0[23];
  1034. bms_data.bms_v18 = okcell_device1.okcell_inf.cell_D0.cell_d0[24];
  1035. bms_data.bms_v19 = okcell_device1.okcell_inf.cell_D0.cell_d0[25];
  1036. bms_data.bms_v20 = okcell_device1.okcell_inf.cell_D0.cell_d0[26];
  1037. bms_data.bms_v21 = okcell_device1.okcell_inf.cell_D0.cell_d0[27];
  1038. bms_data.bms_v22 = okcell_device1.okcell_inf.cell_D0.cell_d0[28];
  1039. bms_data.bms_v23 = okcell_device1.okcell_inf.cell_D0.cell_d0[29];
  1040. bms_data.bms_v24 = okcell_device1.okcell_inf.cell_D0.cell_d0[30];
  1041. bms_data.bms_v25 = okcell_device1.okcell_inf.cell_D0.cell_d0[31];
  1042. bms_data.bms_v26 = okcell_device1.okcell_inf.cell_D0.cell_d0[32];
  1043. bms_data.bms_ids[0] = okcell_device1.okcell_inf.cell_P3.cell_p3[0];
  1044. bms_data.bms_ids[1] = okcell_device1.okcell_inf.cell_P3.cell_p3[1];
  1045. for(int i = 1; i< 11; i++){
  1046. // bms_data.bms_ids[2*i] = ((okcell_device1.okcell_inf.cell_P3.cell_p3[2 + i] >> 4) & 0xf) + '0';
  1047. // bms_data.bms_ids[2*i+1] = (okcell_device1.okcell_inf.cell_P3.cell_p3[2 + i] & 0xf )+ '0';
  1048. bms_data.bms_ids[2*i] = ((okcell_device1.okcell_inf.cell_P3.cell_p3[1 + i] >> 4) & 0xf) + '0';
  1049. bms_data.bms_ids[2*i+1] = (okcell_device1.okcell_inf.cell_P3.cell_p3[1 + i] & 0xf )+ '0';
  1050. }
  1051. //memcpy( bms_data.bms_ids, "okcell", 6 );
  1052. bms_data.bms_ac = okcell_device1.okcell_inf.cell_D0.cell_d0[1];
  1053. bms_data.serial_num = FAC_OKCELL;
  1054. //注册
  1055. if(StrArrayNull( &bms_data.bms_ids[0], sizeof( bms_data.bms_ids ) ) == false && dev_bms1.regist.sn == false)
  1056. regist_dev_info(&dev_bms1,DEVICE_BMS1,false,(char *)bms_data.bms_ids,32,NULL,0,NULL,0,"okcell1",8);
  1057. }
  1058. else
  1059. {
  1060. memset( &bms_data, 0, sizeof( bms_data ) );
  1061. }
  1062. //第二组电池
  1063. if ( okcell_device2.Okcell_Link.connect_status == COMP_NORMAL )
  1064. {
  1065. bms_data2.bms_cycle = okcell_device2.okcell_inf.cell_D3.cell_d3[4];
  1066. if(okcell_device2.okcell_inf.cell_D0.cell_d0[6] >= 18)
  1067. {
  1068. bms_data2.bms_volt = okcell_device2.okcell_inf.cell_D0.cell_d0[0];
  1069. }
  1070. else
  1071. {
  1072. bms_data2.bms_volt = okcell_device2.okcell_inf.cell_D0.cell_d0[0] / 10;
  1073. }
  1074. bms_data2.bms_temp = okcell_device2.okcell_inf.cell_D0.cell_d0[2];
  1075. bms_data2.bms_vs = okcell_device2.okcell_inf.cell_D0.cell_d0[3];
  1076. //正方电池只关心飞控对接异常不让解锁,不关心异常5
  1077. 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;
  1078. bms_data2.bms_num = okcell_device2.okcell_inf.cell_D0.cell_d0[6];
  1079. bms_data2.bms_v1 = okcell_device2.okcell_inf.cell_D0.cell_d0[7];
  1080. bms_data2.bms_v2 = okcell_device2.okcell_inf.cell_D0.cell_d0[8];
  1081. bms_data2.bms_v3 = okcell_device2.okcell_inf.cell_D0.cell_d0[9];
  1082. bms_data2.bms_v4 = okcell_device2.okcell_inf.cell_D0.cell_d0[10];
  1083. bms_data2.bms_v5 = okcell_device2.okcell_inf.cell_D0.cell_d0[11];
  1084. bms_data2.bms_v6 = okcell_device2.okcell_inf.cell_D0.cell_d0[12];
  1085. bms_data2.bms_v7 = okcell_device2.okcell_inf.cell_D0.cell_d0[13];
  1086. bms_data2.bms_v8 = okcell_device2.okcell_inf.cell_D0.cell_d0[14];
  1087. bms_data2.bms_v9 = okcell_device2.okcell_inf.cell_D0.cell_d0[15];
  1088. bms_data2.bms_v10 = okcell_device2.okcell_inf.cell_D0.cell_d0[16];
  1089. bms_data2.bms_v11 = okcell_device2.okcell_inf.cell_D0.cell_d0[17];
  1090. bms_data2.bms_v12 = okcell_device2.okcell_inf.cell_D0.cell_d0[18];
  1091. bms_data2.bms_v13 = okcell_device2.okcell_inf.cell_D0.cell_d0[19];
  1092. bms_data2.bms_v14 = okcell_device2.okcell_inf.cell_D0.cell_d0[20];
  1093. bms_data2.bms_v15 = okcell_device2.okcell_inf.cell_D0.cell_d0[21];
  1094. bms_data2.bms_v16 = okcell_device2.okcell_inf.cell_D0.cell_d0[22];
  1095. bms_data2.bms_v17 = okcell_device2.okcell_inf.cell_D0.cell_d0[23];
  1096. bms_data2.bms_v18 = okcell_device2.okcell_inf.cell_D0.cell_d0[24];
  1097. bms_data2.bms_v19 = okcell_device2.okcell_inf.cell_D0.cell_d0[25];
  1098. bms_data2.bms_v20 = okcell_device2.okcell_inf.cell_D0.cell_d0[26];
  1099. bms_data2.bms_v21 = okcell_device2.okcell_inf.cell_D0.cell_d0[27];
  1100. bms_data2.bms_v22 = okcell_device2.okcell_inf.cell_D0.cell_d0[28];
  1101. bms_data2.bms_v23 = okcell_device2.okcell_inf.cell_D0.cell_d0[29];
  1102. bms_data2.bms_v24 = okcell_device2.okcell_inf.cell_D0.cell_d0[30];
  1103. bms_data2.bms_v25 = okcell_device2.okcell_inf.cell_D0.cell_d0[31];
  1104. bms_data2.bms_v26 = okcell_device2.okcell_inf.cell_D0.cell_d0[32];
  1105. bms_data2.bms_ids[0] = okcell_device1.okcell_inf.cell_P3.cell_p3[0];
  1106. bms_data2.bms_ids[1] = okcell_device1.okcell_inf.cell_P3.cell_p3[1];
  1107. for(int i = 1; i< 11; i++){
  1108. bms_data2.bms_ids[2*i] = ((okcell_device2.okcell_inf.cell_P3.cell_p3[1 + i] >> 4) & 0xf) + '0';
  1109. bms_data2.bms_ids[2*i+1] = (okcell_device2.okcell_inf.cell_P3.cell_p3[1 + i] & 0xf )+ '0';
  1110. }
  1111. //memcpy( bms_data2.bms_ids, "okcell2", 7 );
  1112. bms_data2.bms_ac = okcell_device2.okcell_inf.cell_D0.cell_d0[1];
  1113. bms_data2.serial_num = FAC_OKCELL;
  1114. if(StrArrayNull( &bms_data2.bms_ids[0], sizeof( bms_data2.bms_ids ) ) == false && dev_bms2.regist.sn == false)
  1115. regist_dev_info(&dev_bms2,DEVICE_BMS2,false,(char *)bms_data2.bms_ids,32,NULL,0,NULL,0,"okcell2",8);
  1116. }
  1117. else
  1118. {
  1119. memset( &bms_data2, 0, sizeof( bms_data2 ) );
  1120. }
  1121. }
  1122. else if(tattu_device1.Tattu_Link.connect_status == COMP_NORMAL || tattu_device2.Tattu_Link.connect_status == COMP_NORMAL)
  1123. {
  1124. Dev.Bms_Link.connect_status = COMP_NORMAL;
  1125. if(tattu_device1.Tattu_Link.connect_status == COMP_NORMAL)
  1126. {
  1127. group_num = 1;
  1128. bms_data.bms_cycle = tattu_device1.ttu_inf.tattu_cycle;
  1129. bms_data.bms_volt = tattu_device1.ttu_inf.tattu_volt /10;
  1130. bms_data.bms_temp = tattu_device1.ttu_inf.tattu_temp * 10;
  1131. bms_data.bms_vs = tattu_device1.ttu_inf.tattu_perc;
  1132. bms_data.bms_ss = 0;//ttu_inf.def_info[24] & 0xc00;//格式电池只关心部分报警不让解锁
  1133. bms_data.bms_num = tattu_device1.ttu_inf.tattu_cnum;
  1134. bms_data.bms_v1 = tattu_device1.ttu_inf.tattu_v1;
  1135. bms_data.bms_v2 = tattu_device1.ttu_inf.tattu_v2;
  1136. bms_data.bms_v3 = tattu_device1.ttu_inf.tattu_v3;
  1137. bms_data.bms_v4 = tattu_device1.ttu_inf.tattu_v4;
  1138. bms_data.bms_v5 = tattu_device1.ttu_inf.tattu_v5;
  1139. bms_data.bms_v6 = tattu_device1.ttu_inf.tattu_v6;
  1140. bms_data.bms_v7 = tattu_device1.ttu_inf.tattu_v7;
  1141. bms_data.bms_v8 = tattu_device1.ttu_inf.tattu_v8;
  1142. bms_data.bms_v9 = tattu_device1.ttu_inf.tattu_v9;
  1143. bms_data.bms_v10 = tattu_device1.ttu_inf.tattu_v10;
  1144. bms_data.bms_v11 = tattu_device1.ttu_inf.tattu_v11;
  1145. bms_data.bms_v12 = tattu_device1.ttu_inf.tattu_v12;
  1146. bms_data.bms_v13 = tattu_device1.ttu_inf.tattu_v13;
  1147. bms_data.bms_v14 = tattu_device1.ttu_inf.tattu_v14;
  1148. memcpy(bms_data.bms_ids,&tattu_device1.ttu_inf.tuattu_id[0],16);
  1149. //memcpy(bms_data.bms_ids, "Tattu1", 6);
  1150. bms_data.bms_ac = tattu_device1.ttu_inf.tattu_cur;
  1151. bms_data.serial_num = FAC_TATTU;
  1152. if(StrArrayNull( &bms_data.bms_ids[0], sizeof( bms_data.bms_ids ) ) == false && dev_bms1.regist.sn == false)
  1153. regist_dev_info(&dev_bms1,DEVICE_BMS1,false,(char *)bms_data.bms_ids,16,NULL,0,NULL,0,"tattu1",7);
  1154. }
  1155. else
  1156. {
  1157. memset( &bms_data, 0, sizeof(bms_data));
  1158. }
  1159. if(tattu_device2.Tattu_Link.connect_status == COMP_NORMAL)
  1160. {
  1161. group_num = 2;
  1162. bms_data2.bms_cycle = tattu_device2.ttu_inf.tattu_cycle;
  1163. bms_data2.bms_volt = tattu_device2.ttu_inf.tattu_volt / 10;
  1164. bms_data2.bms_temp = tattu_device2.ttu_inf.tattu_temp * 10;
  1165. bms_data2.bms_vs = tattu_device2.ttu_inf.tattu_perc;
  1166. bms_data2.bms_ss = 0;//ttu_inf.def_info[24] & 0xc00;//格式电池只关心部分报警不让解锁
  1167. bms_data2.bms_num = tattu_device2.ttu_inf.tattu_cnum;
  1168. bms_data2.bms_v1 = tattu_device2.ttu_inf.tattu_v1;
  1169. bms_data2.bms_v2 = tattu_device2.ttu_inf.tattu_v2;
  1170. bms_data2.bms_v3 = tattu_device2.ttu_inf.tattu_v3;
  1171. bms_data2.bms_v4 = tattu_device2.ttu_inf.tattu_v4;
  1172. bms_data2.bms_v5 = tattu_device2.ttu_inf.tattu_v5;
  1173. bms_data2.bms_v6 = tattu_device2.ttu_inf.tattu_v6;
  1174. bms_data2.bms_v7 = tattu_device2.ttu_inf.tattu_v7;
  1175. bms_data2.bms_v8 = tattu_device2.ttu_inf.tattu_v8;
  1176. bms_data2.bms_v9 = tattu_device2.ttu_inf.tattu_v9;
  1177. bms_data2.bms_v10 = tattu_device2.ttu_inf.tattu_v10;
  1178. bms_data2.bms_v11 = tattu_device2.ttu_inf.tattu_v11;
  1179. bms_data2.bms_v12 = tattu_device2.ttu_inf.tattu_v12;
  1180. bms_data2.bms_v13 = tattu_device2.ttu_inf.tattu_v13;
  1181. bms_data2.bms_v14 = tattu_device2.ttu_inf.tattu_v14;
  1182. memcpy(bms_data2.bms_ids,&tattu_device2.ttu_inf.tuattu_id[0],16);
  1183. //memcpy(bms_data2.bms_ids, "Tattu2", 6);
  1184. bms_data2.bms_ac = tattu_device2.ttu_inf.tattu_cur;
  1185. bms_data2.serial_num = FAC_TATTU;
  1186. if(StrArrayNull( &bms_data2.bms_ids[0], sizeof( bms_data2.bms_ids ) ) == false && dev_bms2.regist.sn == false)
  1187. regist_dev_info(&dev_bms2,DEVICE_BMS2,false,(char *)bms_data2.bms_ids,16,NULL,0,NULL,0,"tattu2",7);
  1188. }
  1189. else
  1190. {
  1191. memset( &bms_data2, 0, sizeof( bms_data2 ) );
  1192. }
  1193. }
  1194. else if ( Herewin_Link.connect_status == COMP_NORMAL )
  1195. {
  1196. Dev.Bms_Link.connect_status = COMP_NORMAL;
  1197. group_num = 1;
  1198. bms_data.bms_cycle = herewin_info.circulation_num;
  1199. bms_data.bms_volt = herewin_info.total_vol;
  1200. if(herewin_info.get_temp_flag == true)
  1201. bms_data.bms_temp = ( ( herewin_info.battery_temp[0] + herewin_info.battery_temp[1] + herewin_info.battery_temp[2] ) / 3 - 40 ) * 10;
  1202. bms_data.bms_vs = herewin_info.SOC_info;
  1203. bms_data.bms_ss = herewin_info.warn_info;
  1204. bms_data.bms_num = herewin_info.battery_num;
  1205. bms_data.bms_v1 = herewin_info.battery_vol[0];
  1206. bms_data.bms_v2 = herewin_info.battery_vol[1];
  1207. bms_data.bms_v3 = herewin_info.battery_vol[2];
  1208. bms_data.bms_v4 = herewin_info.battery_vol[3];
  1209. bms_data.bms_v5 = herewin_info.battery_vol[4];
  1210. bms_data.bms_v6 = herewin_info.battery_vol[5];
  1211. bms_data.bms_v7 = herewin_info.battery_vol[6];
  1212. bms_data.bms_v8 = herewin_info.battery_vol[7];
  1213. bms_data.bms_v9 = herewin_info.battery_vol[8];
  1214. bms_data.bms_v10 = herewin_info.battery_vol[9];
  1215. bms_data.bms_v11 = herewin_info.battery_vol[10];
  1216. bms_data.bms_v12 = herewin_info.battery_vol[11];
  1217. bms_data.bms_v13 = herewin_info.battery_vol[12];
  1218. bms_data.bms_v14 = herewin_info.battery_vol[13];
  1219. memcpy( bms_data.bms_ids, "herewin", 7 );
  1220. bms_data.bms_ac = herewin_info.tolal_ele;
  1221. bms_data.serial_num = FAC_HEREWIN;
  1222. if(dev_bms1.regist.dev == false)
  1223. regist_dev_info(&dev_bms1,DEVICE_BMS1,false,NULL,0,NULL,0,NULL,0,"herewin",8);
  1224. }
  1225. else if(Device1.Vkbms_Link.connect_status == COMP_NORMAL || Device2.Vkbms_Link.connect_status == COMP_NORMAL)
  1226. {
  1227. Dev.Bms_Link.connect_status = COMP_NORMAL;
  1228. //第一组电池
  1229. if ( Device1.Vkbms_Link.connect_status == COMP_NORMAL )
  1230. {
  1231. group_num = 1;
  1232. bms_data.bms_cycle = Device1.vk_bms5.circulation_time;
  1233. bms_data.bms_volt = Device1.vk_bms2.voltage;
  1234. bms_data.bms_temp = Device1.vk_bms2.tempture;
  1235. bms_data.bms_vs = Device1.vk_bms2.persent / 10;
  1236. bms_data.bms_ss = Device1.vk_bms2.warn_flag;
  1237. bms_data.bms_num = Device1.vk_bms2.bms_num;
  1238. memcpy(&bms_data.bms_v1,&Device1.vk_bms2.bms_v1,26 * 2);
  1239. memcpy(&bms_data.bms_ids[0],&Device1.vk_bms3.bms_id[0],20);
  1240. // bms_data.bms_ids[0] = Device1.vk_bms3.bms_id[0];
  1241. // bms_data.bms_ids[1] = Device1.vk_bms3.bms_id[1];
  1242. // for(int i = 1; i< 11; i++){
  1243. // bms_data.bms_ids[2*i] = ((Device1.vk_bms3.bms_id[1 + i] >> 4) & 0xf) + '0';
  1244. // bms_data.bms_ids[2*i+1] = (Device1.vk_bms3.bms_id[1 + i] & 0xf )+ '0';
  1245. // }
  1246. bms_data.bms_ac = (short)(Device1.vk_bms2.current / 10);
  1247. bms_data.serial_num = FAC_VK_BMS;
  1248. // if( Device1.vk_bms3.bms_type_info[0] == 'S' && Device1.vk_bms3.bms_type_info[0] == 'H'
  1249. // && Device1.vk_bms3.bms_type_info[0] == 'A' && Device1.vk_bms3.bms_type_info[0] == '1')
  1250. // {
  1251. // bms_data.serial_num = 11; //???
  1252. // }
  1253. //厂家还没加
  1254. if(StrArrayNull( &bms_data.bms_ids[0], sizeof( bms_data.bms_ids ) ) == false && dev_bms1.regist.sn == false)
  1255. regist_dev_info(&dev_bms1,DEVICE_BMS1,false,(char *)bms_data.bms_ids,32,NULL,0,NULL,0,"vk",3);
  1256. }
  1257. else
  1258. {
  1259. memset( &Device1, 0, sizeof( Device1 ) );
  1260. }
  1261. //第二组电池
  1262. if ( Device2.Vkbms_Link.connect_status == COMP_NORMAL )
  1263. {
  1264. group_num = 2;
  1265. bms_data2.bms_cycle = Device2.vk_bms5.circulation_time;
  1266. bms_data2.bms_volt = Device2.vk_bms2.voltage;
  1267. bms_data2.bms_temp = Device2.vk_bms2.tempture;
  1268. bms_data2.bms_vs = Device2.vk_bms2.persent / 10;
  1269. bms_data2.bms_ss = Device2.vk_bms2.warn_flag;
  1270. bms_data2.bms_num = Device2.vk_bms2.bms_num;
  1271. memcpy(&bms_data2.bms_v1,&Device2.vk_bms2.bms_v1,26 * 2);
  1272. memcpy(&bms_data2.bms_ids[0],&Device2.vk_bms3.bms_id[0],20);
  1273. bms_data2.bms_ac = (short)(Device2.vk_bms2.current / 10);
  1274. bms_data2.serial_num = FAC_VK_BMS;
  1275. // if( Device2.vk_bms3.bms_type_info[0] == 'S' && Device2.vk_bms3.bms_type_info[0] == 'H'
  1276. // && Device2.vk_bms3.bms_type_info[0] == 'A' && Device2.vk_bms3.bms_type_info[0] == '1')
  1277. // {
  1278. // bms_data2.serial_num = 11; //???
  1279. // }
  1280. if(StrArrayNull( &bms_data2.bms_ids[0], sizeof( bms_data2.bms_ids ) ) == false && dev_bms2.regist.sn == false)
  1281. regist_dev_info(&dev_bms2,DEVICE_BMS2,false,(char *)bms_data2.bms_ids,32,NULL,0,NULL,0,"vk",3);
  1282. }
  1283. else
  1284. {
  1285. memset( &bms_data2, 0, sizeof( bms_data2 ) );
  1286. }
  1287. }
  1288. else
  1289. {
  1290. if ( Dev.Bms_Link.connect_status == COMP_NORMAL )
  1291. {
  1292. Dev.Bms_Link.connect_status = COMP_LOST;
  1293. //memset(&bms_data, 0, sizeof(bms_data));
  1294. //状态未置异常
  1295. bms_data.bms_ss = 0xFFFF;
  1296. }
  1297. }
  1298. }
  1299. /**
  1300. * @file bms_function
  1301. * @brief 智能电池检测函数
  1302. * @param none
  1303. * @details
  1304. * @author Zhang Sir
  1305. **/
  1306. void bms_function()
  1307. {
  1308. static uint32_t bms_time = 0;
  1309. static uint32_t bms_5hz_time = 0;
  1310. if(Check_Timer_Ready(&bms_time,_10_HZ_))
  1311. {
  1312. update_bms_data();
  1313. send_msg_to_VKbms();
  1314. }
  1315. if(Check_Timer_Ready(&bms_5hz_time,_5_HZ_))
  1316. {
  1317. //给智能电池发送上电信息
  1318. //send_msg_to_okcell();
  1319. send_msg_to_herewin();
  1320. }
  1321. }