mmodbus.c 21 KB

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