You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

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