can_process.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565
  1. #include "can_process.h"
  2. #include "usart.h"
  3. /**********局部函数定义**********/
  4. uint8_t cd_ReadChar(CAN_Buf_TypeDef * ptCANRx, uint8_t ucNum)
  5. {
  6. uint8_t ucData;
  7. uint16_t i;
  8. i = ucNum;
  9. if ((*ptCANRx).ucBufCnt >= ucNum)
  10. {
  11. i += (*ptCANRx).ucBufRdInde;
  12. if (i >= (*ptCANRx).ucBufSize)
  13. {
  14. i -=((*ptCANRx).ucBufSize);
  15. }
  16. }
  17. else
  18. {
  19. i=0;
  20. }
  21. ucData = *((*ptCANRx).pcBufAddr + i);
  22. return ucData;
  23. }
  24. void cd_DelChar(CAN_Buf_TypeDef * ptCANRx, uint8_t ucNum)
  25. {
  26. uint16_t i;
  27. if ((*ptCANRx).ucBufCnt >= ucNum)
  28. {
  29. __HAL_CAN_DISABLE_IT(&hcan, CAN_IT_FMP0);//关接收中断
  30. (*ptCANRx).ucBufCnt -= ucNum;
  31. __HAL_CAN_ENABLE_IT(&hcan, CAN_IT_FMP0);//开接收中断
  32. i = ucNum;
  33. i += (*ptCANRx).ucBufRdInde;
  34. if (i >= (*ptCANRx).ucBufSize)
  35. {
  36. i -= (*ptCANRx).ucBufSize;
  37. }
  38. (*ptCANRx).ucBufRdInde = i;
  39. }
  40. else
  41. {
  42. __HAL_CAN_DISABLE_IT(&hcan, CAN_IT_FMP0);//关接收中断
  43. i = (*ptCANRx).ucBufCnt;
  44. (*ptCANRx).ucBufCnt = 0;
  45. __HAL_CAN_ENABLE_IT(&hcan, CAN_IT_FMP0);//开接收中断
  46. i += (*ptCANRx).ucBufRdInde;
  47. if (i >= (*ptCANRx).ucBufSize)
  48. {
  49. i -= (*ptCANRx).ucBufSize;
  50. }
  51. (*ptCANRx).ucBufRdInde = i;
  52. }
  53. }
  54. //数据解析处理
  55. void DataProcess(uint16_t ID, uint8_t Mode, uint16_t Cmd, uint8_t* Data)
  56. {
  57. uint8_t DataLength;
  58. DataLength = (uint8_t)(Cmd &0x00FF);
  59. switch(ID)
  60. {
  61. //处理MC发送的指令
  62. case ID_MC_BC:
  63. case ID_MC_TO_PBU:
  64. {
  65. PowerOn_flag=1;
  66. MC_Online_Flag=1;
  67. MC_Online_TimeCnt=SysTime_5ms;
  68. switch(Cmd)
  69. {
  70. //MC广播的指令
  71. case 0x1020://MC广播运行信息
  72. {
  73. memcpy((uint8_t*)&MC_RunInfo.BikeSpeed, Data, sizeof(MC_RunInfo_Struct_t));
  74. break;
  75. }
  76. case 0x1104://MC广播故障码
  77. {
  78. MC_error_cnt=0;
  79. memcpy((uint8_t*)&MC_ErrorCode.Code, Data, sizeof(MC_ErrorCode_Struct_t));
  80. break;
  81. }
  82. case 0x1305://MC关机就绪
  83. {
  84. if(strncmp("READY", (char*)Data, DataLength) == 0)
  85. {
  86. PBU_PowerOff_Process.Ready_Status.Status_Bit.MC = 1;
  87. }
  88. break;
  89. }
  90. //MC发送给PBU的指令
  91. case 0x5009://在线检测
  92. {
  93. if(strncmp("HANDSHAKE", (char*)Data, DataLength) == 0)
  94. {
  95. SendData(ID_PBU_TO_MC, MODE_REPORT, 0x3105, (uint8_t*)"READY");
  96. }
  97. break;
  98. }
  99. case 0x5100://查询物理ID
  100. {
  101. SendData(ID_PBU_BC, MODE_REPORT, 0x120C, (uint8_t*)PBU_CheckInfo.MAC_ID);
  102. break;
  103. }
  104. case 0x5200://查询校验码
  105. {
  106. SendData(ID_PBU_BC, MODE_REPORT, 0x130C, (uint8_t*)PBU_CheckInfo.CheckCode);
  107. break;
  108. }
  109. case 0x5303://用户参数配置反馈
  110. {
  111. if(strncmp("ACK", (char*)Data, DataLength) == 0)
  112. {
  113. PBU_MC_Cfg.MC_ACK_Flag = TRUE;
  114. }
  115. break;
  116. }
  117. default:break;
  118. }
  119. break;
  120. }
  121. //处理BMS发送的指令
  122. case ID_BMS_BC:
  123. case ID_BMS_TO_PBU:
  124. {
  125. BMS_Online_Flag = 1;
  126. BMS_Online_TimeCnt=SysTime_5ms;
  127. switch(Cmd)
  128. {
  129. //BMS广播的指令
  130. case 0x1010://BMS广播运行信息
  131. {
  132. memcpy((uint8_t*)&BMS_RunInfo.Voltage, Data, sizeof(BMS_RunInfo_Struct_t));
  133. if(BMS_RunInfo.Status.Status_Bit.Charge == 0x01) //电池连续发送7次进入充电状态,按键才进入充电状态
  134. {
  135. BMS_Charging_count++;
  136. if(BMS_Charging_count>6)
  137. {
  138. BMS_Charging_count=0;
  139. BMS_ChargingFlag = TRUE;
  140. }
  141. }
  142. else
  143. {
  144. BMS_Charging_count=0;
  145. BMS_ChargingFlag = FALSE;
  146. }
  147. break;
  148. }
  149. case 0x1204://BMS广播故障码
  150. {
  151. memcpy((uint8_t*)&BMS_ErrorCode.Code, Data, sizeof(BMS_ErrorCode_Struct_t));
  152. break;
  153. }
  154. case 0x1308://BMS广播关机指令
  155. {
  156. if(strncmp("SHUTDOWN", (char*)Data, DataLength) == 0)
  157. {
  158. //...处理存储关键信息
  159. SendData(ID_PBU_BC, MODE_REPORT, 0x1405, (uint8_t*)"READY");
  160. }
  161. break;
  162. }
  163. }
  164. break;
  165. }
  166. //处理HMI发送的指令
  167. case ID_HMI_BC:
  168. case ID_HMI_TO_PBU:
  169. //处理CDL发送的指令
  170. case ID_CDL_BC:
  171. case ID_CDL_TO_PBU:
  172. {
  173. switch(Cmd)
  174. {
  175. case 0x5000://查询PBU物理ID
  176. {
  177. SendData(ID_PBU_BC, MODE_REPORT, 0x120C, (uint8_t*)(PBU_CheckInfo.MAC_ID));
  178. break;
  179. }
  180. case 0x5100://查询校验码
  181. {
  182. SendData(ID_PBU_BC, MODE_REPORT, 0x130C, (uint8_t*)PBU_CheckInfo.CheckCode);
  183. break;
  184. }
  185. case 0x520C://写入校验码
  186. {
  187. if(strncmp((char*)PBU_CheckInfo.CheckCode, (char*)Data, DataLength) != 0)
  188. {
  189. memcpy(PBU_CheckInfo.CheckCode, Data, 12);
  190. EEPROM_DataUpdate();
  191. }
  192. SendData(ID_PBU_TO_CDL, MODE_REPORT, 0x9003, (uint8_t*)"ACK");
  193. break;
  194. }
  195. case 0x5300://查询PBU生产信息
  196. {
  197. SendData(ID_PBU_TO_CDL, MODE_REPORT, 0x9420, (uint8_t*)PBU_MacInfo.Manufacturer);
  198. break;
  199. }
  200. case 0x5400://查询PBU版本信息
  201. {
  202. SendData(ID_PBU_BC, MODE_REPORT, 0x1140, (uint8_t*)PBU_VerInfo.Mode);
  203. break;
  204. }
  205. case 0x5504://进入按键测试模式
  206. {
  207. if(strncmp("STAR", (char*)Data, DataLength) == 0)
  208. {
  209. PBU_RunMode = PBU_RunMode_CDL_KeyTest;
  210. SendData(ID_PBU_TO_CDL, MODE_REPORT, 0x9003, (uint8_t*)"ACK");
  211. }
  212. else if(strncmp("STOP", (char*)Data, DataLength) == 0)
  213. {
  214. PBU_RunMode = PBU_RunMode_MC_AssisitCtrl;
  215. SendData(ID_PBU_TO_CDL, MODE_REPORT, 0x9003, (uint8_t*)"ACK");
  216. }
  217. break;
  218. }
  219. case 0x5600://查询PBU历史信息
  220. {
  221. SendData(ID_PBU_TO_CDL, MODE_REPORT, 0x9310, (uint8_t*)&PBU_RunLog.RunTime);
  222. break;
  223. }
  224. case 0x5700://查询PBU出厂参数
  225. {
  226. SendData(ID_PBU_TO_CDL, MODE_REPORT, 0x9210, &PBU_ConfigParam.RatedVoltage);
  227. break;
  228. }
  229. case 0x5810://写入PBU出厂参数
  230. {
  231. if(strncmp((char*)&PBU_ConfigParam.RatedVoltage, (char*)Data, DataLength) != 0)
  232. {
  233. memcpy(&PBU_ConfigParam.RatedVoltage, Data, 16);
  234. EEPROM_DataUpdate();
  235. }
  236. SendData(ID_PBU_TO_CDL, MODE_REPORT, 0x9003, (uint8_t*)"ACK");
  237. break;
  238. }
  239. case 0x5900://查询自定义字符串1
  240. {
  241. SendData(ID_PBU_TO_CDL, MODE_REPORT, 0x9510, (uint8_t*)UserString1);
  242. break;
  243. }
  244. case 0x5A10://写入自定义字符串1
  245. {
  246. if(strncmp((char*)UserString1, (char*)Data, DataLength) != 0)
  247. {
  248. memcpy(UserString1, Data, 16);
  249. EEPROM_DataUpdate();
  250. }
  251. SendData(ID_PBU_TO_CDL, MODE_REPORT, 0x9003, (uint8_t*)"ACK");
  252. break;
  253. }
  254. case 0x5B00://查询自定义字符串2
  255. {
  256. SendData(ID_PBU_TO_CDL, MODE_REPORT, 0x9610, (uint8_t*)UserString2);
  257. break;
  258. }
  259. case 0x5C10://写入自定义字符串2
  260. {
  261. if(strncmp((char*)UserString2, (char*)Data, DataLength) != 0)
  262. {
  263. memcpy(UserString2, Data, 16);
  264. EEPROM_DataUpdate();
  265. }
  266. SendData(ID_PBU_TO_CDL, MODE_REPORT, 0x9003, (uint8_t*)"ACK");
  267. break;
  268. }
  269. case 0x5D00://查询自定义字符串3
  270. {
  271. SendData(ID_PBU_TO_CDL, MODE_REPORT, 0x9710, (uint8_t*)UserString3);
  272. break;
  273. }
  274. case 0x5E10://写入自定义字符串3
  275. {
  276. if(strncmp((char*)UserString3, (char*)Data, DataLength) != 0)
  277. {
  278. memcpy(UserString3, Data, 16);
  279. EEPROM_DataUpdate();
  280. }
  281. SendData(ID_PBU_TO_CDL, MODE_REPORT, 0x9003, (uint8_t*)"ACK");
  282. break;
  283. }
  284. case 0x5F20://写入生产信息
  285. {
  286. if(strncmp((char*)PBU_MacInfo.Manufacturer, (char*)Data, DataLength) != 0)
  287. {
  288. memcpy(PBU_MacInfo.Manufacturer, Data, 32);
  289. EEPROM_DataUpdate();
  290. }
  291. SendData(ID_PBU_TO_CDL, MODE_REPORT, 0x9003, (uint8_t*)"ACK");
  292. break;
  293. }
  294. case 0x6010://写入Mode
  295. {
  296. if(strncmp((char*)PBU_VerInfo.Mode, (char*)Data, DataLength) != 0)
  297. {
  298. memcpy(PBU_VerInfo.Mode, Data, 16);
  299. EEPROM_DataUpdate();
  300. }
  301. SendData(ID_PBU_TO_CDL, MODE_REPORT, 0x9003, (uint8_t*)"ACK");
  302. break;
  303. }
  304. case 0x6110://写入SN
  305. {
  306. if(strncmp((char*)PBU_VerInfo.SN_Num, (char*)Data, DataLength) != 0)
  307. {
  308. memcpy(PBU_VerInfo.SN_Num, Data, 16);
  309. EEPROM_DataUpdate();
  310. }
  311. SendData(ID_PBU_TO_CDL, MODE_REPORT, 0x9003, (uint8_t*)"ACK");
  312. break;
  313. }
  314. case 0x6205://复位指令
  315. {
  316. if(strncmp("RESET", (char*)Data, DataLength) == 0)
  317. {
  318. SendData(ID_PBU_TO_CDL, MODE_REPORT, 0x9003, (uint8_t*)"ACK");
  319. HAL_Delay(200);
  320. __set_FAULTMASK(1);//关闭所有中断
  321. HAL_NVIC_SystemReset();
  322. }
  323. break;
  324. }
  325. }
  326. break;
  327. }
  328. case ID_CDL_TO_PBU_TE://0x653
  329. {
  330. switch(Cmd)
  331. {
  332. case 0x6205://复位指令
  333. case 0xA10B://升级指令
  334. PBU_TE_Status = UPDATE_ING;
  335. PBU_RunMode = PBU_RunMode_Updating;
  336. break;
  337. default:
  338. break;
  339. }
  340. SendUartDataToTE(ID_CDL_TO_PBU_TE,Mode, Cmd, Data);
  341. break;
  342. }
  343. default:
  344. break;
  345. }
  346. }
  347. /*********************End*******************/
  348. /************全局函数定义*******************/
  349. void CAN_RxData_Process(CAN_Buf_TypeDef* ptCANRx, uint16_t TimeOutCnt)
  350. {
  351. uint8_t Mode, CmdLength, DataLength, Data[150], CRC_Buf[150];
  352. uint16_t Cmd, i;
  353. uint32_t CrcResult, CrcData;
  354. uint8_t FrameBegin1, FrameBegin2;
  355. if(ptCANRx->ucBufCnt >= 11)
  356. {
  357. //读取帧头
  358. FrameBegin1 = cd_ReadChar(ptCANRx, 0);
  359. CRC_Buf[0] = FrameBegin1;
  360. FrameBegin2 = cd_ReadChar(ptCANRx, 1);
  361. CRC_Buf[1] = FrameBegin2;
  362. if((FrameBegin1 == FRAME_BEGIN1) && (FrameBegin2 == FRAME_BEGIN2))
  363. {
  364. CRC_Buf[2] = (uint8_t)((ptCANRx->ucBufID >> 8) & 0xFF);
  365. CRC_Buf[3] = (uint8_t)(ptCANRx->ucBufID & 0xFF);
  366. //读取帧模式
  367. Mode = cd_ReadChar(ptCANRx, 2);
  368. CRC_Buf[4] = Mode;
  369. if((Mode == MODE_READ) || (Mode == MODE_WRITE) || (Mode == MODE_REPORT))
  370. {
  371. //读取命令段长度和命令字
  372. CmdLength = cd_ReadChar(ptCANRx, 3);
  373. CRC_Buf[5] = CmdLength;
  374. Cmd = (cd_ReadChar(ptCANRx, 4) << 8) + cd_ReadChar(ptCANRx, 5);
  375. CRC_Buf[6] = (uint8_t)((Cmd >> 8) & 0xFF);
  376. CRC_Buf[7] = (uint8_t)(Cmd & 0xFF);
  377. DataLength = cd_ReadChar(ptCANRx, 5);
  378. if((CmdLength - DataLength) == 2)
  379. {
  380. if(ptCANRx->ucBufCnt < (CmdLength + 9))//帧头2bytes + 模式1byte + 命令段长度1byte + 校验位4bytes + 帧尾1byte
  381. {
  382. if(ptCANRx->IsWaitRX_Flag == FALSE)
  383. {
  384. ptCANRx->DelayTimeCnt = HAL_GetTick();
  385. ptCANRx->IsWaitRX_Flag = TRUE;
  386. }
  387. if((HAL_GetTick() - ptCANRx->DelayTimeCnt) > TimeOutCnt)//超时,单位ms
  388. {
  389. cd_DelChar(ptCANRx, ptCANRx->ucBufCnt);
  390. ptCANRx->IsWaitRX_Flag = FALSE;
  391. }
  392. return;
  393. }
  394. else
  395. {
  396. ptCANRx->IsWaitRX_Flag = FALSE;
  397. //接收到完整正确数据包
  398. for(i=0; i<DataLength; i++)//读取数据段
  399. {
  400. Data[i] = cd_ReadChar(ptCANRx, 6 + i);
  401. CRC_Buf[8 + i] = Data[i];
  402. }
  403. CrcData = (cd_ReadChar(ptCANRx, 6 + DataLength) << 24) + \
  404. (cd_ReadChar(ptCANRx, 7 + DataLength) << 16) + \
  405. (cd_ReadChar(ptCANRx, 8 + DataLength) << 8) + \
  406. cd_ReadChar(ptCANRx, 9 + DataLength);
  407. CrcResult = CRC32_Calculate(CRC_Buf, 8 + DataLength);
  408. if((CrcData - CrcResult) == 0) // 比较校验
  409. {
  410. //数据处理
  411. DataProcess(ptCANRx->ucBufID, Mode, Cmd, Data);//Mode为帧模式,Cmd为命令字,Data为数据段
  412. cd_DelChar(ptCANRx, CmdLength + 9);
  413. return;
  414. }
  415. cd_DelChar(ptCANRx, 1);
  416. }
  417. }
  418. else
  419. {
  420. cd_DelChar(ptCANRx, 1);
  421. }
  422. }
  423. else
  424. {
  425. cd_DelChar(ptCANRx, 1);
  426. }
  427. }
  428. else
  429. {
  430. cd_DelChar(ptCANRx, 1);
  431. }
  432. }
  433. }
  434. //数据解析,忽略命令字表示的数据长度
  435. void CAN_RxData_Process_Temp(CAN_Buf_TypeDef* ptCANRx, uint16_t TimeOutCnt)
  436. {
  437. uint8_t Mode, CmdLength, DataLength, Data[150], CRC_Buf[150];
  438. uint16_t Cmd, i;
  439. uint32_t CrcResult, CrcData;
  440. uint8_t FrameBegin1, FrameBegin2;
  441. if(ptCANRx->ucBufCnt >= 11)
  442. {
  443. //读取帧头
  444. FrameBegin1 = cd_ReadChar(ptCANRx, 0);
  445. CRC_Buf[0] = FrameBegin1;
  446. FrameBegin2 = cd_ReadChar(ptCANRx, 1);
  447. CRC_Buf[1] = FrameBegin2;
  448. if((FrameBegin1 == FRAME_BEGIN1) && (FrameBegin2 == FRAME_BEGIN2))
  449. {
  450. CRC_Buf[2] = (uint8_t)((ptCANRx->ucBufID >> 8) & 0xFF);
  451. CRC_Buf[3] = (uint8_t)(ptCANRx->ucBufID & 0xFF);
  452. //读取帧模式
  453. Mode = cd_ReadChar(ptCANRx, 2);
  454. CRC_Buf[4] = Mode;
  455. if((Mode == MODE_READ) || (Mode == MODE_WRITE) || (Mode == MODE_REPORT))
  456. {
  457. //读取命令段长度和命令字
  458. CmdLength = cd_ReadChar(ptCANRx, 3);
  459. CRC_Buf[5] = CmdLength;
  460. Cmd = (cd_ReadChar(ptCANRx, 4) << 8) + cd_ReadChar(ptCANRx, 5);
  461. CRC_Buf[6] = (uint8_t)((Cmd >> 8) & 0xFF);
  462. CRC_Buf[7] = (uint8_t)(Cmd & 0xFF);
  463. DataLength = CmdLength - 2;
  464. if(ptCANRx->ucBufCnt < (CmdLength + 9))//帧头2bytes + 模式1byte + 命令段长度1byte + 校验位4bytes + 帧尾1byte
  465. {
  466. if(ptCANRx->IsWaitRX_Flag == FALSE)
  467. {
  468. ptCANRx->DelayTimeCnt = HAL_GetTick();
  469. ptCANRx->IsWaitRX_Flag = TRUE;
  470. }
  471. if((HAL_GetTick() - ptCANRx->DelayTimeCnt) > TimeOutCnt)//超时,单位ms
  472. {
  473. cd_DelChar(ptCANRx, ptCANRx->ucBufCnt);
  474. ptCANRx->IsWaitRX_Flag = FALSE;
  475. }
  476. return;
  477. }
  478. else
  479. {
  480. ptCANRx->IsWaitRX_Flag = FALSE;
  481. //接收到完整正确数据包
  482. for(i=0; i<DataLength; i++)//读取数据段
  483. {
  484. Data[i] = cd_ReadChar(ptCANRx, 6 + i);
  485. CRC_Buf[8 + i] = Data[i];
  486. }
  487. CrcData = (cd_ReadChar(ptCANRx, 6 + DataLength) << 24) + \
  488. (cd_ReadChar(ptCANRx, 7 + DataLength) << 16) + \
  489. (cd_ReadChar(ptCANRx, 8 + DataLength) << 8) + \
  490. cd_ReadChar(ptCANRx, 9 + DataLength);
  491. CrcResult = CRC32_Calculate(CRC_Buf, 8 + DataLength);
  492. if((CrcData - CrcResult) == 0) // 比较校验
  493. {
  494. //数据处理
  495. DataProcess(ptCANRx->ucBufID, Mode, Cmd, Data);//Mode为帧模式,Cmd为命令字,Data为数据段
  496. cd_DelChar(ptCANRx, CmdLength + 9);
  497. return;
  498. }
  499. cd_DelChar(ptCANRx, 1);
  500. }
  501. }
  502. else
  503. {
  504. cd_DelChar(ptCANRx, 1);
  505. }
  506. }
  507. else
  508. {
  509. cd_DelChar(ptCANRx, 1);
  510. }
  511. }
  512. }
  513. void SendData(uint16_t ID, uint8_t Mode, uint16_t Command, uint8_t* Data)
  514. {
  515. uint8_t SendBuf[150] = {0};
  516. uint8_t CRC_Buf[150] = {0};
  517. uint32_t CRC_Result = 0x00000000;
  518. uint8_t i;
  519. uint8_t DataLength;
  520. DataLength = (uint8_t)(Command & 0xFF);
  521. SendBuf[0] = FRAME_BEGIN1;
  522. CRC_Buf[0] = SendBuf[0];
  523. SendBuf[1] = FRAME_BEGIN2;
  524. CRC_Buf[1] = SendBuf[1];
  525. CRC_Buf[2] = (uint8_t)((ID >> 8) & 0xFF);
  526. CRC_Buf[3] = (uint8_t)(ID & 0xFF);
  527. SendBuf[2] = Mode;
  528. CRC_Buf[4] = SendBuf[2];
  529. SendBuf[3] = DataLength + 2;
  530. CRC_Buf[5] = SendBuf[3];
  531. SendBuf[4] = (uint8_t)((Command >> 8) & 0xFF);
  532. CRC_Buf[6] = SendBuf[4];
  533. SendBuf[5] = DataLength;
  534. CRC_Buf[7] = SendBuf[5];
  535. for(i = 0;i< DataLength;i++)
  536. {
  537. SendBuf[6 + i] = Data[i];
  538. CRC_Buf[8 + i] = SendBuf[6 + i];
  539. }
  540. CRC_Result = CRC32_Calculate(CRC_Buf, DataLength + 8);//帧头 2bytes + ID 2bytes + 模式 1byte + 命令段长度 1byte + 命令字 2bytes
  541. SendBuf[6 + DataLength] = (uint8_t)((CRC_Result >> 24) & 0xFF);
  542. SendBuf[7 + DataLength] = (uint8_t)((CRC_Result >> 16) & 0xFF);
  543. SendBuf[8 + DataLength] = (uint8_t)((CRC_Result >> 8) & 0xFF);
  544. SendBuf[9 + DataLength] = (uint8_t)(CRC_Result & 0xFF);
  545. SendBuf[10 + DataLength] = FRAME_END;
  546. CAN_SendData(ID, SendBuf, DataLength + 11);
  547. }
  548. /********************End********************/