modbus.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607
  1. #include "mmodbus.h"
  2. #include "usart.h"
  3. #include "timer.h"
  4. #include "log.h"
  5. #include "gateway_message.h"
  6. MModBus_t mmodbus;
  7. // #####################################################################################################
  8. #if (_MMODBUS_RTU == 1)
  9. static const uint16_t wCRCTable[] =
  10. {
  11. 0X0000, 0XC0C1, 0XC181, 0X0140, 0XC301, 0X03C0, 0X0280, 0XC241,
  12. 0XC601, 0X06C0, 0X0780, 0XC741, 0X0500, 0XC5C1, 0XC481, 0X0440,
  13. 0XCC01, 0X0CC0, 0X0D80, 0XCD41, 0X0F00, 0XCFC1, 0XCE81, 0X0E40,
  14. 0X0A00, 0XCAC1, 0XCB81, 0X0B40, 0XC901, 0X09C0, 0X0880, 0XC841,
  15. 0XD801, 0X18C0, 0X1980, 0XD941, 0X1B00, 0XDBC1, 0XDA81, 0X1A40,
  16. 0X1E00, 0XDEC1, 0XDF81, 0X1F40, 0XDD01, 0X1DC0, 0X1C80, 0XDC41,
  17. 0X1400, 0XD4C1, 0XD581, 0X1540, 0XD701, 0X17C0, 0X1680, 0XD641,
  18. 0XD201, 0X12C0, 0X1380, 0XD341, 0X1100, 0XD1C1, 0XD081, 0X1040,
  19. 0XF001, 0X30C0, 0X3180, 0XF141, 0X3300, 0XF3C1, 0XF281, 0X3240,
  20. 0X3600, 0XF6C1, 0XF781, 0X3740, 0XF501, 0X35C0, 0X3480, 0XF441,
  21. 0X3C00, 0XFCC1, 0XFD81, 0X3D40, 0XFF01, 0X3FC0, 0X3E80, 0XFE41,
  22. 0XFA01, 0X3AC0, 0X3B80, 0XFB41, 0X3900, 0XF9C1, 0XF881, 0X3840,
  23. 0X2800, 0XE8C1, 0XE981, 0X2940, 0XEB01, 0X2BC0, 0X2A80, 0XEA41,
  24. 0XEE01, 0X2EC0, 0X2F80, 0XEF41, 0X2D00, 0XEDC1, 0XEC81, 0X2C40,
  25. 0XE401, 0X24C0, 0X2580, 0XE541, 0X2700, 0XE7C1, 0XE681, 0X2640,
  26. 0X2200, 0XE2C1, 0XE381, 0X2340, 0XE101, 0X21C0, 0X2080, 0XE041,
  27. 0XA001, 0X60C0, 0X6180, 0XA141, 0X6300, 0XA3C1, 0XA281, 0X6240,
  28. 0X6600, 0XA6C1, 0XA781, 0X6740, 0XA501, 0X65C0, 0X6480, 0XA441,
  29. 0X6C00, 0XACC1, 0XAD81, 0X6D40, 0XAF01, 0X6FC0, 0X6E80, 0XAE41,
  30. 0XAA01, 0X6AC0, 0X6B80, 0XAB41, 0X6900, 0XA9C1, 0XA881, 0X6840,
  31. 0X7800, 0XB8C1, 0XB981, 0X7940, 0XBB01, 0X7BC0, 0X7A80, 0XBA41,
  32. 0XBE01, 0X7EC0, 0X7F80, 0XBF41, 0X7D00, 0XBDC1, 0XBC81, 0X7C40,
  33. 0XB401, 0X74C0, 0X7580, 0XB541, 0X7700, 0XB7C1, 0XB681, 0X7640,
  34. 0X7200, 0XB2C1, 0XB381, 0X7340, 0XB101, 0X71C0, 0X7080, 0XB041,
  35. 0X5000, 0X90C1, 0X9181, 0X5140, 0X9301, 0X53C0, 0X5280, 0X9241,
  36. 0X9601, 0X56C0, 0X5780, 0X9741, 0X5500, 0X95C1, 0X9481, 0X5440,
  37. 0X9C01, 0X5CC0, 0X5D80, 0X9D41, 0X5F00, 0X9FC1, 0X9E81, 0X5E40,
  38. 0X5A00, 0X9AC1, 0X9B81, 0X5B40, 0X9901, 0X59C0, 0X5880, 0X9841,
  39. 0X8801, 0X48C0, 0X4980, 0X8941, 0X4B00, 0X8BC1, 0X8A81, 0X4A40,
  40. 0X4E00, 0X8EC1, 0X8F81, 0X4F40, 0X8D01, 0X4DC0, 0X4C80, 0X8C41,
  41. 0X4400, 0X84C1, 0X8581, 0X4540, 0X8701, 0X47C0, 0X4680, 0X8641,
  42. 0X8201, 0X42C0, 0X4380, 0X8341, 0X4100, 0X81C1, 0X8081, 0X4040};
  43. // crc校验
  44. uint16_t mmodbus_crc16(const uint8_t *nData, uint16_t wLength)
  45. {
  46. uint8_t nTemp;
  47. uint16_t wCRCWord = 0xFFFF;
  48. while (wLength--)
  49. {
  50. nTemp = *nData++ ^ wCRCWord;
  51. wCRCWord >>= 8;
  52. wCRCWord ^= wCRCTable[nTemp];
  53. }
  54. return wCRCWord;
  55. }
  56. #endif
  57. void mmodbus_callback(UART_HandleTypeDef *husart)
  58. {
  59. if(__HAL_UART_GET_FLAG(husart, UART_FLAG_RXNE) && __HAL_UART_GET_IT_SOURCE(husart, UART_IT_RXNE))
  60. {
  61. if (mmodbus.rxIndex < _MMODBUS_RXSIZE - 1)
  62. {
  63. mmodbus.rxBuf[mmodbus.rxIndex] = husart->Instance->DR;
  64. mmodbus.rxIndex++;
  65. }
  66. else
  67. {
  68. uint8_t data = husart->Instance->DR;
  69. }
  70. }
  71. if ((mmodbus.rxIndex > 0) && RESET != __HAL_UART_GET_FLAG(husart, USART_FLAG_IDLE) && __HAL_UART_GET_IT_SOURCE(husart, UART_IT_IDLE))
  72. {
  73. uint8_t i;
  74. mmodbus.done = 1;
  75. i = husart->Instance->SR;
  76. i = husart->Instance->DR;
  77. return;
  78. }
  79. mmodbus.rxTime = gettick();
  80. }
  81. // ##################################################################################################
  82. uint16_t mmodbus_receiveRaw(uint32_t timeout)
  83. {
  84. uint32_t startTime = gettick();
  85. while (1)
  86. {
  87. if (gettick() - startTime> timeout * 1000)
  88. return 0;
  89. if (mmodbus.done == 1)
  90. {
  91. return mmodbus.rxIndex;
  92. }
  93. mmodbus_delay(5);
  94. }
  95. }
  96. // ##################################################################################################
  97. bool mmodbus_sendRaw(uint8_t *data, uint16_t size, uint32_t timeout)
  98. {
  99. GATEWAY_PARAMS *get;
  100. get= get_gateway_config_params();
  101. while(mmodbus.txBusy == 1)
  102. mmodbus_delay(1);
  103. mmodbus.txBusy = 1;
  104. memset(mmodbus.rxBuf, 0, _MMODBUS_RXSIZE);
  105. mmodbus.rxIndex = 0;
  106. mmodbus.done = 0;
  107. uint32_t startTime = gettick();
  108. portENTER_CRITICAL();
  109. if(get->comProtocol){ // get->protocol 1:232 0:485
  110. USART_232_Send(data,size);
  111. }else{
  112. USART_485_Send(data,size);
  113. }
  114. portEXIT_CRITICAL();
  115. mmodbus.done=0;
  116. mmodbus.txBusy = 0;
  117. return true;
  118. }
  119. // ##################################################################################################
  120. bool mmodbus_init(uint32_t timeout)
  121. {
  122. // HAL_GPIO_WritePin(_MMODBUS_CTRL_GPIO, _MMODBUS_CTRL_PIN, GPIO_PIN_RESET); 此处初始化在485 init过
  123. HAL_GPIO_WritePin(_MMODBUS_CTRL_GPIO, _MMODBUS_CTRL_PIN,0);
  124. memset(&mmodbus, 0, sizeof(mmodbus));
  125. mmodbus.timeout = timeout;
  126. return true;
  127. }
  128. // ##################################################################################################
  129. void mmodbus_set16bitOrder(MModBus_16bitOrder_t MModBus_16bitOrder_)
  130. {
  131. mmodbus.byteOrder16 = MModBus_16bitOrder_;
  132. }
  133. // ##################################################################################################
  134. void mmodbus_set32bitOrder(MModBus_32bitOrder_t MModBus_32bitOrder_)
  135. {
  136. mmodbus.byteOrder32 = MModBus_32bitOrder_;
  137. }
  138. // ##################################################################################################
  139. bool mmodbus_readCoil(uint8_t slaveAddress, uint16_t number, uint8_t *data)
  140. {
  141. return mmodbus_readCoils(slaveAddress, number, 1, data);
  142. }
  143. // ##################################################################################################
  144. // 读线圈
  145. bool mmodbus_readCoils(uint8_t slaveAddress, uint16_t startnumber, uint16_t length, uint8_t *data)
  146. {
  147. #if (_MMODBUS_RTU == 1)
  148. uint8_t txData[8];
  149. txData[0] = slaveAddress;
  150. txData[1] = MModbusCMD_ReadCoilStatus;
  151. txData[2] = (startnumber & 0xFF00) >> 8;
  152. txData[3] = (startnumber & 0x00FF);
  153. txData[4] = (length & 0xFF00) >> 8;
  154. txData[5] = (length & 0x00FF);
  155. static uint16_t crc;
  156. crc = mmodbus_crc16(txData, 6);
  157. txData[6] = (crc & 0x00FF);
  158. txData[7] = (crc & 0xFF00) >> 8;
  159. mmodbus_sendRaw(txData, 8, 100);
  160. uint16_t recLen = mmodbus_receiveRaw(mmodbus.timeout);
  161. if (recLen == 0)
  162. return false;
  163. if (mmodbus.rxBuf[0] != slaveAddress)
  164. return false;
  165. if (mmodbus.rxBuf[1] != MModbusCMD_ReadCoilStatus)
  166. return false;
  167. crc = mmodbus_crc16(mmodbus.rxBuf, mmodbus.rxBuf[2] + 3);
  168. if (((crc & 0x00FF) != mmodbus.rxBuf[mmodbus.rxBuf[2] + 3]) || (((crc & 0xFF00) >> 8) != mmodbus.rxBuf[mmodbus.rxBuf[2] + 4]))
  169. return false;
  170. if (data != NULL)
  171. memcpy(data, &mmodbus.rxBuf[3], mmodbus.rxBuf[2]);
  172. return true;
  173. #endif
  174. #if (_MMODBUS_ASCII == 1)
  175. #endif
  176. }
  177. // ##################################################################################################
  178. bool mmodbus_readDiscreteInput(uint8_t slaveAddress, uint16_t number, uint8_t *data)
  179. {
  180. return mmodbus_readDiscreteInputs(slaveAddress, number, 1, data);
  181. }
  182. // ##################################################################################################
  183. // 读取线圈功能码处理
  184. bool mmodbus_readDiscreteInputs(uint8_t slaveAddress, uint16_t startnumber, uint16_t length, uint8_t *data)
  185. {
  186. #if (_MMODBUS_RTU == 1)
  187. uint8_t txData[8];
  188. txData[0] = slaveAddress;
  189. txData[1] = MModbusCMD_ReadDiscreteInputs;
  190. txData[2] = (startnumber & 0xFF00) >> 8;
  191. txData[3] = (startnumber & 0x00FF);
  192. txData[4] = (length & 0xFF00) >> 8;
  193. txData[5] = (length & 0x00FF);
  194. static uint16_t crc;
  195. crc = mmodbus_crc16(txData, 6);
  196. txData[6] = (crc & 0x00FF);
  197. txData[7] = (crc & 0xFF00) >> 8;
  198. mmodbus_sendRaw(txData, 8, 100);
  199. uint16_t recLen = mmodbus_receiveRaw(mmodbus.timeout);
  200. if (recLen == 0)
  201. return false;
  202. if (mmodbus.rxBuf[0] != slaveAddress)
  203. return false;
  204. if (mmodbus.rxBuf[1] != MModbusCMD_ReadDiscreteInputs)
  205. return false;
  206. crc = mmodbus_crc16(mmodbus.rxBuf, mmodbus.rxBuf[2] + 3);
  207. if (((crc & 0x00FF) != mmodbus.rxBuf[mmodbus.rxBuf[2] + 3]) || (((crc & 0xFF00) >> 8) != mmodbus.rxBuf[mmodbus.rxBuf[2] + 4]))
  208. return false;
  209. if (data != NULL)
  210. memcpy(data, &mmodbus.rxBuf[3], mmodbus.rxBuf[2]);
  211. return true;
  212. #endif
  213. }
  214. // ##################################################################################################
  215. bool mmodbus_readInputRegisters8i(uint8_t slaveAddress, uint16_t startnumber, uint16_t length, uint8_t *data)
  216. {
  217. #if (_MMODBUS_RTU == 1)
  218. uint8_t txData[8];
  219. txData[0] = slaveAddress;
  220. txData[1] = MModbusCMD_ReadInputRegisters;
  221. txData[2] = (startnumber & 0xFF00) >> 8;
  222. txData[3] = (startnumber & 0x00FF);
  223. txData[4] = (length & 0xFF00) >> 8;
  224. txData[5] = (length & 0x00FF);
  225. static uint16_t crc;
  226. crc = mmodbus_crc16(txData, 6);
  227. txData[6] = (crc & 0x00FF);
  228. txData[7] = (crc & 0xFF00) >> 8;
  229. mmodbus_sendRaw(txData, 8, 100);
  230. uint16_t recLen = mmodbus_receiveRaw(mmodbus.timeout);
  231. if (recLen == 0)
  232. return false;
  233. if (mmodbus.rxBuf[0] != slaveAddress)
  234. return false;
  235. if (mmodbus.rxBuf[1] != MModbusCMD_ReadInputRegisters)
  236. return false;
  237. crc = mmodbus_crc16(mmodbus.rxBuf, mmodbus.rxBuf[2] + 3);
  238. if (((crc & 0x00FF) != mmodbus.rxBuf[mmodbus.rxBuf[2] + 3]) || (((crc & 0xFF00) >> 8) != mmodbus.rxBuf[mmodbus.rxBuf[2] + 4]))
  239. return false;
  240. if (data != NULL)
  241. memcpy(data, &mmodbus.rxBuf[3], mmodbus.rxBuf[2]);
  242. return true;
  243. #endif
  244. }
  245. // ##################################################################################################
  246. bool mmodbus_readInputRegister32f(uint8_t slaveAddress, uint16_t number, float *data)
  247. {
  248. return mmodbus_readInputRegisters32f(slaveAddress, number, 1, data);
  249. }
  250. // ##################################################################################################
  251. bool mmodbus_readInputRegisters32f(uint8_t slaveAddress, uint16_t startnumber, uint16_t length, float *data)
  252. {
  253. bool ret = mmodbus_readInputRegisters8i(slaveAddress, startnumber, length * 2, (uint8_t *)data);
  254. if (ret == true)
  255. {
  256. for (uint16_t i = 0; i < length; i++)
  257. {
  258. uint8_t tmp1[4], tmp2[4];
  259. switch (mmodbus.byteOrder32)
  260. {
  261. case MModBus_32bitOrder_DCBA:
  262. memcpy(tmp1, &data[i], 4);
  263. tmp2[0] = tmp1[3];
  264. tmp2[1] = tmp1[2];
  265. tmp2[2] = tmp1[1];
  266. tmp2[3] = tmp1[0];
  267. memcpy(&data[i], tmp2, 4);
  268. break;
  269. case MModBus_32bitOrder_BADC:
  270. memcpy(tmp1, &data[i], 4);
  271. tmp2[0] = tmp1[1];
  272. tmp2[1] = tmp1[0];
  273. tmp2[2] = tmp1[3];
  274. tmp2[3] = tmp1[2];
  275. memcpy(&data[i], tmp2, 4);
  276. break;
  277. case MModBus_32bitOrder_CDAB:
  278. memcpy(tmp1, &data[i], 4);
  279. tmp2[0] = tmp1[2];
  280. tmp2[1] = tmp1[3];
  281. tmp2[2] = tmp1[0];
  282. tmp2[3] = tmp1[1];
  283. memcpy(&data[i], tmp2, 4);
  284. break;
  285. default:
  286. break;
  287. }
  288. }
  289. return true;
  290. }
  291. else
  292. return false;
  293. }
  294. // ##################################################################################################
  295. bool mmodbus_readInputRegister32i(uint8_t slaveAddress, uint16_t number, uint32_t *data)
  296. {
  297. return mmodbus_readInputRegisters32i(slaveAddress, number, 1, data);
  298. }
  299. // ##################################################################################################
  300. bool mmodbus_readInputRegisters32i(uint8_t slaveAddress, uint16_t startnumber, uint16_t length, uint32_t *data)
  301. {
  302. return mmodbus_readInputRegisters32f(slaveAddress, startnumber, length, (float *)data);
  303. }
  304. // ##################################################################################################
  305. bool mmodbus_readInputRegister16i(uint8_t slaveAddress, uint16_t number, uint16_t *data)
  306. {
  307. return mmodbus_readInputRegisters16i(slaveAddress, number, 1, data);
  308. }
  309. // ##################################################################################################
  310. bool mmodbus_readInputRegisters16i(uint8_t slaveAddress, uint16_t startnumber, uint16_t length, uint16_t *data)
  311. {
  312. bool ret = mmodbus_readInputRegisters8i(slaveAddress, startnumber, length * 1, (uint8_t *)data);
  313. if (ret == true)
  314. {
  315. uint8_t tmp1[2], tmp2[2];
  316. for (uint16_t i = 0; i < length; i++)
  317. {
  318. switch (mmodbus.byteOrder16)
  319. {
  320. case MModBus_16bitOrder_AB:
  321. memcpy(tmp1, &data[i], 2);
  322. tmp2[0] = tmp1[0];
  323. tmp2[1] = tmp1[1];
  324. memcpy(&data[i], tmp2, 2);
  325. break;
  326. default:
  327. memcpy(tmp1, &data[i], 2);
  328. tmp2[0] = tmp1[1];
  329. tmp2[1] = tmp1[0];
  330. memcpy(&data[i], tmp2, 2);
  331. break;
  332. }
  333. }
  334. return true;
  335. }
  336. else
  337. return false;
  338. }
  339. // ##################################################################################################
  340. bool mmodbus_readHoldingRegisters8i(uint8_t slaveAddress, uint16_t startnumber, uint16_t length, uint8_t *data)
  341. {
  342. #if (_MMODBUS_RTU == 1)
  343. uint8_t txData[8];
  344. txData[0] = slaveAddress;
  345. txData[1] = MModbusCMD_ReadHoldingRegisters;
  346. txData[2] = (startnumber & 0xFF00) >> 8;
  347. txData[3] = (startnumber & 0x00FF);
  348. txData[4] = (length & 0xFF00) >> 8;
  349. txData[5] = (length & 0x00FF);
  350. static uint16_t crc;
  351. crc = mmodbus_crc16(txData, 6);
  352. txData[6] = (crc & 0x00FF);
  353. txData[7] = (crc & 0xFF00) >> 8;
  354. mmodbus_sendRaw(txData, 8, 100);
  355. uint16_t recLen = mmodbus_receiveRaw(mmodbus.timeout);
  356. if (recLen == 0)
  357. return false;
  358. if (mmodbus.rxBuf[0] != slaveAddress)
  359. return false;
  360. if (mmodbus.rxBuf[1] != MModbusCMD_ReadHoldingRegisters)
  361. return false;
  362. crc = mmodbus_crc16(mmodbus.rxBuf, mmodbus.rxBuf[2] + 3);
  363. if (((crc & 0x00FF) != mmodbus.rxBuf[mmodbus.rxBuf[2] + 3]) || (((crc & 0xFF00) >> 8) != mmodbus.rxBuf[mmodbus.rxBuf[2] + 4]))
  364. return false;
  365. if (data != NULL)
  366. {
  367. for (uint8_t i = 0; i < mmodbus.rxBuf[2]; i += 2)
  368. {
  369. uint8_t H = mmodbus.rxBuf[i + 3];
  370. mmodbus.rxBuf[i + 3] = mmodbus.rxBuf[i + 3 + 1];
  371. mmodbus.rxBuf[i + 3 + 1] = H;
  372. }
  373. memcpy(data, &mmodbus.rxBuf[3], mmodbus.rxBuf[2]);
  374. }
  375. return true;
  376. #endif
  377. }
  378. // ##################################################################################################
  379. bool mmodbus_readHoldingRegister32f(uint8_t slaveAddress, uint16_t number, float *data)
  380. {
  381. return mmodbus_readHoldingRegisters32f(slaveAddress, number, 1, data);
  382. }
  383. // ##################################################################################################
  384. bool mmodbus_readHoldingRegisters32f(uint8_t slaveAddress, uint16_t startnumber, uint16_t length, float *data)
  385. {
  386. bool ret = mmodbus_readHoldingRegisters8i(slaveAddress, startnumber, length * 2, (uint8_t *)data);
  387. if (ret == true)
  388. {
  389. for (uint16_t i = 0; i < length; i++)
  390. {
  391. uint8_t tmp1[4], tmp2[4];
  392. switch (mmodbus.byteOrder32)
  393. {
  394. case MModBus_32bitOrder_DCBA:
  395. memcpy(tmp1, &data[i], 4);
  396. tmp2[0] = tmp1[3];
  397. tmp2[1] = tmp1[2];
  398. tmp2[2] = tmp1[1];
  399. tmp2[3] = tmp1[0];
  400. memcpy(&data[i], tmp2, 4);
  401. break;
  402. case MModBus_32bitOrder_BADC:
  403. memcpy(tmp1, &data[i], 4);
  404. tmp2[0] = tmp1[1];
  405. tmp2[1] = tmp1[0];
  406. tmp2[2] = tmp1[3];
  407. tmp2[3] = tmp1[2];
  408. memcpy(&data[i], tmp2, 4);
  409. break;
  410. case MModBus_32bitOrder_CDAB:
  411. memcpy(tmp1, &data[i], 4);
  412. tmp2[0] = tmp1[2];
  413. tmp2[1] = tmp1[3];
  414. tmp2[2] = tmp1[0];
  415. tmp2[3] = tmp1[1];
  416. memcpy(&data[i], tmp2, 4);
  417. break;
  418. default:
  419. break;
  420. }
  421. }
  422. return true;
  423. }
  424. else
  425. return false;
  426. }
  427. // ##################################################################################################
  428. bool mmodbus_readHoldingRegister32i(uint8_t slaveAddress, uint16_t number, uint32_t *data)
  429. {
  430. return mmodbus_readHoldingRegisters32i(slaveAddress, number, 1, data);
  431. }
  432. // ##################################################################################################
  433. bool mmodbus_readHoldingRegisters32i(uint8_t slaveAddress, uint16_t startnumber, uint16_t length, uint32_t *data)
  434. {
  435. return mmodbus_readHoldingRegisters32f(slaveAddress, startnumber, length, (float *)data);
  436. }
  437. // ##################################################################################################
  438. bool mmodbus_readHoldingRegister16i(uint8_t slaveAddress, uint16_t number, uint16_t *data)
  439. {
  440. return mmodbus_readHoldingRegisters16i(slaveAddress, number, 1, data);
  441. }
  442. // ##################################################################################################
  443. bool mmodbus_readHoldingRegisters16i(uint8_t slaveAddress, uint16_t startnumber, uint16_t length, uint16_t *data)
  444. {
  445. bool ret = mmodbus_readHoldingRegisters8i(slaveAddress, startnumber, length * 1, (uint8_t *)data);
  446. if (ret == true)
  447. {
  448. uint8_t tmp1[2], tmp2[2];
  449. for (uint16_t i = 0; i < length; i++)
  450. {
  451. switch (mmodbus.byteOrder16)
  452. {
  453. case MModBus_16bitOrder_AB:
  454. memcpy(tmp1, &data[i], 2);
  455. tmp2[0] = tmp1[0];
  456. tmp2[1] = tmp1[1];
  457. memcpy(&data[i], tmp2, 2);
  458. break;
  459. default:
  460. memcpy(tmp1, &data[i], 2);
  461. tmp2[0] = tmp1[1];
  462. tmp2[1] = tmp1[0];
  463. memcpy(&data[i], tmp2, 2);
  464. break;
  465. }
  466. }
  467. return true;
  468. }
  469. else
  470. return false;
  471. }
  472. // ##################################################################################################
  473. bool mmodbus_writeCoil(uint8_t slaveAddress, uint16_t number, uint8_t data)
  474. {
  475. #if (_MMODBUS_RTU == 1)
  476. uint8_t txData[8];
  477. txData[0] = slaveAddress;
  478. txData[1] = MModbusCMD_WriteSingleCoil;
  479. txData[2] = (number & 0xFF00) >> 8;
  480. txData[3] = (number & 0x00FF);
  481. if (data == 0)
  482. txData[4] = 0;
  483. else
  484. txData[4] = 0xFF;
  485. txData[5] = 0;
  486. static uint16_t crc;
  487. crc = mmodbus_crc16(txData, 6);
  488. txData[6] = (crc & 0x00FF);
  489. txData[7] = (crc & 0xFF00) >> 8;
  490. mmodbus_sendRaw(txData, 8, 100);
  491. uint16_t recLen = mmodbus_receiveRaw(mmodbus.timeout);
  492. if (recLen == 0)
  493. return false;
  494. if (memcmp(txData, mmodbus.rxBuf, 8) == 0)
  495. return true;
  496. else
  497. return false;
  498. #endif
  499. #if (_MMODBUS_ASCII == 1)
  500. #endif
  501. }
  502. // ##################################################################################################
  503. bool mmodbus_writeHoldingRegister16i(uint8_t slaveAddress, uint16_t number, uint16_t data)
  504. {
  505. #if (_MMODBUS_RTU == 1)
  506. uint8_t txData[8];
  507. txData[0] = slaveAddress;
  508. txData[1] = MModbusCMD_WriteSingleRegister;
  509. txData[2] = (number & 0xFF00) >> 8;
  510. txData[3] = (number & 0x00FF);
  511. txData[4] = (data & 0xFF00) >> 8;
  512. txData[5] = data & 0x00FF;
  513. static uint16_t crc;
  514. crc = mmodbus_crc16(txData, 6);
  515. txData[6] = (crc & 0x00FF);
  516. txData[7] = (crc & 0xFF00) >> 8;
  517. mmodbus_sendRaw(txData, 8, 100);
  518. uint16_t recLen = mmodbus_receiveRaw(mmodbus.timeout);
  519. if (recLen == 0)
  520. return false;
  521. if (memcmp(txData, mmodbus.rxBuf, 8) == 0)
  522. return true;
  523. else
  524. return false;
  525. #endif
  526. #if (_MMODBUS_ASCII == 1)
  527. #endif
  528. }
  529. // ##################################################################################################
  530. bool mmodbus_writeHoldingRegisters16i(uint8_t slaveAddress, uint16_t startnumber, uint16_t length, uint16_t *data)
  531. {
  532. #if (_MMODBUS_RTU == 1)
  533. if (length == 1)
  534. {
  535. return mmodbus_writeHoldingRegister16i(slaveAddress, startnumber, data[0]);
  536. }
  537. else
  538. {
  539. uint8_t txData[7 + length * 2 + 2];
  540. txData[0] = slaveAddress;
  541. txData[1] = MModbusCMD_WriteMultipleRegisters;
  542. txData[2] = (startnumber & 0xFF00) >> 8;
  543. txData[3] = (startnumber & 0x00FF);
  544. txData[4] = (length & 0xFF00) >> 8;
  545. txData[5] = (length & 0x00FF);
  546. txData[6] = (length * 2);
  547. uint8_t tmp1[2], tmp2[2];
  548. for (uint16_t i = 0; i < length; i++)
  549. {
  550. switch (mmodbus.byteOrder16)
  551. {
  552. case MModBus_16bitOrder_AB:
  553. memcpy(tmp1, &data[i], 2);
  554. tmp2[0] = tmp1[1];
  555. tmp2[1] = tmp1[0];
  556. memcpy(&txData[7 + i * 2], tmp2, 2);
  557. break;
  558. default:
  559. memcpy(tmp1, &data[i], 2);
  560. tmp2[0] = tmp1[0];
  561. tmp2[1] = tmp1[1];
  562. memcpy(&txData[7 + i * 2], tmp2, 2);
  563. break;
  564. }
  565. }
  566. static uint16_t crc;
  567. crc = mmodbus_crc16(txData, 7 + length * 2);
  568. txData[7 + length * 2 + 0] = (crc & 0x00FF);
  569. txData[7 + length * 2 + 1] = (crc & 0xFF00) >> 8;
  570. mmodbus_sendRaw(txData, 7 + length * 2 + 2, 100);
  571. uint16_t recLen = mmodbus_receiveRaw(mmodbus.timeout);
  572. if (recLen == 0)
  573. return false;
  574. crc = mmodbus_crc16(txData, 6);
  575. txData[6] = (crc & 0x00FF);
  576. txData[7] = (crc & 0xFF00) >> 8;
  577. if (memcmp(txData, mmodbus.rxBuf, 8) == 0)
  578. return true;
  579. else
  580. return false;
  581. }
  582. #endif
  583. #if (_MMODBUS_ASCII == 1)
  584. #endif
  585. }
  586. // ##################################################################################################