You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

280 lines
11 KiB

2 years ago
  1. #include "modbus_processer.hpp"
  2. #include <stdbool.h>
  3. #include <stdint.h>
  4. /***********************485rx**************************/
  5. // ���յ��˶�������
  6. // volatile uint16_t s_modbus_uart_rx_off = 0;
  7. // ��ǰ�Ƿ����ڴ������յ�������
  8. // volatile bool s_modbus_uart_rx_buf_is_processing = false;
  9. /***********************485tx**************************/
  10. static modbus_processer_t* g_processer;
  11. #define GET_UINT16(uint8) (uint16_t)(((uint16_t)((uint8)[0]) << 8) + (uint8)[1])
  12. void modbus_processer_process_data(uint8_t* rx, uint16_t len);
  13. void modbus_processer_init(modbus_processer_t* processer) { g_processer = processer; }
  14. void ModbusProcessRxData(uint8_t* rxraw, uint8_t length, ModbusMasterData_t* rxparsed) {
  15. rxparsed->functionCode = (ModbusFunctionCode)rxraw[1];
  16. if (rxraw[1] == ModbusOrder01 || rxraw[1] == ModbusOrder02 || rxraw[1] == ModbusOrder03 || rxraw[1] == ModbusOrder04) {
  17. /**
  18. * @brief
  19. * ǹԾ001ֵ
  20. */
  21. rxparsed->d.O01.startbit = rxraw[2] * 256 + rxraw[3];
  22. rxparsed->d.O01.numbit = rxraw[4] * 256 + rxraw[5];
  23. } else if (rxraw[1] == ModbusOrder0F || rxraw[1] == ModbusOrder10) {
  24. /**
  25. * @brief
  26. * ǹԾ0Fֵ
  27. */
  28. rxparsed->d.O0F.startbit = rxraw[2] * 256 + rxraw[3];
  29. rxparsed->d.O0F.numbit = rxraw[4] * 256 + rxraw[5];
  30. rxparsed->d.O0F.bytenum = rxraw[6];
  31. rxparsed->d.O0F.bit = &rxraw[7];
  32. } else {
  33. /**
  34. * @brief Not support now
  35. */
  36. }
  37. }
  38. #define UINT16ToUINT8(u16d, u8addbegin) \
  39. { \
  40. (u8addbegin)[0] = u16d >> 8; \
  41. (u8addbegin)[1] = (uint8_t)u16d; \
  42. }
  43. void ModbusCreateTx_setReg(uint8_t* txbuffer, uint8_t length, uint16_t off, uint16_t regdata) {
  44. if (3 + off * 2 > length - 2) {
  45. return;
  46. }
  47. txbuffer[3 + off * 2] = regdata >> 8;
  48. txbuffer[3 + off * 2 + 1] = (uint8_t)regdata;
  49. }
  50. void ModbusCreateTxData(uint8_t* txbuffer, uint8_t length, uint16_t* sendlength, ModbusSlaveData_t* txdata) {
  51. /**
  52. * @brief TODO:txbufferȼ
  53. */
  54. if (length < 4) return;
  55. txbuffer[0] = txdata->deviceId;
  56. txbuffer[1] = (uint8_t)txdata->functionCode;
  57. *sendlength = 0;
  58. volatile uint16_t _sendlength = 0;
  59. volatile uint16_t i = 0;
  60. if (txdata->functionCode == ModbusOrder01 || txdata->functionCode == ModbusOrder02 || txdata->functionCode == ModbusOrder03 || txdata->functionCode == ModbusOrder04) {
  61. /**
  62. * @brief 01,02 ָbit
  63. */
  64. // ��ȡ��������״̬
  65. // sendLen =
  66. // add(1byte)+functionCode(1byte)+addNum(1)+crc(2) = 5+numbyte
  67. volatile uint16_t numbyte = txdata->d.O01.bytenum;
  68. _sendlength = 5 + numbyte;
  69. if (length < _sendlength) return;
  70. txbuffer[2] = txdata->d.O01.bytenum;
  71. if (txdata->d.O01.byte_table != nullptr) {
  72. for (i = 0; i < numbyte; i++) {
  73. txbuffer[3 + i] = txdata->d.O01.byte_table[i];
  74. }
  75. }
  76. } else if (txdata->functionCode == ModbusOrder0F || txdata->functionCode == ModbusOrder10) {
  77. // ���������
  78. // sendLen = add(1byte)+functionCode(1byte)+startAdd(2)+addNum(2)+crc(2) = 8
  79. _sendlength = 8;
  80. if (length < _sendlength) return;
  81. UINT16ToUINT8(txdata->d.O0F.startbit, &txbuffer[2]);
  82. UINT16ToUINT8(txdata->d.O0F.bitnum, &txbuffer[4]);
  83. } else {
  84. /**
  85. * @brief Not support now
  86. */
  87. }
  88. // calculate crc
  89. if (_sendlength > 2) {
  90. modbus_pack_crc_to_packet(txbuffer, _sendlength);
  91. }
  92. *sendlength = _sendlength;
  93. }
  94. void ModbusCreateExceptionData(uint8_t* txbuffer, uint8_t length, uint16_t* sendlength, uint8_t deviceid, uint8_t functioncode, ModbusStatus status) {
  95. /**
  96. * @brief TODO:txbufferȼ
  97. */
  98. volatile uint16_t _sendlength = 0;
  99. volatile uint16_t i = 0;
  100. if (length < 4) return;
  101. txbuffer[0] = deviceid;
  102. txbuffer[1] = functioncode | 0x80;
  103. txbuffer[2] = (uint8_t)status;
  104. *sendlength = 0;
  105. // sendLen = add(1byte)+functionCode(1byte)+exception(1)+crc(2) = 4
  106. _sendlength = 4;
  107. modbus_pack_crc_to_packet(txbuffer, _sendlength);
  108. *sendlength = _sendlength;
  109. return;
  110. }
  111. #if 0
  112. void modbus_processer_try_process_data(void) {
  113. /**
  114. * @brief
  115. * modbusЭ3.5ַʱȻûյ
  116. */
  117. // bool receive_one_packet = false; // ��Ϊkeil��������ע��
  118. if (s_modbus_uart_rx_off != 0) {
  119. uint16_t modbus_uart_rx_off_before = s_modbus_uart_rx_off;
  120. g_processer->port_delay_us(g_processer->modbus_baundrate_one_packet_delay_us);
  121. g_processer->port_enter_critical();
  122. if (s_modbus_uart_rx_off == modbus_uart_rx_off_before) {
  123. s_modbus_uart_rx_buf_is_processing = true;
  124. }
  125. g_processer->port_exit_critical();
  126. if (s_modbus_uart_rx_buf_is_processing) {
  127. modbus_processer_process_data(g_processer->modbus_processer_rx_buf, s_modbus_uart_rx_off);
  128. g_processer->port_enter_critical();
  129. s_modbus_uart_rx_off = 0;
  130. s_modbus_uart_rx_buf_is_processing = false;
  131. g_processer->port_exit_critical();
  132. }
  133. }
  134. }
  135. #endif
  136. /***********************************************************************************************************************
  137. * ==================================================modbusϢ=================================================== *
  138. ***********************************************************************************************************************/
  139. void modbus_processer_process_data(uint8_t* rx, uint16_t rxlen) {
  140. /**
  141. * @brief modbusԺд
  142. *
  143. */
  144. // �������ǹ㲥��Ϣ���߲��ǵ�ǰ�豸����Ϣ������
  145. if (rx[0] != 0 && rx[0] != g_processer->modbus_device_id) {
  146. return;
  147. }
  148. // CRCУ��ʧ��
  149. if (!modbus_checkcrc16(rx, rxlen)) {
  150. return;
  151. }
  152. // if(functioncode)
  153. static ModbusMasterData_t rxorder;
  154. static ModbusSlaveData_t txorder;
  155. // �����ܵ������ݽ�������
  156. ModbusProcessRxData(rx, rxlen, &rxorder);
  157. // static uint16_t txsendlen = 0; // ��Ϊkeil��������ע��
  158. txorder.deviceId = g_processer->modbus_device_id;
  159. // ������
  160. txorder.functionCode = rxorder.functionCode;
  161. modbus_processer_context_t context = {0};
  162. context.tx = &txorder;
  163. context.rx = &rxorder;
  164. g_processer->process_rx(&context);
  165. }
  166. /***********************************************************************************************************************
  167. * ======================================================Extern======================================================= *
  168. ***********************************************************************************************************************/
  169. ModbusFunctionCode modbus_get_function_code(modbus_processer_context_t* context) { //
  170. return context->tx->functionCode;
  171. }
  172. void modbus_set_tx_reg_03(modbus_processer_context_t* context, uint16_t regoff, uint16_t regdata) {
  173. uint16_t off = regoff - context->rx->d.O03.startreg;
  174. ModbusCreateTx_setReg(g_processer->modbus_processer_tx_buf, g_processer->modbus_processer_tx_buf_size, off, //
  175. regdata);
  176. }
  177. void modbus_set_tx_regs_03(modbus_processer_context_t* context, uint16_t regoff, uint16_t* regdata, int reglen) {
  178. for (int i = 0; i < reglen; i++) {
  179. modbus_set_tx_reg_03(context, regoff + i, regdata[i]);
  180. }
  181. }
  182. uint16_t modbus_get_reg_10(modbus_processer_context_t* context, uint16_t regoff) {
  183. uint16_t off = regoff - context->rx->d.O10.startreg;
  184. uint8_t* data = context->rx->d.O10.reg;
  185. if ((off + 1) * 2 <= context->rx->d.O10.bytenum) {
  186. uint16_t u16 = GET_UINT16(&data[off * 2]);
  187. return u16;
  188. } else {
  189. uint16_t u16 = data[off * 2];
  190. return u16;
  191. }
  192. }
  193. uint8_t* modbus_get_buf_10(modbus_processer_context_t* context, uint16_t regoff) {
  194. uint16_t off = regoff - context->rx->d.O10.startreg;
  195. uint8_t* data = context->rx->d.O10.reg;
  196. return &data[off * 2];
  197. }
  198. bool modbus_if_register_exists_03(modbus_processer_context_t* context, uint16_t regoff) {
  199. uint16_t startreg = context->rx->d.O03.startreg;
  200. uint16_t endreg = context->rx->d.O03.startreg + context->rx->d.O03.numreg;
  201. return regoff >= startreg && regoff < endreg;
  202. }
  203. bool modbus_if_registers_exists_03(modbus_processer_context_t* context, uint16_t regoff, uint16_t regnum) { return (modbus_if_register_exists_03(context, regoff) && modbus_if_register_exists_03(context, regoff + regnum - 1)); }
  204. bool modbus_if_register_exists_10(modbus_processer_context_t* context, uint16_t regoff) {
  205. uint16_t startreg = context->rx->d.O10.startreg;
  206. uint16_t endreg = context->rx->d.O10.startreg + context->rx->d.O10.numreg;
  207. return regoff >= startreg && regoff < endreg;
  208. }
  209. void modbus_send_03(modbus_processer_context_t* context, ModbusStatus modbus_status) {
  210. uint16_t sendlegth = 0;
  211. if (modbus_status == Modbus_OK) {
  212. /**
  213. * @brief
  214. */
  215. context->tx->functionCode = context->rx->functionCode;
  216. context->tx->deviceId = g_processer->modbus_device_id;
  217. context->tx->d.O03.bytenum = context->rx->d.O03.numreg * 2;
  218. context->tx->d.O03.reg = nullptr;
  219. // ������Ӧ��
  220. ModbusCreateTxData(g_processer->modbus_processer_tx_buf, g_processer->modbus_processer_tx_buf_size, &sendlegth, context->tx);
  221. // �������Ժ����͸�������
  222. g_processer->tx(g_processer->modbus_processer_tx_buf, sendlegth);
  223. } else {
  224. // LOGD("error");
  225. /**
  226. * @brief
  227. */
  228. // �����쳣����
  229. ModbusCreateExceptionData(g_processer->modbus_processer_tx_buf, //
  230. g_processer->modbus_processer_tx_buf_size, //
  231. &sendlegth, //
  232. g_processer->modbus_device_id, //
  233. context->rx->functionCode, //
  234. modbus_status);
  235. // �������ɷ���Ӧ��
  236. g_processer->tx(g_processer->modbus_processer_tx_buf, sendlegth);
  237. }
  238. }
  239. void modbus_send_10(modbus_processer_context_t* context, ModbusStatus modbus_status) {
  240. uint16_t sendlegth = 0;
  241. if (modbus_status == Modbus_OK) {
  242. context->tx->functionCode = context->rx->functionCode;
  243. context->tx->deviceId = g_processer->modbus_device_id;
  244. context->tx->d.O10.regnum = context->rx->d.O10.numreg;
  245. context->tx->d.O10.startreg = context->rx->d.O10.startreg;
  246. // ������ִ��������
  247. ModbusCreateTxData(g_processer->modbus_processer_tx_buf, g_processer->modbus_processer_tx_buf_size, &sendlegth, context->tx);
  248. g_processer->tx(g_processer->modbus_processer_tx_buf, sendlegth);
  249. } else {
  250. // �����쳣��������
  251. ModbusCreateExceptionData(g_processer->modbus_processer_tx_buf, //
  252. g_processer->modbus_processer_tx_buf_size, //
  253. &sendlegth, //
  254. g_processer->modbus_device_id, //
  255. context->rx->functionCode, //
  256. modbus_status);
  257. g_processer->tx(g_processer->modbus_processer_tx_buf, sendlegth);
  258. }
  259. }