您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
 
 
 
 

680 行
18 KiB

  1. #include "stm32f4xx.h"
  2. #include "ucos_ii.h"
  3. #include "os.h"
  4. #include "string.h"
  5. #include "modbus.h"
  6. extern OS_EVENT* ModbusWriteFlash; /*接收到modbus写入coil请求报文*/
  7. extern OS_EVENT* ModbusConnect; /*已接收到modbus正确报文*/
  8. uint8_t ModbusErr;
  9. /*0x270F + 1 = K10000 */
  10. uint8_t ModbusCoil[1250]; /*10000/8=1250*/
  11. uint16_t ModbusReg[10000];
  12. /*附加功能:页寄存器*/
  13. uint16_t ModbusExtPage[1] = {0}; /*设置地址为0xFFFE*/
  14. uint16_t ModbusExtReg[1]; /*地址映射为0x10000*/
  15. /*附加功能:读取所有单数个寄存器*/
  16. uint16_t ModbusExtOdd[1] = {0}; /*设置地址为0xFFFF*/
  17. uint8_t ModbusRxBuf[MODBUS_RX_BUF_SIZE]; /*接收数组*/
  18. uint16_t ModbusRxLen = 0; /*接收数据长度*/
  19. uint8_t ModbusTxBuf[MODBUS_TX_BUF_SIZE]; /*发送数组*/
  20. uint16_t ModbusTxLen = 0; /*发送数据长度*/
  21. /*modbus协议帧解析任务*/
  22. void AppTaskModbusParse (void *p_arg)
  23. {
  24. OS_ERR err;
  25. MODBUS_FRAME frame;
  26. uint16_t rxLen;
  27. uint8_t rxBuf[256];
  28. while(1)
  29. {
  30. /*无限期等待接收到数据帧信号量*/
  31. OSSemPend(ModbusReceived, 0, &err);
  32. /*数据接收,防止下一帧覆盖*/
  33. rxLen = ModbusRxLen;
  34. memcpy(rxBuf, ModbusRxBuf, rxLen);
  35. /*帧分解*/
  36. frame.slaveAddres = rxBuf[0];
  37. frame.func = rxBuf[1];
  38. frame.crc = ((uint16_t)(rxBuf[rxLen - 2])) | ((uint16_t)rxBuf[rxLen - 1] << 8);
  39. frame.opeAddres = ((uint16_t)rxBuf[2] << 8) | ((uint16_t)rxBuf[3]);
  40. frame.opeNum = ((uint16_t)rxBuf[4] << 8) | ((uint16_t)rxBuf[5]);
  41. /*crc校验判断*/
  42. if(ChcekCrc16(frame.crc, rxBuf, rxLen) != 0)
  43. {
  44. /*crc校验错误,直接丢弃*/
  45. ModbusErr = ERR_CRC;
  46. continue;
  47. }
  48. /*从机地址判断*/
  49. if(frame.slaveAddres != SLAVE_ADDRES)
  50. {
  51. /*从机地址错误,直接丢弃*/
  52. ModbusErr = ERR_SLAVE_ADDRES;
  53. continue;
  54. }
  55. /*释放正确接收信号量*/
  56. OSSemPost(ModbusConnect);
  57. /*功能码分类*/
  58. switch(frame.func)
  59. {
  60. case 0x01:/*读线圈*/
  61. ModbusErr = ModbusReadCoils(frame.opeAddres, frame.opeNum);
  62. break;
  63. case 0x03:/*读寄存器*/
  64. ModbusErr = ModbusReadRegs(frame.opeAddres, frame.opeNum);
  65. break;
  66. case 0x0F:/*写多个线圈*/
  67. frame.wNum = rxBuf[6];
  68. memcpy(frame.wData, &rxBuf[7], frame.wNum);
  69. ModbusErr = ModbusWriteCoils(frame.opeAddres, frame.opeNum, frame.wData);
  70. break;
  71. case 0x10:/*写多个寄存器*/
  72. frame.wNum = rxBuf[6];
  73. memcpy(frame.wData, &rxBuf[7], frame.wNum);
  74. ModbusErr = ModbusWriteRegs(frame.opeAddres, frame.opeNum, frame.wData);
  75. break;
  76. case 0x05:/*写单个线圈*/
  77. memcpy(frame.wData, &rxBuf[4], 2);
  78. ModbusErr = ModbusWriteCoil(frame.opeAddres, frame.wData);
  79. break;
  80. case 0x06:/*写单个寄存器*/
  81. memcpy(frame.wData, &rxBuf[4], 2);
  82. ModbusErr = ModbusWriteReg(frame.opeAddres, frame.wData);
  83. break;
  84. default:/*功能码错误*/
  85. ModbusErr = ERR_FUNC;
  86. ModbusErr = ModbusErrReply(frame.func, ERR_FUNC);
  87. break;
  88. }
  89. /*实现附加功能时不在这里启动发送*/
  90. if(frame.func == 0x03 && frame.opeAddres == 0XFFFF);
  91. else
  92. {
  93. ModbusSend(ModbusTxBuf, ModbusTxLen);
  94. }
  95. if(ModbusErr == 0 && (frame.func == 0x0F || frame.func == 0x10
  96. || frame.func == 0x05 || frame.func == 0x06))
  97. {
  98. /*释放写FLASH信号量*/
  99. OSSemPost(ModbusWriteFlash);
  100. }
  101. }
  102. }
  103. uint8_t ModbusReadCoils(uint16_t addres, uint16_t num)
  104. {
  105. uint16_t byteIndI; /*字节索引*/
  106. uint8_t bitIndI; /*位索引*/
  107. uint16_t byteIndO;
  108. uint8_t bitIndO;
  109. uint8_t dataLen; /*响应帧返回字节数*/
  110. uint8_t index; /*发送数组索引*/
  111. uint8_t readVal; /*读取到的形式值*/
  112. uint8_t writeVal; /*写入的形式值*/
  113. if(ModbusRxLen < 8)
  114. {
  115. return ModbusErrReply(0x01, ERR_DATA);
  116. }
  117. /*操作地址超限*/
  118. if(addres > 0x270F || (addres + (num - 1)) > 0x270F)
  119. {
  120. return ModbusErrReply(0x01, ERR_OPE_ADDRES);
  121. }
  122. /*操作数量超限*/
  123. if(num == 0 || num > 2000)
  124. {
  125. return ModbusErrReply(0x01, ERR_DATA);
  126. }
  127. /*不能num/8+1,当为8的整数时会多一个*/
  128. dataLen = (num + 7) / 8;
  129. /*清零发送数组*/
  130. memset(&ModbusTxBuf[3], 0, 253);
  131. for(uint16_t i = 0; i < num; i++)
  132. {
  133. byteIndO = i / 8;
  134. bitIndO = i % 8;
  135. byteIndI = (addres + i) / 8;
  136. bitIndI = (addres + i) % 8;
  137. /*位掩码读取线圈值*/
  138. readVal = ModbusCoil[byteIndI] & ((uint8_t)1 << bitIndI);
  139. /*读取到的值为0则不进行操作*/
  140. if(readVal != 0)
  141. {
  142. index = 3 + byteIndO;
  143. /*将读取到的值移位到要写入的位*/
  144. writeVal = (uint8_t)1u << bitIndO;
  145. ModbusTxBuf[index] |= writeVal;
  146. }
  147. }
  148. ModbusTxBuf[0] = SLAVE_ADDRES; /*从机地址*/
  149. ModbusTxBuf[1] = 0x01; /*功能码*/
  150. ModbusTxBuf[2] = dataLen; /*响应帧返回数据字节数*/
  151. AddCrc16(ModbusTxBuf, 3 + dataLen);
  152. ModbusTxLen = 5 + dataLen;
  153. return 0;
  154. }
  155. uint8_t ModbusWriteCoils(uint16_t addres, uint16_t num, uint8_t *data)
  156. {
  157. uint16_t byteIndI;
  158. uint8_t bitIndI;
  159. uint16_t byteIndO;
  160. uint8_t bitIndO;
  161. uint8_t readVal;
  162. uint8_t writeVal;
  163. if(ModbusRxLen < 10)
  164. {
  165. return ModbusErrReply(0x0F, ERR_DATA);
  166. }
  167. /*操作地址超限*/
  168. if(addres > 0x270F || (addres + (num - 1)) > 0x270F)
  169. {
  170. return ModbusErrReply(0x0F, ERR_OPE_ADDRES);
  171. }
  172. /*操作数量超限*/
  173. if(num == 0 || num > 1968)
  174. {
  175. return ModbusErrReply(0x0F, ERR_DATA);
  176. }
  177. for(uint16_t i = 0; i < num; i++)
  178. {
  179. byteIndI = (addres + i) / 8;
  180. bitIndI = (addres + i) % 8;
  181. byteIndO = i / 8;
  182. bitIndO = i % 8;
  183. /*位掩码读取要写入的值*/
  184. readVal = data[byteIndO] & ((uint8_t)1 << bitIndO);
  185. /*将写入值移位到要写入的位*/
  186. writeVal = (uint8_t)1 << bitIndI;
  187. /*对应位写入1*/
  188. if(readVal != 0)
  189. {
  190. ModbusCoil[byteIndI] |= writeVal;
  191. }
  192. /*对应位写入0*/
  193. else
  194. {
  195. ModbusCoil[byteIndI] &= (~writeVal);
  196. }
  197. }
  198. ModbusTxBuf[0] = SLAVE_ADDRES;
  199. ModbusTxBuf[1] = 0x0F;
  200. /*操作地址*/
  201. ModbusTxBuf[2] = (uint8_t)(addres >> 8);
  202. ModbusTxBuf[3] = (uint8_t)(addres & 0x00FF);
  203. /*成功写入的数量*/
  204. ModbusTxBuf[4] = (uint8_t)(num >> 8);
  205. ModbusTxBuf[5] = (uint8_t)(num & 0x00FF);
  206. AddCrc16(ModbusTxBuf, 6);
  207. ModbusTxLen = 8;
  208. return 0;
  209. }
  210. uint8_t ModbusReadRegs(uint16_t addres, uint16_t num)
  211. {
  212. uint8_t index;
  213. uint8_t readValH;
  214. uint8_t readValL;
  215. uint8_t dataLen;
  216. if(ModbusRxLen < 8)
  217. {
  218. return ModbusErrReply(0x13, ERR_DATA);
  219. }
  220. /*操作地址超限*/
  221. if(addres > 0x270F || (addres + (num - 1)) > 0x270F)
  222. {
  223. if(addres == 0xFFFF && num == 1)
  224. {
  225. ;
  226. }
  227. else
  228. {
  229. return ModbusErrReply(0x03, ERR_OPE_ADDRES);
  230. }
  231. }
  232. /*操作数量超限*/
  233. if(num == 0 || num > 125)
  234. {
  235. return ModbusErrReply(0x03, ERR_DATA);
  236. }
  237. dataLen = num * 2;
  238. /*附加功能:读取0x10000寄存器*/
  239. if(ModbusExtPage[0] == 1 && addres == 0x0000)
  240. {
  241. /*将16位寄存器值拆分为两个8位*/
  242. readValH = (uint8_t)(ModbusExtReg[0] >> 8);
  243. readValL = (uint8_t)(ModbusExtReg[0] & 0x00FF);
  244. ModbusTxBuf[3] = readValH;
  245. ModbusTxBuf[4] = readValL;
  246. }
  247. /*附加功能:读取大量奇数寄存器*/
  248. else if(addres == 0xFFFF && num == 1)
  249. {
  250. return ModbusExtReadOdd(ModbusExtOdd[0]);
  251. }
  252. else
  253. {
  254. for(uint16_t i = 0; i < num; i++)
  255. {
  256. index = 3 + (i * 2);
  257. /*将16位寄存器值拆分为两个8位*/
  258. readValH = (uint8_t)(ModbusReg[addres + i] >> 8);
  259. readValL = (uint8_t)(ModbusReg[addres + i] & 0x00FF);
  260. ModbusTxBuf[index] = readValH;
  261. ModbusTxBuf[index + 1] = readValL;
  262. }
  263. }
  264. ModbusTxBuf[0] = SLAVE_ADDRES;
  265. ModbusTxBuf[1] = 0x03;
  266. ModbusTxBuf[2] = dataLen;
  267. AddCrc16(ModbusTxBuf, 3 + dataLen);
  268. ModbusTxLen = 5 + dataLen;
  269. return 0;
  270. }
  271. uint8_t ModbusWriteRegs(uint16_t addres, uint16_t num, uint8_t *data)
  272. {
  273. uint8_t index;
  274. uint8_t writeValH;
  275. uint8_t writeValL;
  276. uint16_t writeVal;
  277. if(ModbusRxLen < 11)
  278. {
  279. return ModbusErrReply(0x10, ERR_DATA);
  280. }
  281. /*操作地址超限*/
  282. if(addres > 0x270F || (addres + (num - 1)) > 0x270F)
  283. {
  284. if((addres == 0xFFFE || addres == 0xFFFF) && num == 1)
  285. {
  286. ;
  287. }
  288. else
  289. {
  290. return ModbusErrReply(0x10, ERR_OPE_ADDRES);
  291. }
  292. }
  293. /*操作数量超限*/
  294. if(num == 0 || num > 123)
  295. {
  296. return ModbusErrReply(0x10, ERR_DATA);
  297. }
  298. /*附加功能:读取0x10000寄存器*/
  299. if(addres == 0xFFFE && num == 1)
  300. {
  301. writeValH = data[0];
  302. writeValL = data[1];
  303. /*将要写入两个8位值拼接为16位*/
  304. writeVal = ((uint16_t)writeValH << 8) | ((uint16_t)writeValL & 0x00FF);
  305. ModbusExtPage[0] = writeVal;
  306. }
  307. /*附加功能:读取大量奇数寄存器*/
  308. else if(addres == 0xFFFF && num == 1)
  309. {
  310. writeValH = data[0];
  311. writeValL = data[1];
  312. /*将要写入两个8位值拼接为16位*/
  313. writeVal = ((uint16_t)writeValH << 8) | ((uint16_t)writeValL & 0x00FF);
  314. ModbusExtOdd[0] = writeVal;
  315. }
  316. /*正常功能*/
  317. else
  318. {
  319. for(uint16_t i = 0; i < num; i++)
  320. {
  321. index = i * 2;
  322. writeValH = data[index];
  323. writeValL = data[index + 1];
  324. /*将要写入两个8位值拼接为16位*/
  325. writeVal = ((uint16_t)writeValH << 8) | ((uint16_t)writeValL & 0x00FF);
  326. ModbusReg[addres + i] = writeVal;
  327. }
  328. }
  329. ModbusTxBuf[0] = SLAVE_ADDRES;
  330. ModbusTxBuf[1] = 0x10;
  331. /*操作地址*/
  332. ModbusTxBuf[2] = (uint8_t)(addres >> 8);
  333. ModbusTxBuf[3] = (uint8_t)(addres & 0x00FF);
  334. /*成功写入数量*/
  335. ModbusTxBuf[4] = (uint8_t)(num >> 8);
  336. ModbusTxBuf[5] = (uint8_t)(num & 0x00FF);
  337. AddCrc16(ModbusTxBuf, 6);
  338. ModbusTxLen = 8;
  339. return 0;
  340. }
  341. uint8_t ModbusWriteCoil(uint16_t addres, uint8_t *data)
  342. {
  343. uint16_t byteIndI;
  344. uint8_t bitIndI;
  345. uint16_t readVal;
  346. uint8_t writeVal;
  347. /*操作地址超限*/
  348. if(addres > 0x270F)
  349. {
  350. return ModbusErrReply(0x0F, ERR_OPE_ADDRES);
  351. }
  352. byteIndI = addres / 8;
  353. bitIndI = addres % 8;
  354. /*位掩码读取要写入的值*/
  355. readVal = ((uint16_t)data[0] << 8) | ((uint16_t)data[1] & 0x00FF);
  356. /*将写入值移位到要写入的位*/
  357. writeVal = (uint8_t)1 << bitIndI;
  358. /*置on*/
  359. if(readVal == 0xFF00)
  360. {
  361. ModbusCoil[byteIndI] |= writeVal;
  362. }
  363. /*置off*/
  364. else if(readVal == 0x0000)
  365. {
  366. ModbusCoil[byteIndI] &= (~writeVal);
  367. }
  368. else
  369. {
  370. return ModbusErrReply(0x05, ERR_DATA);
  371. }
  372. ModbusTxBuf[0] = SLAVE_ADDRES;
  373. ModbusTxBuf[1] = 0x0F;
  374. /*操作地址*/
  375. ModbusTxBuf[2] = (uint8_t)(addres >> 8);
  376. ModbusTxBuf[3] = (uint8_t)(addres & 0x00FF);
  377. /*成功写入*/
  378. ModbusTxBuf[4] = data[0];
  379. ModbusTxBuf[5] = data[1];
  380. AddCrc16(ModbusTxBuf, 6);
  381. ModbusTxLen = 8;
  382. return 0;
  383. }
  384. uint8_t ModbusWriteReg(uint16_t addres, uint8_t *data)
  385. {
  386. uint8_t writeValH;
  387. uint8_t writeValL;
  388. uint16_t writeVal;
  389. /*操作地址超限*/
  390. if(addres > 0x270F)
  391. {
  392. return ModbusErrReply(0x10, ERR_OPE_ADDRES);
  393. }
  394. writeValH = data[0];
  395. writeValL = data[1];
  396. /*将要写入两个8位值拼接为16位*/
  397. writeVal = ((uint16_t)writeValH << 8) | ((uint16_t)writeValL & 0x00FF);
  398. ModbusReg[addres] = writeVal;
  399. ModbusTxBuf[0] = SLAVE_ADDRES;
  400. ModbusTxBuf[1] = 0x10;
  401. /*操作地址*/
  402. ModbusTxBuf[2] = (uint8_t)(addres >> 8);
  403. ModbusTxBuf[3] = (uint8_t)(addres & 0x00FF);
  404. /*成功写入*/
  405. ModbusTxBuf[4] = writeValH;
  406. ModbusTxBuf[5] = writeValL;
  407. AddCrc16(ModbusTxBuf, 6);
  408. ModbusTxLen = 8;
  409. return 0;
  410. }
  411. /*USART接收空闲中断*/
  412. void USART1_IRQHandler(void)
  413. {
  414. OSIntEnter(); /*进入中断*/
  415. uint32_t temp;
  416. uint16_t rxLenRemain;
  417. if(USART_GetITStatus(USART1, USART_IT_IDLE) == SET)
  418. {
  419. /*在计算数据长度之前先关闭DMA接收通道,防止计算过程中DMA继续转运数据*/
  420. DMA_Cmd(DMA2_Stream2, DISABLE);
  421. /*清除IDLE中断标志位*/
  422. temp = USART1->SR;
  423. temp = USART1->DR;
  424. (void)temp;
  425. /*清除传输已经完成TCIF2、传输已经完成一半HTIF2标志位*/
  426. DMA_ClearFlag(DMA2_Stream2, DMA_FLAG_TCIF2 | DMA_FLAG_HTIF2);
  427. /*计算数据长度*/
  428. rxLenRemain = DMA_GetCurrDataCounter(DMA2_Stream2);
  429. ModbusRxLen = MODBUS_RX_BUF_SIZE - rxLenRemain;
  430. /*释放接收到数据帧信号量,唤醒帧解析任务*/
  431. if(ModbusRxLen != 0)
  432. {
  433. OSSemPost(ModbusReceived);
  434. }
  435. /*重新指定接收地址*/
  436. DMA_MemoryTargetConfig(DMA2_Stream2, (uint32_t)ModbusRxBuf, DMA_Memory_0);
  437. /*重启DMA*/
  438. DMA_SetCurrDataCounter(DMA2_Stream2, MODBUS_RX_BUF_SIZE);
  439. DMA_Cmd(DMA2_Stream2, ENABLE);
  440. }
  441. OSIntExit(); /*退出中断*/
  442. }
  443. /*modbus响应帧发送*/
  444. void ModbusSend(uint8_t *txBuf, uint16_t len)
  445. {
  446. if(DMA_GetCmdStatus(DMA2_Stream7) == ENABLE)
  447. {
  448. /*等待DMA发送完成*/
  449. while(DMA_GetFlagStatus(DMA2_Stream7, DMA_FLAG_TCIF7) == RESET);
  450. }
  451. /*先关闭DMA发送通道*/
  452. DMA_Cmd(DMA2_Stream7, DISABLE);
  453. /*等待DMA关闭*/
  454. while (DMA_GetCmdStatus(DMA2_Stream7) != DISABLE);
  455. /*清除传输已经完成TCIF7、传输已经完成一半HTIF7、FIFO错误FEIF7标志位*/
  456. DMA_ClearFlag(DMA2_Stream7, DMA_FLAG_FEIF7 | DMA_FLAG_HTIF7 | DMA_FLAG_TCIF7);
  457. /*配置发送地址和长度*/
  458. DMA_MemoryTargetConfig(DMA2_Stream7, (uint32_t)txBuf, DMA_Memory_0);
  459. DMA_SetCurrDataCounter(DMA2_Stream7, len);
  460. /*等待串口发送完成*/
  461. while (USART_GetFlagStatus(USART1, USART_FLAG_TC) == RESET);
  462. /*启动 DMA 发送*/
  463. DMA_Cmd(DMA2_Stream7, ENABLE);
  464. }
  465. uint8_t ModbusExtReadOdd(uint16_t num)
  466. {
  467. uint8_t i = 0;
  468. uint8_t numJ = (num + 124) / 125;
  469. uint8_t numI = num % 125;
  470. uint8_t index;
  471. uint16_t indexR;
  472. uint8_t readValH;
  473. uint8_t readValL;
  474. uint8_t dataLen;
  475. for(uint16_t j = 0; j < numJ; j++)
  476. {
  477. if(j == numJ - 1)
  478. {
  479. for(i = 0; i < numI; i++)
  480. {
  481. index = 3 + (i * 2);
  482. indexR = j * 250 + 2 * i + 1;
  483. /*将16位寄存器值拆分为两个8位*/
  484. readValH = (uint8_t)(ModbusReg[indexR] >> 8);
  485. readValL = (uint8_t)(ModbusReg[indexR] & 0x00FF);
  486. ModbusTxBuf[index] = readValH;
  487. ModbusTxBuf[index + 1] = readValL;
  488. }
  489. dataLen = 2 * numI;
  490. ModbusTxBuf[0] = SLAVE_ADDRES;
  491. ModbusTxBuf[1] = 0x03;
  492. ModbusTxBuf[2] = dataLen;
  493. AddCrc16(ModbusTxBuf, 3 + dataLen);
  494. ModbusTxLen = 5 + dataLen;
  495. }
  496. else
  497. {
  498. for(i = 0; i < 125; i++)
  499. {
  500. index = 3 + (i * 2);
  501. indexR = j * 250 + 2 * i + 1;
  502. /*将16位寄存器值拆分为两个8位*/
  503. readValH = (uint8_t)(ModbusReg[indexR] >> 8);
  504. readValL = (uint8_t)(ModbusReg[indexR] & 0x00FF);
  505. ModbusTxBuf[index] = readValH;
  506. ModbusTxBuf[index + 1] = readValL;
  507. }
  508. dataLen = 250;
  509. ModbusTxBuf[0] = SLAVE_ADDRES;
  510. ModbusTxBuf[1] = 0x03;
  511. ModbusTxBuf[2] = dataLen;
  512. AddCrc16(ModbusTxBuf, 3 + dataLen);
  513. ModbusTxLen = 5 + dataLen;
  514. }
  515. /*演示2ms*/
  516. OSTimeDly(OS_TICKS_PER_SEC / 500);
  517. ModbusSend(ModbusTxBuf, ModbusTxLen);
  518. }
  519. return 0;
  520. }
  521. uint8_t ModbusErrReply(uint8_t func, uint8_t err)
  522. {
  523. ModbusTxBuf[0] = SLAVE_ADDRES;
  524. ModbusTxBuf[1] = func;
  525. ModbusTxBuf[2] = err;
  526. AddCrc16(ModbusTxBuf, 3);
  527. ModbusTxLen = 5;
  528. return err;
  529. }
  530. void AddCrc16(uint8_t *data, uint16_t length)
  531. {
  532. uint8_t *dataT = data;
  533. uint16_t crc16 = Crc16(data, length);
  534. /*低前高后*/
  535. dataT[length] = (uint8_t)(crc16 & 0x00FF);
  536. dataT[length + 1] = (uint8_t)(crc16 >> 8);
  537. }
  538. /*crc16校验*/
  539. uint16_t Crc16(const uint8_t *data, uint16_t length)
  540. {
  541. uint16_t crc;
  542. uint16_t byteInd;
  543. uint8_t bitInd;
  544. crc = 0xFFFFu;
  545. for (byteInd = 0u; byteInd < length; byteInd++)
  546. {
  547. crc ^= (uint16_t)data[byteInd];
  548. for (bitInd = 0u; bitInd < 8u; bitInd++)
  549. {
  550. if ((crc & 0x0001u) != 0u)
  551. {
  552. crc >>= 1;
  553. crc ^= 0xA001u;
  554. }
  555. else
  556. {
  557. crc >>= 1;
  558. }
  559. }
  560. }
  561. return crc;
  562. }
  563. /*crc16检查*/
  564. int8_t ChcekCrc16(uint16_t recCrc16, uint8_t *data, uint16_t length)
  565. {
  566. uint16_t crc16 = Crc16(data, (length - 2));
  567. if(recCrc16 == crc16)
  568. {
  569. return 0;
  570. }
  571. else
  572. {
  573. return -1;
  574. }
  575. }