MODBUS_S_LOW_ATY.c 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  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 - 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. * - 1_02_240120 > ATY
  27. * -# add multy addr and channel
  28. * -# add lock
  29. ********************************************************************************
  30. */
  31. #ifndef __MODBUS_S_LOW_ATY_C
  32. #define __MODBUS_S_LOW_ATY_C
  33. #include "MODBUS_S_LOW_ATY.h"
  34. /******************************* For user *************************************/
  35. /******************************************************************************/
  36. /**
  37. * @brief modbus process
  38. *
  39. * @param buf
  40. * @param len
  41. * @param dev
  42. * @return uint8_t
  43. * @note only make 03/06/10 function code, others will return err 01
  44. */
  45. uint8_t Modbus_Process(uint8_t* buf, uint8_t len, struct MODBUS_S_LOW_ATY_Dev* dev)
  46. {
  47. uint8_t sendBuf[(MODBUS_REG_HOLDING_SIZE * 2) + 4] = {0x00};
  48. uint16_t sendBufSize = 4;
  49. __ATY_LOCK(dev);
  50. sendBuf[0] = buf[0];
  51. sendBuf[1] = buf[1];
  52. if(buf[0] == dev->addr){ // check addr
  53. if(len < 4){ // check buf min size
  54. sendBuf[1] = buf[1] + 0x80;
  55. sendBuf[2] = 0x02;
  56. sendBufSize = 6;
  57. }
  58. else if(CheckCrc16Modbus(buf, len)){ // check crc
  59. sendBuf[1] = buf[1] + 0x80;
  60. sendBuf[2] = 0x08;
  61. sendBufSize = 6;
  62. }
  63. else{
  64. switch(buf[1]) // check function code
  65. {
  66. // case MODBUS_FUNC_READ_COILS:{break; }
  67. // case MODBUS_FUNC_READ_DISCRETE_INPUTS:{break; }
  68. case MODBUS_FUNC_READ_HOLDING_REGISTERS:{
  69. uint16_t i = 0, startAddr = 0, regCount = 0;
  70. startAddr = ((buf[2] << 8) + buf[3]);
  71. regCount = ((buf[4] << 8) + buf[5]);
  72. if(startAddr + regCount - 1 > MODBUS_REG_HOLDING_SIZE){
  73. sendBuf[1] = buf[1] + 0x80;
  74. sendBuf[2] = 0x02;
  75. sendBufSize = 6;
  76. break;
  77. }
  78. sendBuf[2] = regCount * 2;
  79. sendBufSize += 1;
  80. for(i = 0; i < regCount; i++){
  81. if(dev->bigEndian){
  82. sendBuf[2 + (i * 2) + 1] = dev->mbRegs[startAddr + i];
  83. sendBuf[2 + (i * 2) + 2] = dev->mbRegs[startAddr + i] >> 8;
  84. }
  85. else{
  86. sendBuf[2 + (i * 2) + 1] = dev->mbRegs[startAddr + i] >> 8;
  87. sendBuf[2 + (i * 2) + 2] = dev->mbRegs[startAddr + i];
  88. }
  89. sendBufSize += 2;
  90. }
  91. break;
  92. }
  93. // case MODBUS_FUNC_READ_INPUT_REGISTERS:{break; }
  94. // case MODBUS_FUNC_WRITE_SINGLE_COIL:{break; }
  95. case MODBUS_FUNC_WRITE_SINGLE_HOLDING_REGISTERS:{
  96. uint16_t startAddr = 0;
  97. startAddr = (((uint16_t)buf[2] << 8) + (uint16_t)buf[3]);
  98. if(startAddr >= MODBUS_REG_HOLDING_SIZE){
  99. sendBuf[1] = buf[1] + 0x80;
  100. sendBuf[2] = 0x02;
  101. sendBufSize = 6;
  102. break;
  103. }
  104. if(dev->bigEndian){
  105. dev->mbRegs[startAddr] = buf[4] + buf[5] << 8;
  106. }
  107. else{
  108. dev->mbRegs[startAddr] = buf[4] << 8 + buf[5];
  109. }
  110. sendBuf[2] = startAddr >> 8;
  111. sendBuf[3] = startAddr;
  112. if(dev->bigEndian){
  113. sendBuf[4] = dev->mbRegs[startAddr];
  114. sendBuf[5] = dev->mbRegs[startAddr] >> 8;
  115. }
  116. else{
  117. sendBuf[4] = dev->mbRegs[startAddr] >> 8;
  118. sendBuf[5] = dev->mbRegs[startAddr];
  119. }
  120. sendBufSize += 4;
  121. dev->setFlag = 1;
  122. break;
  123. }
  124. case MODBUS_FUNC_WRITE_MULTY_HOLDING_REGISTERS:{
  125. uint16_t i = 0, startAddr = 0, regCount = 0;
  126. startAddr = ((buf[2] << 8) + buf[3]);
  127. regCount = ((buf[4] << 8) + buf[5]);
  128. if(startAddr + regCount - 1 > MODBUS_REG_HOLDING_SIZE){
  129. sendBuf[1] = buf[1] + 0x80;
  130. sendBuf[2] = 0x02;
  131. sendBufSize = 6;
  132. break;
  133. }
  134. for(i = 0; i < regCount; i++)
  135. {
  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, 1);
  160. sendBuf[sendBufSize - 1] = GenCrc16ModbusHL(sendBuf, sendBufSize - 2, 0);
  161. dev->uartSendBytes(sendBuf, sendBufSize);
  162. }
  163. __ATY_UNLOCK(dev);
  164. return 0;
  165. }
  166. #endif /* __MODBUS_S_LOW_ATY_C */
  167. /******************************** End Of File *********************************/