MODBUS_LOW_ATY.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331
  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 snedBufSize = 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. snedBufSize = 6;
  155. break;
  156. }
  157. sendBuf[2] = regCount * 4;
  158. snedBufSize += 1;
  159. for(i = 0; i < regCount; i++){
  160. mbFloatChange_u.f_t = mbRegHoding[startAddr + i];
  161. sendBuf[2 + (i * 4) + 1] = mbFloatChange_u.u8_t[0];
  162. sendBuf[2 + (i * 4) + 2] = mbFloatChange_u.u8_t[1];
  163. sendBuf[2 + (i * 4) + 3] = mbFloatChange_u.u8_t[2];
  164. sendBuf[2 + (i * 4) + 4] = mbFloatChange_u.u8_t[3];
  165. snedBufSize += 4;
  166. }
  167. break; }
  168. // case MODBUS_FUNC_READ_INPUT_REGISTERS:{break; }
  169. // case MODBUS_FUNC_WRITE_SINGLE_COIL:{break; }
  170. case MODBUS_FUNC_WRITE_SINGLE_HOLDING_REGISTERS:{
  171. uint16_t startAddr = 0;
  172. float regValue = 0.0;
  173. startAddr = (((uint16_t)buf[2] << 8) + (uint16_t)buf[3]);
  174. if(startAddr >= MODBUS_REG_HOLDING_SIZE){
  175. sendBuf[1] = buf[1] + 0x80;
  176. sendBuf[2] = 0x02;
  177. snedBufSize = 6;
  178. break;
  179. }
  180. mbFloatChange_u.u8_t[0] = buf[4];
  181. mbFloatChange_u.u8_t[1] = buf[5];
  182. mbFloatChange_u.u8_t[2] = buf[6];
  183. mbFloatChange_u.u8_t[3] = buf[7];
  184. regValue = mbFloatChange_u.f_t;
  185. mbRegHoding[startAddr] = regValue;
  186. sendBuf[2] = startAddr >> 8;
  187. sendBuf[3] = startAddr;
  188. sendBuf[4] = mbFloatChange_u.u8_t[0];
  189. sendBuf[5] = mbFloatChange_u.u8_t[1];
  190. sendBuf[6] = mbFloatChange_u.u8_t[2];
  191. sendBuf[7] = mbFloatChange_u.u8_t[3];
  192. snedBufSize += 6;
  193. break; }
  194. case MODBUS_FUNC_WRITE_MULTY_HOLDING_REGISTERS:{
  195. uint16_t i = 0, startAddr = 0, regCount = 0;
  196. startAddr = ((buf[2] << 8) + buf[3]);
  197. regCount = ((buf[4] << 8) + buf[5]);
  198. if(startAddr + regCount - 1 > MODBUS_REG_HOLDING_SIZE){
  199. sendBuf[1] = buf[1] + 0x80;
  200. sendBuf[2] = 0x02;
  201. snedBufSize = 6;
  202. break;
  203. }
  204. for(i = 0; i < regCount; i++)
  205. {
  206. float regValue = 0.0;
  207. mbFloatChange_u.u8_t[0] = buf[6 + (i * 4) + 1];
  208. mbFloatChange_u.u8_t[1] = buf[6 + (i * 4) + 2];
  209. mbFloatChange_u.u8_t[2] = buf[6 + (i * 4) + 3];
  210. mbFloatChange_u.u8_t[3] = buf[6 + (i * 4) + 4];
  211. regValue = mbFloatChange_u.f_t;
  212. mbRegHoding[startAddr + i] = regValue;
  213. }
  214. sendBuf[2] = startAddr >> 8;
  215. sendBuf[3] = startAddr;
  216. sendBuf[4] = regCount >> 8;
  217. sendBuf[5] = regCount;
  218. snedBufSize += 4;
  219. break; }
  220. default:{
  221. sendBuf[1] = buf[1] + 0x80;
  222. sendBuf[2] = 0x01;
  223. snedBufSize = 6;
  224. break; }
  225. }
  226. sendBuf[snedBufSize - 2] = GenCrc16ModbusHL(sendBuf, snedBufSize - 2, 1);
  227. sendBuf[snedBufSize - 1] = GenCrc16ModbusHL(sendBuf, snedBufSize - 2, 0);
  228. UartSendBytes(sendBuf, snedBufSize);
  229. }
  230. #else
  231. uint16_t mbRegHoding[MODBUS_REG_HOLDING_SIZE] = {0x0000};
  232. /**
  233. * @brief modbus process
  234. * @note only make 03/06/10 function code, others will return err 01
  235. */
  236. void Modbus_Process(uint8_t* buf, uint8_t len)
  237. {
  238. uint8_t sendBuf[(MODBUS_REG_HOLDING_SIZE * 2) + 4] = {0x00};
  239. uint16_t snedBufSize = 4;
  240. if(len < 4) return; // check buf min size
  241. if(buf[0] != MODBUS_ADDR) return; // check addr
  242. if(CheckCrc16Modbus(buf, len)) return; // check crc
  243. sendBuf[0] = buf[0];
  244. sendBuf[1] = buf[1];
  245. switch(buf[1]) // check function code
  246. {
  247. // case MODBUS_FUNC_READ_COILS:{break; }
  248. // case MODBUS_FUNC_READ_DISCRETE_INPUTS:{break; }
  249. case MODBUS_FUNC_READ_HOLDING_REGISTERS:{
  250. uint16_t i = 0, startAddr = 0, regCount = 0;
  251. startAddr = (buf[2] << 8 + buf[3]);
  252. regCount = (buf[4] << 8 + buf[5]);
  253. if(startAddr + regCount - 1 >= MODBUS_REG_HOLDING_SIZE){
  254. sendBuf[1] = buf[1] + 0x80;
  255. sendBuf[2] = 0x02;
  256. snedBufSize = 6;
  257. break;
  258. }
  259. sendBuf[2] = regCount * 2;
  260. snedBufSize += 1;
  261. for(i = 0; i < regCount; i++){
  262. sendBuf[3 + (i * 2)] = mbRegHoding[startAddr + i] >> 8;
  263. sendBuf[3 + (i * 2) + 1] = mbRegHoding[startAddr + i];
  264. snedBufSize += 2;
  265. }
  266. break; }
  267. // case MODBUS_FUNC_READ_INPUT_REGISTERS:{break; }
  268. // case MODBUS_FUNC_WRITE_SINGLE_COIL:{break; }
  269. case MODBUS_FUNC_WRITE_SINGLE_HOLDING_REGISTERS:{
  270. uint16_t startAddr = 0, regValue = 0;
  271. startAddr = (buf[2] << 8 + buf[3]);
  272. regValue = (buf[4] << 8 + buf[5]);
  273. if(startAddr >= MODBUS_REG_HOLDING_SIZE){
  274. sendBuf[1] = buf[1] + 0x80;
  275. sendBuf[2] = 0x02;
  276. snedBufSize = 6;
  277. break;
  278. }
  279. mbRegHoding[startAddr] = regValue;
  280. sendBuf[2] = startAddr >> 8;
  281. sendBuf[3] = startAddr;
  282. sendBuf[4] = regValue >> 8;
  283. sendBuf[5] = regValue;
  284. snedBufSize += 4;
  285. break; }
  286. case MODBUS_FUNC_WRITE_MULTY_HOLDING_REGISTERS:{
  287. uint16_t i = 0, startAddr = 0, regCount = 0;
  288. startAddr = (buf[2] << 8 + buf[3]);
  289. regCount = (buf[4] << 8 + buf[5]);
  290. if(startAddr + regCount - 1 >= MODBUS_REG_HOLDING_SIZE){
  291. sendBuf[1] = buf[1] + 0x80;
  292. sendBuf[2] = 0x02;
  293. snedBufSize = 6;
  294. break;
  295. }
  296. for(i = 0; i < regCount; i++)
  297. mbRegHoding[startAddr + i] =
  298. (buf[7 + (i * 2)] << 8 + buf[8 + (i * 2)]);
  299. sendBuf[2] = startAddr >> 8;
  300. sendBuf[3] = startAddr;
  301. sendBuf[4] = regCount >> 8;
  302. sendBuf[5] = regCount;
  303. snedBufSize += 4;
  304. break; }
  305. default:{
  306. sendBuf[1] = buf[1] + 0x80;
  307. sendBuf[2] = 0x01;
  308. snedBufSize = 6;
  309. break;
  310. }
  311. }
  312. sendBuf[snedBufSize - 2] = GenCrc16ModbusHL(sendBuf, snedBufSize - 2, 0);
  313. sendBuf[snedBufSize - 1] = GenCrc16ModbusHL(sendBuf, snedBufSize - 2, 1);
  314. UartSendBytes(sendBuf, snedBufSize);
  315. }
  316. #endif /* MODBUS_FLOAT_MODE */
  317. #endif /* __MODBUS_LOW_ATY_C */
  318. /******************************** End Of File *********************************/