MODBUS_S_LOW_ATY.c 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  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 - 2025 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. * @param buf
  39. * @param len
  40. * @param dev
  41. * @return uint8_t
  42. * @note only make 03/06/10 function code, others will return err 01
  43. */
  44. uint8_t Modbus_Process(uint8_t* buf, uint8_t len, struct MODBUS_S_LOW_ATY_Dev* dev)
  45. {
  46. uint8_t sendBuf[(MODBUS_REG_HOLDING_SIZE * 2) + 4] = {0x00};
  47. uint16_t sendBufSize = 4;
  48. __ATY_LOCK(dev);
  49. sendBuf[0] = buf[0];
  50. sendBuf[1] = buf[1];
  51. if(buf[0] == dev->addr){ // check addr
  52. if(len < 4){ // check buf min size
  53. sendBuf[1] = buf[1] + 0x80;
  54. sendBuf[2] = 0x02;
  55. sendBufSize = 6;
  56. }
  57. else if(CheckCrc16Modbus(buf, len)){ // check crc
  58. sendBuf[1] = buf[1] + 0x80;
  59. sendBuf[2] = 0x08;
  60. sendBufSize = 6;
  61. }
  62. else{
  63. switch(buf[1]) // check function code
  64. {
  65. // case MODBUS_FUNC_READ_COILS:{break; }
  66. // case MODBUS_FUNC_READ_DISCRETE_INPUTS:{break; }
  67. case MODBUS_FUNC_READ_HOLDING_REGISTERS:{
  68. uint16_t i = 0, startAddr = 0, regCount = 0;
  69. startAddr = ((buf[2] << 8) + buf[3]);
  70. regCount = ((buf[4] << 8) + buf[5]);
  71. if(startAddr + regCount - 1 > MODBUS_REG_HOLDING_SIZE){
  72. sendBuf[1] = buf[1] + 0x80;
  73. sendBuf[2] = 0x02;
  74. sendBufSize = 6;
  75. break;
  76. }
  77. sendBuf[2] = regCount * 2;
  78. sendBufSize += 1;
  79. for(i = 0; i < regCount; i++){
  80. if(dev->bigEndian){
  81. sendBuf[2 + (i * 2) + 1] = dev->mbRegs[startAddr + i];
  82. sendBuf[2 + (i * 2) + 2] = dev->mbRegs[startAddr + i] >> 8;
  83. }
  84. else{
  85. sendBuf[2 + (i * 2) + 1] = dev->mbRegs[startAddr + i] >> 8;
  86. sendBuf[2 + (i * 2) + 2] = dev->mbRegs[startAddr + i];
  87. }
  88. sendBufSize += 2;
  89. }
  90. break;
  91. }
  92. // case MODBUS_FUNC_READ_INPUT_REGISTERS:{break; }
  93. // case MODBUS_FUNC_WRITE_SINGLE_COIL:{break; }
  94. case MODBUS_FUNC_WRITE_SINGLE_HOLDING_REGISTERS:{
  95. uint16_t startAddr = 0;
  96. startAddr = (((uint16_t)buf[2] << 8) + (uint16_t)buf[3]);
  97. if(startAddr >= MODBUS_REG_HOLDING_SIZE){
  98. sendBuf[1] = buf[1] + 0x80;
  99. sendBuf[2] = 0x02;
  100. sendBufSize = 6;
  101. break;
  102. }
  103. if(dev->bigEndian){
  104. dev->mbRegs[startAddr] = buf[4] + buf[5] << 8;
  105. }
  106. else{
  107. dev->mbRegs[startAddr] = buf[4] << 8 + buf[5];
  108. }
  109. sendBuf[2] = startAddr >> 8;
  110. sendBuf[3] = startAddr;
  111. if(dev->bigEndian){
  112. sendBuf[4] = dev->mbRegs[startAddr];
  113. sendBuf[5] = dev->mbRegs[startAddr] >> 8;
  114. }
  115. else{
  116. sendBuf[4] = dev->mbRegs[startAddr] >> 8;
  117. sendBuf[5] = dev->mbRegs[startAddr];
  118. }
  119. sendBufSize += 4;
  120. dev->setFlag = 1;
  121. break;
  122. }
  123. case MODBUS_FUNC_WRITE_MULTY_HOLDING_REGISTERS:{
  124. uint16_t i = 0, startAddr = 0, regCount = 0;
  125. startAddr = ((buf[2] << 8) + buf[3]);
  126. regCount = ((buf[4] << 8) + buf[5]);
  127. if(startAddr + regCount - 1 > MODBUS_REG_HOLDING_SIZE){
  128. sendBuf[1] = buf[1] + 0x80;
  129. sendBuf[2] = 0x02;
  130. sendBufSize = 6;
  131. break;
  132. }
  133. for(i = 0; i < regCount; i++)
  134. {
  135. if(dev->bigEndian){
  136. dev->mbRegs[startAddr + i] = (buf[6 + (i * 2) + 1]) + (buf[6 + (i * 2) + 2] << 8);
  137. }
  138. else{
  139. dev->mbRegs[startAddr + i] = (buf[6 + (i * 2) + 1] << 8) + (buf[6 + (i * 2) + 2]);
  140. }
  141. }
  142. sendBuf[2] = startAddr >> 8;
  143. sendBuf[3] = startAddr;
  144. sendBuf[4] = regCount >> 8;
  145. sendBuf[5] = regCount;
  146. sendBufSize += 4;
  147. dev->setFlag = 1;
  148. break;
  149. }
  150. default:{
  151. sendBuf[1] = buf[1] + 0x80;
  152. sendBuf[2] = 0x01;
  153. sendBufSize = 6;
  154. break;
  155. }
  156. }
  157. }
  158. sendBuf[sendBufSize - 2] = GenCrc16ModbusHL(sendBuf, sendBufSize - 2, 1);
  159. sendBuf[sendBufSize - 1] = GenCrc16ModbusHL(sendBuf, sendBufSize - 2, 0);
  160. dev->uartSendBytes(sendBuf, sendBufSize);
  161. }
  162. __ATY_UNLOCK(dev);
  163. return 0;
  164. }
  165. /**
  166. * @brief
  167. *
  168. * @param floatBuf
  169. * @param dev
  170. */
  171. void UpdateMbRegsFromFloat(float* floatBuf, struct MODBUS_S_LOW_ATY_Dev* dev)
  172. {
  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. dev->mbRegs[i * 2] = (mbFloatChange_u.u8_t[3] << 8) + mbFloatChange_u.u8_t[2];
  183. dev->mbRegs[(i * 2) + 1] = (mbFloatChange_u.u8_t[1] << 8) + mbFloatChange_u.u8_t[0];
  184. }
  185. }
  186. }
  187. /**
  188. * @brief
  189. *
  190. * @param floatBuf
  191. * @param dev
  192. */
  193. void TransMbRegsToFloat(float* floatBuf, struct MODBUS_S_LOW_ATY_Dev* dev)
  194. {
  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. mbFloatChange_u.u8_t[3] = (uint8_t)(dev->mbRegs[i * 2] >> 8);
  206. mbFloatChange_u.u8_t[2] = (uint8_t)(dev->mbRegs[i * 2]);
  207. mbFloatChange_u.u8_t[1] = (uint8_t)(dev->mbRegs[(i * 2) + 1] >> 8);
  208. mbFloatChange_u.u8_t[0] = (uint8_t)(dev->mbRegs[(i * 2) + 1]);
  209. }
  210. floatBuf[i] = mbFloatChange_u.f_t;
  211. }
  212. }
  213. #endif /* __MODBUS_S_LOW_ATY_C */
  214. /************************************ etc *************************************/
  215. /* init */
  216. // // mb
  217. // uint8_t MODBUS1_UART(uint8_t* buf, uint8_t len){
  218. // UartSendBytes(buf, len, &HW_UART_ATY_Dev_3);
  219. // return 0;
  220. // }
  221. // struct MODBUS_S_LOW_ATY_Dev MODBUS_S_LOW_ATY_Dev_1 = {
  222. // .addr = 0x01,
  223. // .size = MODBUS_REG_HOLDING_SIZE,
  224. // .mbRegs = {0},
  225. // .uartSendBytes = MODBUS1_UART,
  226. // .lock = _ATY_UNLOCKED,
  227. // .debugEnable = 0,
  228. // .LOG = printf
  229. // };
  230. /* use */
  231. // void UartReceiveProcess_User_3(void)
  232. // {
  233. // if((HW_UART_ATY_Dev_3.rx[0] == 'O'
  234. // && HW_UART_ATY_Dev_3.rx[1] == 'K'
  235. // && HW_UART_ATY_Dev_3.rx[2] == '?'))
  236. // UartSendStr("OK!", &HW_UART_ATY_Dev_3);
  237. // Modbus_Process(HW_UART_ATY_Dev_3.rx, HW_UART_ATY_Dev_3.rxCount, &MODBUS_S_LOW_ATY_Dev_1);
  238. // }
  239. // // 100ms cycle
  240. // {
  241. // UpdateMbRegsFromFloat(mbG, &MODBUS_S_LOW_ATY_Dev_1);
  242. // }
  243. /******************************************************************************/
  244. /******************************** End Of File *********************************/