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.

109 lines
3.5 KiB

  1. #include "zmodbus_slave.h"
  2. #define UINT16ToUINT8(u16d, u8addbegin) \
  3. { \
  4. (u8addbegin)[0] = u16d >> 8; \
  5. (u8addbegin)[1] = (uint8_t)u16d; \
  6. }
  7. void ModbusProcessRxData(uint8_t *rxraw, uint8_t length, ModbusMasterData_t *rxparsed) {
  8. rxparsed->functionCode = (ModbusFunctionCode)rxraw[1];
  9. if (rxraw[1] == ModbusOrder01 || rxraw[1] == ModbusOrder02 || rxraw[1] == ModbusOrder03 ||
  10. rxraw[1] == ModbusOrder04) {
  11. /**
  12. * @brief
  13. * 001
  14. */
  15. rxparsed->d.O01.startbit = rxraw[2] * 256 + rxraw[3];
  16. rxparsed->d.O01.numbit = rxraw[4] * 256 + rxraw[5];
  17. } else if (rxraw[1] == ModbusOrder0F || rxraw[1] == ModbusOrder10) {
  18. /**
  19. * @brief
  20. * 0F
  21. */
  22. rxparsed->d.O0F.startbit = rxraw[2] * 256 + rxraw[3];
  23. rxparsed->d.O0F.numbit = rxraw[4] * 256 + rxraw[5];
  24. rxparsed->d.O0F.bytenum = rxraw[6];
  25. rxparsed->d.O0F.bit = &rxraw[7];
  26. } else {
  27. /**
  28. * @brief Not support now
  29. */
  30. }
  31. }
  32. void ModbusCreateTx_setReg(uint8_t *txbuffer, uint8_t length, uint16_t off, uint16_t regdata) {
  33. if (3 + off * 2 > length - 2) {
  34. return;
  35. }
  36. txbuffer[3 + off * 2] = regdata >> 8;
  37. txbuffer[3 + off * 2 + 1] = (uint8_t)regdata;
  38. }
  39. void ModbusCreateTxData(uint8_t *txbuffer, uint8_t length, uint16_t *sendlength, ModbusSlaveData_t *txdata) {
  40. /**
  41. * @brief TODO:txbuffer长度计算
  42. */
  43. if (length < 4) return;
  44. txbuffer[0] = txdata->deviceId;
  45. txbuffer[1] = (uint8_t)txdata->functionCode;
  46. *sendlength = 0;
  47. volatile uint16_t _sendlength = 0;
  48. volatile uint16_t i = 0;
  49. if (txdata->functionCode == ModbusOrder01 || txdata->functionCode == ModbusOrder02 ||
  50. txdata->functionCode == ModbusOrder03 || txdata->functionCode == ModbusOrder04) {
  51. /**
  52. * @brief 01,02 bit
  53. */
  54. //读取多个输出状态
  55. // sendLen =
  56. // add(1byte)+functionCode(1byte)+addNum(1)+crc(2) = 5+numbyte
  57. volatile uint16_t numbyte = txdata->d.O01.bytenum;
  58. _sendlength = 5 + numbyte;
  59. if (length < _sendlength) return;
  60. txbuffer[2] = txdata->d.O01.bytenum;
  61. if (txdata->d.O01.byte_table != NULL) {
  62. for (i = 0; i < numbyte; i++) {
  63. txbuffer[3 + i] = txdata->d.O01.byte_table[i];
  64. }
  65. }
  66. } else if (txdata->functionCode == ModbusOrder0F || txdata->functionCode == ModbusOrder10) {
  67. //写入多个输出
  68. // sendLen = add(1byte)+functionCode(1byte)+startAdd(2)+addNum(2)+crc(2) = 8
  69. _sendlength = 8;
  70. if (length < _sendlength) return;
  71. UINT16ToUINT8(txdata->d.O0F.startbit, &txbuffer[2]);
  72. UINT16ToUINT8(txdata->d.O0F.bitnum, &txbuffer[4]);
  73. } else {
  74. /**
  75. * @brief Not support now
  76. */
  77. }
  78. // calculate crc
  79. if (_sendlength > 2) {
  80. ZGenerateCRC16CheckCodeToPacket(txbuffer, _sendlength);
  81. }
  82. *sendlength = _sendlength;
  83. }
  84. void ModbusCreateExceptionData(uint8_t *txbuffer, uint8_t length, uint16_t *sendlength, uint8_t deviceid,
  85. uint8_t functioncode, ModbusStatus status) {
  86. /**
  87. * @brief TODO:txbuffer长度计算
  88. */
  89. volatile uint16_t _sendlength = 0;
  90. volatile uint16_t i = 0;
  91. if (length < 4) return;
  92. txbuffer[0] = deviceid;
  93. txbuffer[1] = functioncode | 0x80;
  94. txbuffer[2] = (uint8_t)status;
  95. *sendlength = 0;
  96. // sendLen = add(1byte)+functionCode(1byte)+exception(1)+crc(2) = 4
  97. _sendlength = 4;
  98. ZGenerateCRC16CheckCodeToPacket(txbuffer, _sendlength);
  99. *sendlength = _sendlength;
  100. return;
  101. }