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.

156 lines
6.1 KiB

  1. #include "modbus_processer.h"
  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. static void modbus_processer_process_data(uint8_t* rx, uint16_t rxlen) {
  13. /**
  14. * @brief modbus接收完成以后在这里进行处理数据
  15. *
  16. */
  17. //如果不是广播信息或者不是当前设备的信息,丢弃
  18. if (rx[0] != 0 && rx[0] != g_processer->modbus_device_id) {
  19. return;
  20. }
  21. // CRC校验失败
  22. if (!ZCheckRTUMessageIntegrity(rx, rxlen)) {
  23. return;
  24. }
  25. // if(functioncode)
  26. static ModbusMasterData_t rxorder;
  27. static ModbusSlaveData_t txorder;
  28. //将接受到的数据进行组包
  29. ModbusProcessRxData(rx, rxlen, &rxorder);
  30. static uint16_t txsendlen = 0;
  31. txorder.deviceId = g_processer->modbus_device_id;
  32. //功能码
  33. txorder.functionCode = rxorder.functionCode;
  34. modbus_processer_context_t context = {0};
  35. context.tx = &txorder;
  36. context.rx = &rxorder;
  37. g_processer->process_rx(&context);
  38. }
  39. void modbus_processer_init(modbus_processer_t* processer) { g_processer = processer; }
  40. void modbus_processer_push_data(uint8_t rxdata) {
  41. if (!s_modbus_uart_rx_buf_is_processing) {
  42. if (s_modbus_uart_rx_off < g_processer->modbus_processer_rx_buf_size) {
  43. g_processer->modbus_processer_rx_buf[s_modbus_uart_rx_off] = rxdata;
  44. s_modbus_uart_rx_off++;
  45. }
  46. }
  47. }
  48. ModbusFunctionCode modbus_get_function_code(modbus_processer_context_t* context) { //
  49. return context->tx->functionCode;
  50. }
  51. void modbus_set_tx_reg_03(modbus_processer_context_t* context, uint16_t regoff, uint16_t regdata) {
  52. uint16_t off = regoff - context->rx->d.O03.startreg;
  53. ModbusCreateTx_setReg(g_processer->modbus_processer_tx_buf, g_processer->modbus_processer_tx_buf_size, off, //
  54. regdata);
  55. }
  56. uint16_t modbus_get_reg_10(modbus_processer_context_t* context, uint16_t regoff) {
  57. uint16_t off = regoff - context->rx->d.O10.startreg;
  58. uint8_t* data = context->rx->d.O10.reg;
  59. if ((off + 1) * 2 <= context->rx->d.O10.bytenum) {
  60. uint16_t u16 = GET_UINT16(&data[off * 2]);
  61. return u16;
  62. } else {
  63. uint16_t u16 = data[off * 2];
  64. return u16;
  65. }
  66. }
  67. bool modbus_if_register_exists_03(modbus_processer_context_t* context, uint16_t regoff) {
  68. uint16_t startreg = context->rx->d.O03.startreg;
  69. uint16_t endreg = context->rx->d.O03.startreg + context->rx->d.O03.numreg;
  70. return regoff >= startreg && regoff < endreg;
  71. }
  72. bool modbus_if_register_exists_10(modbus_processer_context_t* context, uint16_t regoff) {
  73. uint16_t startreg = context->rx->d.O10.startreg;
  74. uint16_t endreg = context->rx->d.O10.startreg + context->rx->d.O10.numreg;
  75. return regoff >= startreg && regoff < endreg;
  76. }
  77. void modbus_send_03(modbus_processer_context_t* context, ModbusStatus modbus_status) {
  78. uint16_t sendlegth = 0;
  79. if (modbus_status == Modbus_OK) {
  80. context->tx->functionCode = context->rx->functionCode;
  81. context->tx->deviceId = g_processer->modbus_device_id;
  82. context->tx->d.O10.regnum = context->rx->d.O10.numreg;
  83. context->tx->d.O10.startreg = context->rx->d.O10.startreg;
  84. //构造回执,并发送
  85. ModbusCreateTxData(g_processer->modbus_processer_tx_buf, g_processer->modbus_processer_tx_buf_size, &sendlegth, context->tx);
  86. g_processer->tx(g_processer->modbus_processer_tx_buf, sendlegth);
  87. } else {
  88. //构造异常包并发送
  89. ModbusCreateExceptionData(g_processer->modbus_processer_tx_buf, //
  90. g_processer->modbus_processer_tx_buf_size, //
  91. &sendlegth, //
  92. g_processer->modbus_device_id, //
  93. context->rx->functionCode, //
  94. modbus_status);
  95. g_processer->tx(g_processer->modbus_processer_tx_buf, sendlegth);
  96. }
  97. }
  98. void modbus_send_10(modbus_processer_context_t* context, ModbusStatus modbus_status) {
  99. uint16_t sendlegth = 0;
  100. if (modbus_status == Modbus_OK) {
  101. context->tx->functionCode = context->rx->functionCode;
  102. context->tx->deviceId = g_processer->modbus_device_id;
  103. context->tx->d.O10.regnum = context->rx->d.O10.numreg;
  104. context->tx->d.O10.startreg = context->rx->d.O10.startreg;
  105. //构造回执,并发送
  106. ModbusCreateTxData(g_processer->modbus_processer_tx_buf, g_processer->modbus_processer_tx_buf_size, &sendlegth, context->tx);
  107. g_processer->tx(g_processer->modbus_processer_tx_buf, sendlegth);
  108. } else {
  109. //构造异常包并发送
  110. ModbusCreateExceptionData(g_processer->modbus_processer_tx_buf, //
  111. g_processer->modbus_processer_tx_buf_size, //
  112. &sendlegth, //
  113. g_processer->modbus_device_id, //
  114. context->rx->functionCode, //
  115. modbus_status);
  116. g_processer->tx(g_processer->modbus_processer_tx_buf, sendlegth);
  117. }
  118. }
  119. void modbus_processer_try_process_data() {
  120. /**
  121. * @brief
  122. * modbus协议3.5
  123. */
  124. if (s_modbus_uart_rx_off != 0) {
  125. uint16_t modbus_uart_rx_off_before = s_modbus_uart_rx_off;
  126. g_processer->port_delay_us(g_processer->modbus_baundrate_one_packet_delay_us);
  127. g_processer->port_enter_critical();
  128. if (s_modbus_uart_rx_off == modbus_uart_rx_off_before) {
  129. s_modbus_uart_rx_buf_is_processing = true;
  130. }
  131. g_processer->port_exit_critical();
  132. if (s_modbus_uart_rx_buf_is_processing) {
  133. modbus_processer_process_data(g_processer->modbus_processer_rx_buf, s_modbus_uart_rx_off);
  134. g_processer->port_enter_critical();
  135. s_modbus_uart_rx_off = 0;
  136. s_modbus_uart_rx_buf_is_processing = false;
  137. g_processer->port_exit_critical();
  138. }
  139. }
  140. }