MODBUS_LOW_ATY.c 14 KB

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