can_process.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674
  1. #include "can_process.h"
  2. #include "uart_process.h"
  3. #include "motor_control.h"
  4. #include "crc_cal.h"
  5. #include "var.h"
  6. #include "eeprom_24c02.h"
  7. #include "eeprom_flash.h"
  8. #include "tasks.h"
  9. /**********局部函数定义**********/
  10. uint8_t cd_ReadChar(CAN_Buf_TypeDef * ptCANRx, uint8_t ucNum)
  11. {
  12. uint8_t ucData;
  13. uint16_t i;
  14. i = ucNum;
  15. if ((*ptCANRx).ucBufCnt >= ucNum)
  16. {
  17. i += (*ptCANRx).ucBufRdInde;
  18. if (i >= (*ptCANRx).ucBufSize)
  19. {
  20. i -=((*ptCANRx).ucBufSize);
  21. }
  22. }
  23. else
  24. {
  25. i=0;
  26. }
  27. ucData = *((*ptCANRx).pcBufAddr + i);
  28. return ucData;
  29. }
  30. void cd_DelChar(CAN_Buf_TypeDef * ptCANRx, uint8_t ucNum)
  31. {
  32. uint16_t i;
  33. if ((*ptCANRx).ucBufCnt >= ucNum)
  34. {
  35. __HAL_CAN_DISABLE_IT(&hcan, CAN_IT_FMP0);//关接收中断
  36. (*ptCANRx).ucBufCnt -= ucNum;
  37. __HAL_CAN_ENABLE_IT(&hcan, CAN_IT_FMP0);//开接收中断
  38. i = ucNum;
  39. i += (*ptCANRx).ucBufRdInde;
  40. if (i >= (*ptCANRx).ucBufSize)
  41. {
  42. i -= (*ptCANRx).ucBufSize;
  43. }
  44. (*ptCANRx).ucBufRdInde = i;
  45. }
  46. else
  47. {
  48. __HAL_CAN_DISABLE_IT(&hcan, CAN_IT_FMP0);//关接收中断
  49. i = (*ptCANRx).ucBufCnt;
  50. (*ptCANRx).ucBufCnt = 0;
  51. __HAL_CAN_ENABLE_IT(&hcan, CAN_IT_FMP0);//开接收中断
  52. i += (*ptCANRx).ucBufRdInde;
  53. if (i >= (*ptCANRx).ucBufSize)
  54. {
  55. i -= (*ptCANRx).ucBufSize;
  56. }
  57. (*ptCANRx).ucBufRdInde = i;
  58. }
  59. }
  60. //数据解析处理
  61. void DataProcess(uint16_t ID, uint8_t Mode, uint16_t Cmd, uint8_t* Data)
  62. {
  63. uint8_t DataLength;
  64. DataLength = (uint8_t)(Cmd &0x00FF);
  65. switch(ID)
  66. {
  67. //处理BMS发送的指令
  68. case ID_BMS_BC: case ID_BMS_TO_MC:
  69. {
  70. switch(Cmd)
  71. {
  72. //BMS广播的指令
  73. case 0x1010://BMS运行信息
  74. {
  75. //更新电池运行信息
  76. memcpy(&BMS_RunInfo.Voltage, Data, DataLength);
  77. //电池通信正常标志置位,用于续航计算
  78. RemainDis.IsBMS_ComOK_Flag = TRUE;
  79. RemainDis.BMS_Com_DelayTimeCnt = HAL_GetTick();
  80. //BMS通信正常标志置位
  81. IsComOK_BMS.IsOK_Flag = TRUE;
  82. IsComOK_BMS.OK_TrigTime = HAL_GetTick();
  83. break;
  84. }
  85. case 0x1308://关机指令
  86. {
  87. PowerOff_Process();
  88. break;
  89. }
  90. case 0x1410://电池设计信息
  91. {
  92. memcpy(&BMS_DesignInfo.Capacity, Data, DataLength);
  93. break;
  94. }
  95. case 0x160C://电池物理ID
  96. {
  97. memcpy(BMS_CheckInfo.MAC_ID, Data, DataLength);
  98. break;
  99. }
  100. case 0x170C://电池存储的校验码
  101. {
  102. memcpy(BMS_CheckInfo.CheckCode, Data, DataLength);
  103. break;
  104. }
  105. //BMS发送给MC的指令
  106. case 0x3005://电池在线检测反馈
  107. {
  108. if(strncmp("READY", (char*)Data, DataLength) == 0)
  109. {
  110. DeviceOnLine_Status.Status_Bit.BMS_OffLine = 0;
  111. }
  112. break;
  113. }
  114. default:break;
  115. }
  116. break;
  117. }
  118. //处理PBU发送的指令
  119. case ID_PBU_BC: case ID_PBU_TO_MC:
  120. {
  121. switch(Cmd)
  122. {
  123. //PBU广播的指令
  124. case 0x1008://PBU关机指令
  125. {
  126. PowerOff_Process();
  127. break;
  128. }
  129. case 0x120C://PBU物理ID
  130. {
  131. memcpy(PBU_CheckInfo.MAC_ID, Data, DataLength);
  132. break;
  133. }
  134. case 0x130C://PBU存储的校验码
  135. {
  136. memcpy(PBU_CheckInfo.CheckCode, Data, DataLength);
  137. break;
  138. }
  139. //PBU发送给MC的指令
  140. case 0x3002://控制电机指令
  141. {
  142. memcpy(&MC_ControlCode.GearSt, Data, DataLength);
  143. Update_MC_ControlCode_Back();
  144. MC_RunInfo.GearSt = MC_ControlCode.GearSt;//当前助力档位更新
  145. SendData(ID_MC_BC, MODE_REPORT, 0x1020, (uint8_t*)&MC_RunInfo.BikeSpeed);
  146. //PBU通信正常标志置位
  147. IsComOK_PBU.IsOK_Flag = TRUE;
  148. IsComOK_PBU.OK_TrigTime = HAL_GetTick();
  149. break;
  150. }
  151. case 0x3105://PBU在线检测反馈
  152. {
  153. if(strncmp("READY", (char*)Data, DataLength) == 0)
  154. {
  155. DeviceOnLine_Status.Status_Bit.PBU_OffLine = 0;
  156. }
  157. break;
  158. }
  159. case 0x3208://控制参数配置
  160. {
  161. memcpy(&PBU_ConfigParam.GearsNum, Data, DataLength);
  162. SendData(ID_MC_TO_PBU, MODE_REPORT, 0x5303, (uint8_t*)"ACK");
  163. break;
  164. }
  165. default:break;
  166. }
  167. break;
  168. }
  169. //处理HMI发送的指令
  170. case ID_HMI_BC: case ID_HMI_TO_MC:
  171. {
  172. switch(Cmd)
  173. {
  174. //HMI广播的指令
  175. case 0x110C://HMI物理ID
  176. {
  177. memcpy(HMI_CheckInfo.MAC_ID, Data, DataLength);
  178. break;
  179. }
  180. case 0x120C://HMI存储的校验码
  181. {
  182. memcpy(HMI_CheckInfo.CheckCode, Data, DataLength);
  183. break;
  184. }
  185. case 0x1508://HMI运行信息
  186. {
  187. //HMI通信正常标志置位
  188. IsComOK_HMI.IsOK_Flag = TRUE;
  189. IsComOK_HMI.OK_TrigTime = HAL_GetTick();
  190. break;
  191. }
  192. //HMI发送MC的指令
  193. case 0x3000://查询电机版本信息
  194. {
  195. ReadDataFromEEPROM_Flash(EEPROM_FLASH_ADDR_MODE, (uint8_t*)MC_VerInfo.Mode, 16);
  196. ReadDataFromEEPROM_Flash(EEPROM_FLASH_ADDR_SN, (uint8_t*)MC_VerInfo.SN_Num, 16);
  197. SendData(ID_MC_BC, MODE_REPORT, 0x1240, (uint8_t*)MC_VerInfo.Mode);
  198. break;
  199. }
  200. case 0x3100://查询电机配置参数
  201. {
  202. GetParamFromEEprom_24C02(&I2C_Handle_EEPROM, EEPROM_24C02_ADDR_CONFIG_PARAM, sizeof(MC_ConfigParam), &MC_ConfigParam.RS1);
  203. Data[0] = MC_ConfigParam.WheelSize;
  204. Data[1] = MC_ConfigParam.StarModel;
  205. SendData(ID_MC_TO_HMI, MODE_REPORT, 0x7308, Data);
  206. break;
  207. }
  208. case 0x3208://设置电机配置参数
  209. {
  210. MC_ConfigParam.WheelSize = Data[0];
  211. MC_ConfigParam.StarModel = (MC_StarMode_Struct_t)Data[1];
  212. SaveParamToEEprom_24C02(&I2C_Handle_EEPROM, EEPROM_24C02_ADDR_CONFIG_PARAM, sizeof(MC_ConfigParam), &MC_ConfigParam.RS1);
  213. SendData(ID_MC_TO_HMI, MODE_REPORT, 0x7403, (uint8_t*)"ACK");
  214. break;
  215. }
  216. case 0x3305://HMI在线检测反馈
  217. {
  218. if(strncmp("READY", (char*)Data, DataLength) == 0)
  219. {
  220. DeviceOnLine_Status.Status_Bit.HMI_OffLine = 0;
  221. }
  222. break;
  223. }
  224. default:break;
  225. }
  226. break;
  227. }
  228. //处理CDL发送的指令
  229. case ID_CDL_BC: case ID_CDL_TO_MC:
  230. {
  231. switch(Cmd)
  232. {
  233. case 0x1000://查询校验密钥
  234. {
  235. GetParamFromEEprom_24C02(&I2C_Handle_EEPROM, EEPROM_24C02_ADDR_SECRET_KEY, sizeof(Secret_Key), Secret_Key);
  236. SendData(ID_MC_TO_CDL, MODE_REPORT, 0xA408, Secret_Key);
  237. break;
  238. }
  239. case 0x1108://写入校验密钥
  240. {
  241. memcpy(Secret_Key, Data, DataLength);
  242. SaveParamToEEprom_24C02(&I2C_Handle_EEPROM, EEPROM_24C02_ADDR_SECRET_KEY, sizeof(Secret_Key), Secret_Key);
  243. SendData(ID_MC_BC, MODE_REPORT, 0xA903, (uint8_t*)"ACK");
  244. break;
  245. }
  246. case 0x1200://查询电机版本信息
  247. {
  248. ReadDataFromEEPROM_Flash(EEPROM_FLASH_ADDR_MODE, (uint8_t*)MC_VerInfo.Mode, 16);
  249. ReadDataFromEEPROM_Flash(EEPROM_FLASH_ADDR_SN, (uint8_t*)MC_VerInfo.SN_Num, 16);
  250. SendData(ID_MC_BC, MODE_REPORT, 0x1240, (uint8_t*)MC_VerInfo.Mode);
  251. break;
  252. }
  253. case 0x1300://查询自定义字符串1
  254. {
  255. ReadDataFromEEPROM_Flash(EEPROM_FLASH_ADDR_USER_INFO1, UserString1, 16);
  256. SendData(ID_MC_TO_CDL, MODE_REPORT, 0xA610, UserString1);
  257. break;
  258. }
  259. case 0x1410://写入自定义字符串1
  260. {
  261. memcpy(UserString1, Data, DataLength);
  262. EEPROM_Flash_DataUpdate();
  263. SendData(ID_MC_BC, MODE_REPORT, 0xA903, (uint8_t*)"ACK");
  264. break;
  265. }
  266. case 0x1500://查询自定义字符串2
  267. {
  268. ReadDataFromEEPROM_Flash(EEPROM_FLASH_ADDR_USER_INFO2, UserString2, 16);
  269. SendData(ID_MC_TO_CDL, MODE_REPORT, 0xA710, UserString2);
  270. break;
  271. }
  272. case 0x1610://写入自定义字符串2
  273. {
  274. memcpy(UserString2, Data, DataLength);
  275. EEPROM_Flash_DataUpdate();
  276. SendData(ID_MC_BC, MODE_REPORT, 0xA903, (uint8_t*)"ACK");
  277. break;
  278. }
  279. case 0x1700://查询自定义字符串3
  280. {
  281. ReadDataFromEEPROM_Flash(EEPROM_FLASH_ADDR_USER_INFO3, UserString3, 16);
  282. SendData(ID_MC_TO_CDL, MODE_REPORT, 0xA810, UserString3);
  283. break;
  284. }
  285. case 0x1810://写入自定义字符串3
  286. {
  287. memcpy(UserString3, Data, DataLength);
  288. EEPROM_Flash_DataUpdate();
  289. SendData(ID_MC_BC, MODE_REPORT, 0xA903, (uint8_t*)"ACK");
  290. break;
  291. }
  292. case 0x1901://写入电机工作模式
  293. {
  294. MC_WorkMode = (MC_WorkMode_Struct_t)*Data;
  295. MC_WorkMode_Back = (MC_WorkMode_Struct_t)~MC_WorkMode;
  296. break;
  297. }
  298. case 0x1A00://查询电机控制参数
  299. {
  300. GetParamFromEEprom_24C02(&I2C_Handle_EEPROM, EEPROM_24C02_ADDR_CONFIG_PARAM, sizeof(MC_ConfigParam), &MC_ConfigParam.RS1);
  301. SendData(ID_MC_TO_CDL, MODE_REPORT, 0xA020, &MC_ConfigParam.RS1);
  302. break;
  303. }
  304. case 0x1B20://写入电机控制参数
  305. {
  306. memcpy(&MC_ConfigParam.RS1, Data, DataLength);
  307. SaveParamToEEprom_24C02(&I2C_Handle_EEPROM, EEPROM_24C02_ADDR_CONFIG_PARAM, sizeof(MC_ConfigParam), &MC_ConfigParam.RS1);
  308. //助力参数初始化
  309. UpdateGearParam(MC_ConfigParam.SerialNum);
  310. SendData(ID_MC_TO_CDL, MODE_REPORT, 0xA903, (uint8_t*)"ACK");
  311. break;
  312. }
  313. case 0x1C00://查询马达参数
  314. {
  315. GetParamFromEEprom_24C02(&I2C_Handle_EEPROM, EEPROM_24C02_ADDR_MOTOR_PARAM, sizeof(MC_MotorParam), (uint8_t*)&MC_MotorParam.Rate_Power);
  316. SendData(ID_MC_TO_CDL, MODE_REPORT, 0xA110, (uint8_t*)&MC_MotorParam.Rate_Power);
  317. break;
  318. }
  319. case 0x1D10://写入马达参数
  320. {
  321. memcpy((uint8_t*)&MC_MotorParam.Rate_Power, Data, DataLength);
  322. SaveParamToEEprom_24C02(&I2C_Handle_EEPROM, EEPROM_24C02_ADDR_MOTOR_PARAM, sizeof(MC_MotorParam), (uint8_t*)&MC_MotorParam.Rate_Power);
  323. SendData(ID_MC_TO_CDL, MODE_REPORT, 0xA903, (uint8_t*)"ACK");
  324. break;
  325. }
  326. case 0x1E00://查询电机历史信息
  327. {
  328. uint32_t DataTemp;
  329. GetParamFromEEprom_24C02(&I2C_Handle_EEPROM, EEPROM_24C02_ADDR_RUN_LOG, sizeof(MC_RunLog), (uint8_t*)&MC_RunLog.PowerOnCnt);
  330. DataTemp = MC_RunLog.ODO_Km;
  331. MC_RunLog.ODO_Km = DataTemp / 10; // 存储按照0.1km,发送按照1km
  332. SendData(ID_MC_TO_CDL, MODE_REPORT, 0xA230, (uint8_t*)&MC_RunLog.PowerOnCnt);
  333. MC_RunLog.ODO_Km = DataTemp;
  334. break;
  335. }
  336. case 0x1F00://查询电机生产信息
  337. {
  338. ReadDataFromEEPROM_Flash(EEPROM_FLASH_ADDR_MAC_INFO, (uint8_t*)MC_MacInfo.Manufacturer, 32);
  339. SendData(ID_MC_TO_CDL, MODE_REPORT, 0xA520, (uint8_t*)MC_MacInfo.Manufacturer);
  340. break;
  341. }
  342. case 0x2000://查询力矩传感器零偏数据
  343. {
  344. GetParamFromEEprom_24C02(&I2C_Handle_EEPROM, EEPROM_24C02_ADDR_TORQUE_OFFSET, sizeof(TorqueOffSetData), (uint8_t*)TorqueOffSetData.Data);
  345. SendData(ID_MC_TO_CDL, MODE_REPORT, 0xA318, (uint8_t*)TorqueOffSetData.Data);
  346. break;
  347. }
  348. case 0x2100://查询设备在线结果
  349. {
  350. SendData(ID_MC_BC, MODE_REPORT, 0x1401, &DeviceOnLine_Status.Status);
  351. break;
  352. }
  353. case 0x2210://写入电机Mode
  354. {
  355. memcpy(MC_VerInfo.Mode, Data, DataLength);
  356. EEPROM_Flash_DataUpdate();
  357. SendData(ID_MC_BC, MODE_REPORT, 0xA903, (uint8_t*)"ACK");
  358. break;
  359. }
  360. case 0x2310://写入电机SN
  361. {
  362. memcpy(MC_VerInfo.SN_Num, Data, DataLength);
  363. EEPROM_Flash_DataUpdate();
  364. SendData(ID_MC_BC, MODE_REPORT, 0xA903, (uint8_t*)"ACK");
  365. break;
  366. }
  367. case 0x2420://写入电机生产信息
  368. {
  369. memcpy(MC_MacInfo.Manufacturer, Data, DataLength);
  370. EEPROM_Flash_DataUpdate();
  371. SendData(ID_MC_BC, MODE_REPORT, 0xA903, (uint8_t*)"ACK");
  372. break;
  373. }
  374. case 0x2505://复位指令
  375. {
  376. if(strncmp("RESET", (char*)Data, DataLength) == 0)
  377. {
  378. SendData(ID_MC_TO_CDL, MODE_REPORT, 0xA903, (uint8_t*)"ACK");
  379. SendCmdData(&UART_TxBuff_Struct3, MODE_WRITE, 0x1205, (uint8_t*)"RESET");
  380. HAL_Delay(200);
  381. __set_FAULTMASK(1);//关闭所有中断
  382. HAL_NVIC_SystemReset();
  383. }
  384. break;
  385. }
  386. case 0x2605://数据清除
  387. {
  388. if(strncmp("CLEAR", (char*)Data, DataLength) == 0)
  389. {
  390. EEPROM_24C02_ClearData(&I2C_Handle_EEPROM, EEPROM_24C02_ADDR_FLAG, EEPROM_24C02_ADDR_END, 0xFF);
  391. EEPROM_Flash_Erase();
  392. SendData(ID_MC_TO_CDL, MODE_REPORT, 0xA903, (uint8_t*)"ACK");
  393. SendCmdData(&UART_TxBuff_Struct3, MODE_WRITE, 0x1205, (uint8_t*)"RESET");
  394. __set_FAULTMASK(1);//关闭所有中断
  395. HAL_NVIC_SystemReset();
  396. }
  397. break;
  398. }
  399. case 0x2708://系统还原
  400. {
  401. if(strncmp("RECOVERY", (char*)Data, DataLength) == 0)
  402. {
  403. //...
  404. SendData(ID_MC_TO_CDL, MODE_REPORT, 0xA903, (uint8_t*)"ACK");
  405. SendCmdData(&UART_TxBuff_Struct3, MODE_WRITE, 0x1205, (uint8_t*)"RESET");
  406. __set_FAULTMASK(1);//关闭所有中断
  407. HAL_NVIC_SystemReset();
  408. }
  409. break;
  410. }
  411. case 0x2802://控制指令
  412. {
  413. memcpy(&MC_ControlCode.GearSt, Data, DataLength);
  414. Update_MC_ControlCode_Back();
  415. //PBU通信正常标志置位,避免上位機測試時認爲PBU失聯而關閉助力
  416. IsComOK_PBU.IsOK_Flag = TRUE;
  417. IsComOK_PBU.OK_TrigTime = HAL_GetTick();
  418. //運行信息助力档位更新
  419. MC_RunInfo.GearSt = MC_ControlCode.GearSt;
  420. SendData(ID_MC_BC, MODE_REPORT, 0x1020, (uint8_t*)&MC_RunInfo.BikeSpeed);
  421. break;
  422. }
  423. case 0x2900://查询力矩传感器校正信息
  424. {
  425. SendData(ID_MC_TO_CDL, MODE_REPORT, 0xAA04, (uint8_t*)&MC_TorqueCorrectParam.StarData);
  426. break;
  427. }
  428. case 0x2A01://写入力矩传感器标定系数
  429. {
  430. memcpy((uint8_t*)&MC_TorqueCorrectParam.K, Data, DataLength);
  431. SaveParamToEEprom_24C02(&I2C_Handle_EEPROM, EEPROM_24C02_ADDR_TORQUE_PARAM, sizeof(MC_TorqueCorrectParam_Struct_t), (uint8_t*)&MC_TorqueCorrectParam.StarData);
  432. SendData(ID_MC_BC, MODE_REPORT, 0xA903, (uint8_t*)"ACK");
  433. break;
  434. }
  435. case 0x2B02://写入力矩传感器启动值
  436. {
  437. memcpy((uint8_t*)&MC_TorqueCorrectParam.StarData, Data, DataLength);
  438. SaveParamToEEprom_24C02(&I2C_Handle_EEPROM, EEPROM_24C02_ADDR_TORQUE_PARAM, sizeof(MC_TorqueCorrectParam_Struct_t), (uint8_t*)&MC_TorqueCorrectParam.StarData);
  439. SendData(ID_MC_BC, MODE_REPORT, 0xA903, (uint8_t*)"ACK");
  440. break;
  441. }
  442. case 0x2C01://设置推行模式最高转速百分比
  443. {
  444. MC_WalkMode_Persent = Data[0];
  445. break;
  446. }
  447. default:break;
  448. }
  449. break;
  450. }
  451. default:break;
  452. }
  453. }
  454. /*********************End*******************/
  455. /************全局函数定义*******************/
  456. //CAN数据解析,严格按照协议格式
  457. void CAN_RxData_Process(CAN_Buf_TypeDef* ptCANRx, uint16_t TimeOutCnt)
  458. {
  459. uint8_t Mode, CmdLength, DataLength, Data[64], CRC_Buf[78];
  460. uint16_t Cmd, i;
  461. uint32_t CrcResult, CrcData;
  462. uint8_t FrameBegin1, FrameBegin2;
  463. if(ptCANRx->ucBufCnt >= 11)
  464. {
  465. //读取帧头
  466. FrameBegin1 = cd_ReadChar(ptCANRx, 0);
  467. CRC_Buf[0] = FrameBegin1;
  468. FrameBegin2 = cd_ReadChar(ptCANRx, 1);
  469. CRC_Buf[1] = FrameBegin2;
  470. if((FrameBegin1 == FRAME_BEGIN1) && (FrameBegin2 == FRAME_BEGIN2))
  471. {
  472. CRC_Buf[2] = (uint8_t)((ptCANRx->ucBufID >> 8) & 0xFF);
  473. CRC_Buf[3] = (uint8_t)(ptCANRx->ucBufID & 0xFF);
  474. //读取帧模式
  475. Mode = cd_ReadChar(ptCANRx, 2);
  476. CRC_Buf[4] = Mode;
  477. if((Mode == MODE_READ) || (Mode == MODE_WRITE) || (Mode == MODE_REPORT))
  478. {
  479. //读取命令段长度和命令字
  480. CmdLength = cd_ReadChar(ptCANRx, 3);
  481. CRC_Buf[5] = CmdLength;
  482. Cmd = (cd_ReadChar(ptCANRx, 4) << 8) + cd_ReadChar(ptCANRx, 5);
  483. CRC_Buf[6] = (uint8_t)((Cmd >> 8) & 0xFF);
  484. CRC_Buf[7] = (uint8_t)(Cmd & 0xFF);
  485. DataLength = cd_ReadChar(ptCANRx, 5);
  486. if((CmdLength - DataLength) == 2)
  487. {
  488. if(ptCANRx->ucBufCnt < (CmdLength + 9))//帧头2bytes + 模式1byte + 命令段长度1byte + 校验位4bytes + 帧尾1byte
  489. {
  490. if(ptCANRx->IsWaitRX_Flag == FALSE)
  491. {
  492. ptCANRx->DelayTimeCnt = HAL_GetTick();
  493. ptCANRx->IsWaitRX_Flag = TRUE;
  494. }
  495. if((HAL_GetTick() - ptCANRx->DelayTimeCnt) > TimeOutCnt)//超时,单位ms
  496. {
  497. cd_DelChar(ptCANRx, ptCANRx->ucBufCnt);
  498. ptCANRx->IsWaitRX_Flag = FALSE;
  499. }
  500. return;
  501. }
  502. else
  503. {
  504. ptCANRx->IsWaitRX_Flag = FALSE;
  505. //接收到完整正确数据包
  506. for(i=0; i<DataLength; i++)//读取数据段
  507. {
  508. Data[i] = cd_ReadChar(ptCANRx, 6 + i);
  509. CRC_Buf[8 + i] = Data[i];
  510. }
  511. CrcData = (cd_ReadChar(ptCANRx, 6 + DataLength) << 24) + \
  512. (cd_ReadChar(ptCANRx, 7 + DataLength) << 16) + \
  513. (cd_ReadChar(ptCANRx, 8 + DataLength) << 8) + \
  514. cd_ReadChar(ptCANRx, 9 + DataLength);
  515. CrcResult = CRC32_Calculate(CRC_Buf, 8 + DataLength);
  516. if((CrcData - CrcResult) == 0) // 比较校验
  517. {
  518. //数据处理
  519. DataProcess(ptCANRx->ucBufID, Mode, Cmd, Data);//Mode为帧模式,Cmd为命令字,Data为数据段
  520. cd_DelChar(ptCANRx, CmdLength + 9);
  521. return;
  522. }
  523. cd_DelChar(ptCANRx, 1);
  524. }
  525. }
  526. else
  527. {
  528. cd_DelChar(ptCANRx, 1);
  529. }
  530. }
  531. else
  532. {
  533. cd_DelChar(ptCANRx, 1);
  534. }
  535. }
  536. else
  537. {
  538. cd_DelChar(ptCANRx, 1);
  539. }
  540. }
  541. }
  542. #if 0
  543. //数据解析,忽略命令字表示的数据长度
  544. void CAN_RxData_Process_Temp(CAN_Buf_TypeDef* ptCANRx, uint16_t TimeOutCnt)
  545. {
  546. uint8_t Mode, CmdLength, DataLength, Data[64], CRC_Buf[78];
  547. uint16_t Cmd, i;
  548. uint32_t CrcResult, CrcData;
  549. uint8_t FrameBegin1, FrameBegin2;
  550. if(ptCANRx->ucBufCnt >= 11)
  551. {
  552. //读取帧头
  553. FrameBegin1 = cd_ReadChar(ptCANRx, 0);
  554. CRC_Buf[0] = FrameBegin1;
  555. FrameBegin2 = cd_ReadChar(ptCANRx, 1);
  556. CRC_Buf[1] = FrameBegin2;
  557. if((FrameBegin1 == FRAME_BEGIN1) && (FrameBegin2 == FRAME_BEGIN2))
  558. {
  559. CRC_Buf[2] = (uint8_t)((ptCANRx->ucBufID >> 8) & 0xFF);
  560. CRC_Buf[3] = (uint8_t)(ptCANRx->ucBufID & 0xFF);
  561. //读取帧模式
  562. Mode = cd_ReadChar(ptCANRx, 2);
  563. CRC_Buf[4] = Mode;
  564. if((Mode == MODE_READ) || (Mode == MODE_WRITE) || (Mode == MODE_REPORT))
  565. {
  566. //读取命令段长度和命令字
  567. CmdLength = cd_ReadChar(ptCANRx, 3);
  568. CRC_Buf[5] = CmdLength;
  569. Cmd = (cd_ReadChar(ptCANRx, 4) << 8) + cd_ReadChar(ptCANRx, 5);
  570. CRC_Buf[6] = (uint8_t)((Cmd >> 8) & 0xFF);
  571. CRC_Buf[7] = (uint8_t)(Cmd & 0xFF);
  572. DataLength = CmdLength - 2;
  573. if(ptCANRx->ucBufCnt < (CmdLength + 9))//帧头2bytes + 模式1byte + 命令段长度1byte + 校验位4bytes + 帧尾1byte
  574. {
  575. if(ptCANRx->IsWaitRX_Flag == FALSE)
  576. {
  577. ptCANRx->DelayTimeCnt = HAL_GetTick();
  578. ptCANRx->IsWaitRX_Flag = TRUE;
  579. }
  580. if((HAL_GetTick() - ptCANRx->DelayTimeCnt) > TimeOutCnt)//超时,单位ms
  581. {
  582. cd_DelChar(ptCANRx, ptCANRx->ucBufCnt);
  583. ptCANRx->IsWaitRX_Flag = FALSE;
  584. }
  585. return;
  586. }
  587. else
  588. {
  589. ptCANRx->IsWaitRX_Flag = FALSE;
  590. //接收到完整正确数据包
  591. for(i=0; i<DataLength; i++)//读取数据段
  592. {
  593. Data[i] = cd_ReadChar(ptCANRx, 6 + i);
  594. CRC_Buf[8 + i] = Data[i];
  595. }
  596. CrcData = (cd_ReadChar(ptCANRx, 6 + DataLength) << 24) + \
  597. (cd_ReadChar(ptCANRx, 7 + DataLength) << 16) + \
  598. (cd_ReadChar(ptCANRx, 8 + DataLength) << 8) + \
  599. cd_ReadChar(ptCANRx, 9 + DataLength);
  600. CrcResult = CRC32_Calculate(CRC_Buf, 8 + DataLength);
  601. if((CrcData - CrcResult) == 0) // 比较校验
  602. {
  603. //数据处理
  604. DataProcess(ptCANRx->ucBufID, Mode, Cmd, Data);//Mode为帧模式,Cmd为命令字,Data为数据段
  605. cd_DelChar(ptCANRx, CmdLength + 9);
  606. return;
  607. }
  608. cd_DelChar(ptCANRx, 1);
  609. }
  610. }
  611. else
  612. {
  613. cd_DelChar(ptCANRx, 1);
  614. }
  615. }
  616. else
  617. {
  618. cd_DelChar(ptCANRx, 1);
  619. }
  620. }
  621. }
  622. #endif
  623. void SendData(uint16_t ID, uint8_t Mode, uint16_t Command, uint8_t* Data)
  624. {
  625. uint8_t SendBuf[96] = {0};
  626. uint8_t CRC_Buf[98] = {0};
  627. uint32_t CRC_Result = 0x00000000;
  628. uint8_t DataLength;
  629. DataLength = (uint8_t)(Command & 0xFF);
  630. SendBuf[0] = FRAME_BEGIN1;
  631. SendBuf[1] = FRAME_BEGIN2;
  632. SendBuf[2] = Mode;
  633. SendBuf[3] = DataLength + 2;
  634. SendBuf[4] = (uint8_t)((Command >> 8) & 0xFF);
  635. SendBuf[5] = DataLength;
  636. memcpy(SendBuf + 6, Data, DataLength);
  637. CRC_Buf[0] = FRAME_BEGIN1;
  638. CRC_Buf[1] = FRAME_BEGIN2;
  639. CRC_Buf[2] = (uint8_t)(ID >> 8);
  640. CRC_Buf[3] = (uint8_t)(ID & 0xFF);
  641. memcpy(CRC_Buf + 4, SendBuf + 2, DataLength + 4);
  642. CRC_Result = CRC32_Calculate(CRC_Buf, DataLength + 8);//帧头 2bytes + ID 2bytes + 模式 1byte + 命令段长度 1byte + 命令字 2bytes
  643. SendBuf[6 + DataLength] = (uint8_t)((CRC_Result >> 24) & 0xFF);
  644. SendBuf[7 + DataLength] = (uint8_t)((CRC_Result >> 16) & 0xFF);
  645. SendBuf[8 + DataLength] = (uint8_t)((CRC_Result >> 8) & 0xFF);
  646. SendBuf[9 + DataLength] = (uint8_t)(CRC_Result & 0xFF);
  647. SendBuf[10 + DataLength] = FRAME_END;
  648. CAN_SendData(ID, SendBuf, DataLength + 11);
  649. }
  650. /********************End********************/