MODBUS_S_LOW_ATY.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  1. /**
  2. * @file MODBUS_S_LOW_ATY.c
  3. *
  4. * @param Project DEVICE_GENERAL_ATY_LIB
  5. *
  6. * @author ATY
  7. *
  8. * @copyright
  9. * - Copyright 2017 - 2026 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 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. * - 1_02_240120 > ATY
  27. * -# add multy addr and channel
  28. * -# add lock
  29. * - 1_03_251121 > ATY
  30. * -# change output always big endian and test
  31. * @todo test in 51
  32. ********************************************************************************
  33. */
  34. #ifndef __MODBUS_S_LOW_ATY_C
  35. #define __MODBUS_S_LOW_ATY_C
  36. #include "MODBUS_S_LOW_ATY.h"
  37. /******************************* For user *************************************/
  38. /******************************************************************************/
  39. /**
  40. * @brief modbus process
  41. * @param buf
  42. * @param len
  43. * @param dev
  44. * @return uint8_t
  45. * @note only make 03/06/10 function code, others will return err 01
  46. */
  47. uint8_t Modbus_Process(uint8_t* buf, uint8_t len, struct MODBUS_S_LOW_ATY_Dev* dev){
  48. uint8_t sendBuf[(MODBUS_REG_HOLDING_SIZE * 2) + 4] = {0x00};
  49. uint16_t sendBufSize = 4;
  50. __ATY_LOCK(dev);
  51. sendBuf[0] = buf[0];
  52. sendBuf[1] = buf[1];
  53. if(buf[0] == dev->addr){ // check addr
  54. if(len < 4){ // check buf min size
  55. sendBuf[1] = buf[1] + 0x80;
  56. sendBuf[2] = 0x02;
  57. sendBufSize = 6;
  58. }
  59. else if(CheckCrc16Modbus(buf, len)){ // check crc
  60. sendBuf[1] = buf[1] + 0x80;
  61. sendBuf[2] = 0x08;
  62. sendBufSize = 6;
  63. }
  64. else{
  65. switch(buf[1]) // check function code
  66. {
  67. // case MODBUS_FUNC_READ_COILS:{break; }
  68. // case MODBUS_FUNC_READ_DISCRETE_INPUTS:{break; }
  69. case MODBUS_FUNC_READ_HOLDING_REGISTERS:{
  70. uint16_t i = 0, startAddr = 0, regCount = 0;
  71. startAddr = ((buf[2] << 8) + buf[3]);
  72. regCount = ((buf[4] << 8) + buf[5]);
  73. if(startAddr + regCount - 1 > MODBUS_REG_HOLDING_SIZE){
  74. sendBuf[1] = buf[1] + 0x80;
  75. sendBuf[2] = 0x02;
  76. sendBufSize = 6;
  77. break;
  78. }
  79. sendBuf[2] = regCount * 2;
  80. sendBufSize += 1;
  81. for(i = 0; i < regCount; i++){
  82. if(dev->bigEndian){
  83. sendBuf[2 + (i * 2) + 1] = dev->mbRegs[startAddr + i];
  84. sendBuf[2 + (i * 2) + 2] = dev->mbRegs[startAddr + i] >> 8;
  85. }
  86. else{
  87. sendBuf[2 + (i * 2) + 1] = dev->mbRegs[startAddr + i] >> 8;
  88. sendBuf[2 + (i * 2) + 2] = dev->mbRegs[startAddr + i];
  89. }
  90. sendBufSize += 2;
  91. }
  92. break;
  93. }
  94. // case MODBUS_FUNC_READ_INPUT_REGISTERS:{break; }
  95. // case MODBUS_FUNC_WRITE_SINGLE_COIL:{break; }
  96. case MODBUS_FUNC_WRITE_SINGLE_HOLDING_REGISTERS:{
  97. uint16_t startAddr = 0;
  98. startAddr = (((uint16_t)buf[2] << 8) + (uint16_t)buf[3]);
  99. if(startAddr >= MODBUS_REG_HOLDING_SIZE){
  100. sendBuf[1] = buf[1] + 0x80;
  101. sendBuf[2] = 0x02;
  102. sendBufSize = 6;
  103. break;
  104. }
  105. if(dev->bigEndian){
  106. dev->mbRegs[startAddr] = buf[4] + buf[5] << 8;
  107. }
  108. else{
  109. dev->mbRegs[startAddr] = buf[4] << 8 + buf[5];
  110. }
  111. sendBuf[2] = startAddr >> 8;
  112. sendBuf[3] = startAddr;
  113. if(dev->bigEndian){
  114. sendBuf[4] = dev->mbRegs[startAddr];
  115. sendBuf[5] = dev->mbRegs[startAddr] >> 8;
  116. }
  117. else{
  118. sendBuf[4] = dev->mbRegs[startAddr] >> 8;
  119. sendBuf[5] = dev->mbRegs[startAddr];
  120. }
  121. sendBufSize += 4;
  122. dev->setFlag = 1;
  123. break;
  124. }
  125. case MODBUS_FUNC_WRITE_MULTY_HOLDING_REGISTERS:{
  126. uint16_t i = 0, startAddr = 0, regCount = 0;
  127. startAddr = ((buf[2] << 8) + buf[3]);
  128. regCount = ((buf[4] << 8) + buf[5]);
  129. if(startAddr + regCount - 1 > MODBUS_REG_HOLDING_SIZE){
  130. sendBuf[1] = buf[1] + 0x80;
  131. sendBuf[2] = 0x02;
  132. sendBufSize = 6;
  133. break;
  134. }
  135. for(i = 0; i < regCount; i++){
  136. if(dev->bigEndian){
  137. dev->mbRegs[startAddr + i] = (buf[6 + (i * 2) + 1]) + (buf[6 + (i * 2) + 2] << 8);
  138. }
  139. else{
  140. dev->mbRegs[startAddr + i] = (buf[6 + (i * 2) + 1] << 8) + (buf[6 + (i * 2) + 2]);
  141. }
  142. }
  143. sendBuf[2] = startAddr >> 8;
  144. sendBuf[3] = startAddr;
  145. sendBuf[4] = regCount >> 8;
  146. sendBuf[5] = regCount;
  147. sendBufSize += 4;
  148. dev->setFlag = 1;
  149. break;
  150. }
  151. default:{
  152. sendBuf[1] = buf[1] + 0x80;
  153. sendBuf[2] = 0x01;
  154. sendBufSize = 6;
  155. break;
  156. }
  157. }
  158. }
  159. sendBuf[sendBufSize - 2] = GenCrc16ModbusHL(sendBuf, sendBufSize - 2, 0);
  160. sendBuf[sendBufSize - 1] = GenCrc16ModbusHL(sendBuf, sendBufSize - 2, 1);
  161. dev->uartSendBytes(sendBuf, sendBufSize);
  162. }
  163. __ATY_UNLOCK(dev);
  164. return 0;
  165. }
  166. /**
  167. * @brief
  168. *
  169. * @param floatBuf
  170. * @param dev
  171. */
  172. void UpdateMbRegsFromFloat(float* floatBuf, struct MODBUS_S_LOW_ATY_Dev* dev){
  173. union mbFloatChange mbFloatChange_u = {0};
  174. uint8_t i = 0;
  175. for(i = 0; i < (uint8_t)(MODBUS_REG_HOLDING_SIZE / 2); i++){
  176. mbFloatChange_u.f_t = floatBuf[i];
  177. // if(dev->bigEndian){
  178. // dev->mbRegs[i * 2] = (mbFloatChange_u.u8_t[0] << 8) + mbFloatChange_u.u8_t[1];
  179. // dev->mbRegs[(i * 2) + 1] = (mbFloatChange_u.u8_t[2] << 8) + mbFloatChange_u.u8_t[3];
  180. // }
  181. // else
  182. {
  183. dev->mbRegs[i * 2] = (mbFloatChange_u.u8_t[3] << 8) + mbFloatChange_u.u8_t[2];
  184. dev->mbRegs[(i * 2) + 1] = (mbFloatChange_u.u8_t[1] << 8) + mbFloatChange_u.u8_t[0];
  185. }
  186. }
  187. }
  188. /**
  189. * @brief
  190. *
  191. * @param floatBuf
  192. * @param dev
  193. */
  194. void TransMbRegsToFloat(float* floatBuf, struct MODBUS_S_LOW_ATY_Dev* dev){
  195. union mbFloatChange mbFloatChange_u = {0};
  196. uint8_t i = 0;
  197. for(i = 0; i < (uint8_t)(MODBUS_REG_HOLDING_SIZE / 2); i++){
  198. // if(dev->bigEndian){
  199. // mbFloatChange_u.u8_t[0] = (uint8_t)(dev->mbRegs[i * 2] >> 8);
  200. // mbFloatChange_u.u8_t[1] = (uint8_t)(dev->mbRegs[i * 2]);
  201. // mbFloatChange_u.u8_t[2] = (uint8_t)(dev->mbRegs[(i * 2) + 1] >> 8);
  202. // mbFloatChange_u.u8_t[3] = (uint8_t)(dev->mbRegs[(i * 2) + 1]);
  203. // }
  204. // else
  205. {
  206. mbFloatChange_u.u8_t[3] = (uint8_t)(dev->mbRegs[i * 2] >> 8);
  207. mbFloatChange_u.u8_t[2] = (uint8_t)(dev->mbRegs[i * 2]);
  208. mbFloatChange_u.u8_t[1] = (uint8_t)(dev->mbRegs[(i * 2) + 1] >> 8);
  209. mbFloatChange_u.u8_t[0] = (uint8_t)(dev->mbRegs[(i * 2) + 1]);
  210. }
  211. floatBuf[i] = mbFloatChange_u.f_t;
  212. }
  213. }
  214. #endif /* __MODBUS_S_LOW_ATY_C */
  215. /************************************ etc *************************************/
  216. /* init */
  217. // Modbus ----------------------------------------------------------------------
  218. // #include "MODBUS_S_LOW_ATY.h"
  219. // float mbG[MODBUS_REG_HOLDING_SIZE / 2] = {0};
  220. // uint8_t MODBUS1_UART(uint8_t* buf, uint8_t len){
  221. // UartSendBytes(buf, len, &HW_UART_ATY_Dev_1);
  222. // return 0;
  223. // }
  224. // struct MODBUS_S_LOW_ATY_Dev MODBUS_S_LOW_ATY_Dev_1 = {
  225. // .addr = 0x01,
  226. // .mbRegs = {0},
  227. // .uartSendBytes = MODBUS1_UART,
  228. // .bigEndian = 0,
  229. // .lock = __ATY_UNLOCKED
  230. // };
  231. /* use */
  232. // void UartReceiveProcess_User_1(void){
  233. // if(HW_UART_ATY_Dev_1.rx[0] == 'O'
  234. // && HW_UART_ATY_Dev_1.rx[1] == 'K'
  235. // && HW_UART_ATY_Dev_1.rx[2] == '?')
  236. // printf_ATY("OK!");
  237. // if(HW_UART_ATY_Dev_1.rxCount != 0){
  238. // Modbus_Process(HW_UART_ATY_Dev_1.rx, HW_UART_ATY_Dev_1.rxCount, &MODBUS_S_LOW_ATY_Dev_1);
  239. // if(MODBUS_S_LOW_ATY_Dev_1.setFlag == 1){
  240. // MODBUS_S_LOW_ATY_Dev_1.setFlag = 0;
  241. // TransMbRegsToFloat(mbG, &MODBUS_S_LOW_ATY_Dev_1);
  242. // }
  243. // // simulate data change
  244. // for(uint8_t i = 0; i < MODBUS_REG_HOLDING_SIZE / 2; i++){
  245. // if(mbG[i] < 100.0)
  246. // mbG[i] += (0.01 * (float)(i + 1));
  247. // else if(mbG[i] >= 100.0 && mbG[i] < 200.0)
  248. // mbG[i] = i;
  249. // // else test write save if mbG[i] > 200.0, data stop auto change
  250. // }
  251. // }
  252. // }
  253. // // 100ms cycle
  254. // {
  255. // UpdateMbRegsFromFloat(mbG, &MODBUS_S_LOW_ATY_Dev_1);
  256. // }
  257. /******************************************************************************/
  258. /******************************** End Of File *********************************/