MODBUS_LOW_ATY.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359
  1. /**
  2. * @file MODBUS_LOW_ATY.c
  3. *
  4. * @param Project DEVICE_GENERAL_ATY_LIB
  5. *
  6. * @author ATY
  7. *
  8. * @copyright
  9. * - Copyright 2017 - 2023 MZ-ATY
  10. * - This code follows:
  11. * - MZ-ATY Various Contents Joint Statement -
  12. * <a href="https://mengze.top/MZ-ATY_VCJS">
  13. * https://mengze.top/MZ-ATY_VCJS</a>
  14. * - CC 4.0 BY-NC-SA -
  15. * <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/">
  16. * https://creativecommons.org/licenses/by-nc-sa/4.0/</a>
  17. * - Your use will be deemed to have accepted the terms of this statement.
  18. *
  19. * @brief Familiar functions of modbus for all device
  20. *
  21. * @version
  22. * - 1_01_221029 > ATY
  23. * -# Preliminary version, first Release
  24. ********************************************************************************
  25. */
  26. #ifndef __MODBUS_LOW_ATY_C
  27. #define __MODBUS_LOW_ATY_C
  28. #include "MODBUS_LOW_ATY.h"
  29. /******************************* For user *************************************/
  30. /******************************************************************************/
  31. #if defined(MODBUS_FLOAT_MODE)
  32. float mbRegHoding[MODBUS_REG_HOLDING_SIZE] = {0};
  33. /**
  34. * @brief modbus process with float
  35. * @note only make 03/06/10 function code, others will return err 01
  36. */
  37. void Modbus_Process(uint8_t* buf, uint8_t len)
  38. {
  39. uint8_t sendBuf[(MODBUS_REG_HOLDING_SIZE * 4) + 4] = {0x00};
  40. uint16_t snedBufSize = 4;
  41. if(len < 4) return; // check buf min size
  42. if(buf[0] != MODBUS_ADDR) return; // check addr
  43. if(CheckCrc16Modbus(buf, len)) return; // check crc
  44. sendBuf[0] = buf[0];
  45. sendBuf[1] = buf[1];
  46. switch(buf[1]) // check function code
  47. {
  48. // case MODBUS_FUNC_READ_COILS:{break; }
  49. // case MODBUS_FUNC_READ_DISCRETE_INPUTS:{break; }
  50. case MODBUS_FUNC_READ_HOLDING_REGISTERS:{
  51. uint16_t i = 0, startAddr = 0, regCount = 0;
  52. startAddr = ((buf[2] << 8) + buf[3]);
  53. regCount = ((buf[4] << 8) + buf[5]);
  54. if(startAddr + regCount - 1 > MODBUS_REG_HOLDING_SIZE){
  55. sendBuf[1] = buf[1] + 0x80;
  56. sendBuf[2] = 0x02;
  57. snedBufSize = 6;
  58. break;
  59. }
  60. sendBuf[2] = regCount * 4;
  61. snedBufSize += 1;
  62. for(i = 0; i < regCount; i++){
  63. sendBuf[2 + (i * 4) + 1] = (uint32_t)(MUL_FLOAT * mbRegHoding[startAddr + i]) >> 24;
  64. sendBuf[2 + (i * 4) + 2] = (uint32_t)(MUL_FLOAT * mbRegHoding[startAddr + i]) >> 16;
  65. sendBuf[2 + (i * 4) + 3] = (uint32_t)(MUL_FLOAT * mbRegHoding[startAddr + i]) >> 8;
  66. sendBuf[2 + (i * 4) + 4] = (uint32_t)(MUL_FLOAT * mbRegHoding[startAddr + i]);
  67. snedBufSize += 4;
  68. }
  69. break; }
  70. // case MODBUS_FUNC_READ_INPUT_REGISTERS:{break; }
  71. // case MODBUS_FUNC_WRITE_SINGLE_COIL:{break; }
  72. case MODBUS_FUNC_WRITE_SINGLE_HOLDING_REGISTERS:{
  73. uint16_t startAddr = 0;
  74. float regValue = 0.0;
  75. startAddr = (((uint16_t)buf[2] << 8) + (uint16_t)buf[3]);
  76. if(startAddr >= MODBUS_REG_HOLDING_SIZE){
  77. sendBuf[1] = buf[1] + 0x80;
  78. sendBuf[2] = 0x02;
  79. snedBufSize = 6;
  80. break;
  81. }
  82. regValue = (((uint32_t)buf[4] << 24) + ((uint32_t)buf[5] << 16) + ((uint32_t)buf[6] << 8) + (uint32_t)buf[7]);
  83. mbRegHoding[startAddr] = regValue / MUL_FLOAT;
  84. // sendBuf[2] = buf[2];
  85. // sendBuf[3] = buf[3];
  86. // sendBuf[4] = buf[4];
  87. // sendBuf[5] = buf[5];
  88. // sendBuf[6] = buf[6];
  89. // sendBuf[7] = buf[7];
  90. sendBuf[2] = startAddr >> 8;
  91. sendBuf[3] = startAddr;
  92. sendBuf[4] = ((uint32_t)regValue >> 24);
  93. sendBuf[5] = ((uint32_t)regValue >> 16);
  94. sendBuf[6] = ((uint32_t)regValue >> 8);
  95. sendBuf[7] = (uint32_t)regValue;
  96. snedBufSize += 6;
  97. break; }
  98. // case MODBUS_FUNC_WRITE_MULTY_HOLDING_REGISTERS:{
  99. // uint16_t i = 0, startAddr = 0, regCount = 0;
  100. // startAddr = ((buf[2] << 8) + buf[3]);
  101. // regCount = ((buf[4] << 8) + buf[5]);
  102. // if(startAddr + regCount - 1 >= MODBUS_REG_HOLDING_SIZE){
  103. // sendBuf[1] = buf[1] + 0x80;
  104. // sendBuf[2] = 0x02;
  105. // snedBufSize = 6;
  106. // break;
  107. // }
  108. // for(i = 0; i < regCount; i++)
  109. // mbRegHoding[startAddr + i] =
  110. // ((buf[7 + (i * 2)] << 8) + buf[8 + (i * 2)]) / MUL_FLOAT;
  111. // sendBuf[2] = startAddr >> 8;
  112. // sendBuf[3] = startAddr;
  113. // sendBuf[4] = regCount >> 8;
  114. // sendBuf[5] = regCount;
  115. // snedBufSize += 4;
  116. // break; }
  117. default:{
  118. sendBuf[1] = buf[1] + 0x80;
  119. sendBuf[2] = 0x01;
  120. snedBufSize = 6;
  121. break; }
  122. }
  123. sendBuf[snedBufSize - 2] = GenCrc16ModbusHL(sendBuf, snedBufSize - 2, 1);
  124. sendBuf[snedBufSize - 1] = GenCrc16ModbusHL(sendBuf, snedBufSize - 2, 0);
  125. UartSendBytes(sendBuf, snedBufSize);
  126. }
  127. #elif defined(MODBUS_FLOAT_CODE_MODE)
  128. __XDATA float mbRegHoding[MODBUS_REG_HOLDING_SIZE] = {0};
  129. union{ float f_t; uint8_t u8_t[4]; }mbFloatChange_u;
  130. /**
  131. * @brief modbus process with float
  132. * @note only make 03/06/10 function code, others will return err 01
  133. */
  134. void Modbus_Process(uint8_t* buf, uint8_t len)
  135. {
  136. uint8_t sendBuf[(MODBUS_REG_HOLDING_SIZE * 4) + 4] = {0x00};
  137. uint16_t sendBufSize = 4;
  138. if(len < 4) return; // check buf min size
  139. if(buf[0] != MODBUS_ADDR) return; // check addr
  140. if(CheckCrc16Modbus(buf, len)) return; // check crc
  141. sendBuf[0] = buf[0];
  142. sendBuf[1] = buf[1];
  143. switch(buf[1]) // check function code
  144. {
  145. // case MODBUS_FUNC_READ_COILS:{break; }
  146. // case MODBUS_FUNC_READ_DISCRETE_INPUTS:{break; }
  147. case MODBUS_FUNC_READ_HOLDING_REGISTERS:{
  148. uint16_t i = 0, startAddr = 0, regCount = 0;
  149. startAddr = ((buf[2] << 8) + buf[3]);
  150. regCount = ((buf[4] << 8) + buf[5]);
  151. if(startAddr + regCount - 1 > MODBUS_REG_HOLDING_SIZE){
  152. sendBuf[1] = buf[1] + 0x80;
  153. sendBuf[2] = 0x02;
  154. sendBufSize = 6;
  155. break;
  156. }
  157. sendBuf[2] = regCount * 4;
  158. sendBufSize += 1;
  159. for(i = 0; i < regCount; i++){
  160. mbFloatChange_u.f_t = mbRegHoding[startAddr + i];
  161. #ifdef BIG_ENDIAN
  162. sendBuf[2 + (i * 4) + 1] = mbFloatChange_u.u8_t[0];
  163. sendBuf[2 + (i * 4) + 2] = mbFloatChange_u.u8_t[1];
  164. sendBuf[2 + (i * 4) + 3] = mbFloatChange_u.u8_t[2];
  165. sendBuf[2 + (i * 4) + 4] = mbFloatChange_u.u8_t[3];
  166. #else
  167. sendBuf[2 + (i * 4) + 1] = mbFloatChange_u.u8_t[3];
  168. sendBuf[2 + (i * 4) + 2] = mbFloatChange_u.u8_t[2];
  169. sendBuf[2 + (i * 4) + 3] = mbFloatChange_u.u8_t[1];
  170. sendBuf[2 + (i * 4) + 4] = mbFloatChange_u.u8_t[0];
  171. #endif
  172. sendBufSize += 4;
  173. }
  174. break; }
  175. // case MODBUS_FUNC_READ_INPUT_REGISTERS:{break; }
  176. // case MODBUS_FUNC_WRITE_SINGLE_COIL:{break; }
  177. case MODBUS_FUNC_WRITE_SINGLE_HOLDING_REGISTERS:{
  178. uint16_t startAddr = 0;
  179. float regValue = 0.0;
  180. startAddr = (((uint16_t)buf[2] << 8) + (uint16_t)buf[3]);
  181. if(startAddr >= MODBUS_REG_HOLDING_SIZE){
  182. sendBuf[1] = buf[1] + 0x80;
  183. sendBuf[2] = 0x02;
  184. sendBufSize = 6;
  185. break;
  186. }
  187. #ifdef BIG_ENDIAN
  188. mbFloatChange_u.u8_t[0] = buf[4];
  189. mbFloatChange_u.u8_t[1] = buf[5];
  190. mbFloatChange_u.u8_t[2] = buf[6];
  191. mbFloatChange_u.u8_t[3] = buf[7];
  192. #else
  193. mbFloatChange_u.u8_t[3] = buf[4];
  194. mbFloatChange_u.u8_t[2] = buf[5];
  195. mbFloatChange_u.u8_t[1] = buf[6];
  196. mbFloatChange_u.u8_t[0] = buf[7];
  197. #endif
  198. regValue = mbFloatChange_u.f_t;
  199. mbRegHoding[startAddr] = regValue;
  200. sendBuf[2] = startAddr >> 8;
  201. sendBuf[3] = startAddr;
  202. #ifdef BIG_ENDIAN
  203. sendBuf[4] = mbFloatChange_u.u8_t[0];
  204. sendBuf[5] = mbFloatChange_u.u8_t[1];
  205. sendBuf[6] = mbFloatChange_u.u8_t[2];
  206. sendBuf[7] = mbFloatChange_u.u8_t[3];
  207. #else
  208. sendBuf[4] = mbFloatChange_u.u8_t[3];
  209. sendBuf[5] = mbFloatChange_u.u8_t[2];
  210. sendBuf[6] = mbFloatChange_u.u8_t[1];
  211. sendBuf[7] = mbFloatChange_u.u8_t[0];
  212. #endif
  213. sendBufSize += 6;
  214. break; }
  215. case MODBUS_FUNC_WRITE_MULTY_HOLDING_REGISTERS:{
  216. uint16_t i = 0, startAddr = 0, regCount = 0;
  217. startAddr = ((buf[2] << 8) + buf[3]);
  218. regCount = ((buf[4] << 8) + buf[5]);
  219. if(startAddr + regCount - 1 > MODBUS_REG_HOLDING_SIZE){
  220. sendBuf[1] = buf[1] + 0x80;
  221. sendBuf[2] = 0x02;
  222. sendBufSize = 6;
  223. break;
  224. }
  225. for(i = 0; i < regCount; i++)
  226. {
  227. float regValue = 0.0;
  228. #ifdef BIG_ENDIAN
  229. mbFloatChange_u.u8_t[0] = buf[6 + (i * 4) + 1];
  230. mbFloatChange_u.u8_t[1] = buf[6 + (i * 4) + 2];
  231. mbFloatChange_u.u8_t[2] = buf[6 + (i * 4) + 3];
  232. mbFloatChange_u.u8_t[3] = buf[6 + (i * 4) + 4];
  233. #else
  234. mbFloatChange_u.u8_t[3] = buf[6 + (i * 4) + 1];
  235. mbFloatChange_u.u8_t[2] = buf[6 + (i * 4) + 2];
  236. mbFloatChange_u.u8_t[1] = buf[6 + (i * 4) + 3];
  237. mbFloatChange_u.u8_t[0] = buf[6 + (i * 4) + 4];
  238. #endif
  239. regValue = mbFloatChange_u.f_t;
  240. mbRegHoding[startAddr + i] = regValue;
  241. }
  242. sendBuf[2] = startAddr >> 8;
  243. sendBuf[3] = startAddr;
  244. sendBuf[4] = regCount >> 8;
  245. sendBuf[5] = regCount;
  246. sendBufSize += 4;
  247. break; }
  248. default:{
  249. sendBuf[1] = buf[1] + 0x80;
  250. sendBuf[2] = 0x01;
  251. sendBufSize = 6;
  252. break; }
  253. }
  254. sendBuf[sendBufSize - 2] = GenCrc16ModbusHL(sendBuf, sendBufSize - 2, 1);
  255. sendBuf[sendBufSize - 1] = GenCrc16ModbusHL(sendBuf, sendBufSize - 2, 0);
  256. UartSendBytes(sendBuf, sendBufSize);
  257. }
  258. #else
  259. uint16_t mbRegHoding[MODBUS_REG_HOLDING_SIZE] = {0x0000};
  260. /**
  261. * @brief modbus process
  262. * @note only make 03/06/10 function code, others will return err 01
  263. */
  264. void Modbus_Process(uint8_t* buf, uint8_t len)
  265. {
  266. uint8_t sendBuf[(MODBUS_REG_HOLDING_SIZE * 2) + 4] = {0x00};
  267. uint16_t sendBufSize = 4;
  268. if(len < 4) return; // check buf min size
  269. if(buf[0] != MODBUS_ADDR) return; // check addr
  270. if(CheckCrc16Modbus(buf, len)) return; // check crc
  271. sendBuf[0] = buf[0];
  272. sendBuf[1] = buf[1];
  273. switch(buf[1]) // check function code
  274. {
  275. // case MODBUS_FUNC_READ_COILS:{break; }
  276. // case MODBUS_FUNC_READ_DISCRETE_INPUTS:{break; }
  277. case MODBUS_FUNC_READ_HOLDING_REGISTERS:{
  278. uint16_t i = 0, startAddr = 0, regCount = 0;
  279. startAddr = (buf[2] << 8 + buf[3]);
  280. regCount = (buf[4] << 8 + buf[5]);
  281. if(startAddr + regCount - 1 >= MODBUS_REG_HOLDING_SIZE){
  282. sendBuf[1] = buf[1] + 0x80;
  283. sendBuf[2] = 0x02;
  284. sendBufSize = 6;
  285. break;
  286. }
  287. sendBuf[2] = regCount * 2;
  288. sendBufSize += 1;
  289. for(i = 0; i < regCount; i++){
  290. sendBuf[3 + (i * 2)] = mbRegHoding[startAddr + i] >> 8;
  291. sendBuf[3 + (i * 2) + 1] = mbRegHoding[startAddr + i];
  292. sendBufSize += 2;
  293. }
  294. break; }
  295. // case MODBUS_FUNC_READ_INPUT_REGISTERS:{break; }
  296. // case MODBUS_FUNC_WRITE_SINGLE_COIL:{break; }
  297. case MODBUS_FUNC_WRITE_SINGLE_HOLDING_REGISTERS:{
  298. uint16_t startAddr = 0, regValue = 0;
  299. startAddr = (buf[2] << 8 + buf[3]);
  300. regValue = (buf[4] << 8 + buf[5]);
  301. if(startAddr >= MODBUS_REG_HOLDING_SIZE){
  302. sendBuf[1] = buf[1] + 0x80;
  303. sendBuf[2] = 0x02;
  304. sendBufSize = 6;
  305. break;
  306. }
  307. mbRegHoding[startAddr] = regValue;
  308. sendBuf[2] = startAddr >> 8;
  309. sendBuf[3] = startAddr;
  310. sendBuf[4] = regValue >> 8;
  311. sendBuf[5] = regValue;
  312. sendBufSize += 4;
  313. break; }
  314. case MODBUS_FUNC_WRITE_MULTY_HOLDING_REGISTERS:{
  315. uint16_t i = 0, startAddr = 0, regCount = 0;
  316. startAddr = (buf[2] << 8 + buf[3]);
  317. regCount = (buf[4] << 8 + buf[5]);
  318. if(startAddr + regCount - 1 >= MODBUS_REG_HOLDING_SIZE){
  319. sendBuf[1] = buf[1] + 0x80;
  320. sendBuf[2] = 0x02;
  321. sendBufSize = 6;
  322. break;
  323. }
  324. for(i = 0; i < regCount; i++)
  325. mbRegHoding[startAddr + i] =
  326. (buf[7 + (i * 2)] << 8 + buf[8 + (i * 2)]);
  327. sendBuf[2] = startAddr >> 8;
  328. sendBuf[3] = startAddr;
  329. sendBuf[4] = regCount >> 8;
  330. sendBuf[5] = regCount;
  331. sendBufSize += 4;
  332. break; }
  333. default:{
  334. sendBuf[1] = buf[1] + 0x80;
  335. sendBuf[2] = 0x01;
  336. sendBufSize = 6;
  337. break;
  338. }
  339. }
  340. sendBuf[sendBufSize - 2] = GenCrc16ModbusHL(sendBuf, sendBufSize - 2, 0);
  341. sendBuf[sendBufSize - 1] = GenCrc16ModbusHL(sendBuf, sendBufSize - 2, 1);
  342. UartSendBytes(sendBuf, sendBufSize);
  343. }
  344. #endif /* MODBUS_FLOAT_MODE */
  345. #endif /* __MODBUS_LOW_ATY_C */
  346. /******************************** End Of File *********************************/