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.

83 lines
2.6 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 ModbusCreateTx_setReg(uint8_t *txbuffer, uint8_t length, uint16_t off, uint16_t regdata) {
  8. if (3 + off * 2 > length - 2) {
  9. return;
  10. }
  11. txbuffer[3 + off * 2] = regdata >> 8;
  12. txbuffer[3 + off * 2 + 1] = (uint8_t)regdata;
  13. }
  14. void ModbusCreateTxData(uint8_t *txbuffer, uint8_t length, uint16_t *sendlength, ModbusSlaveData_t *txdata) {
  15. /**
  16. * @brief TODO:txbuffer长度计算
  17. */
  18. if (length < 4) return;
  19. txbuffer[0] = txdata->deviceId;
  20. txbuffer[1] = (uint8_t)txdata->functionCode;
  21. *sendlength = 0;
  22. volatile uint16_t _sendlength = 0;
  23. volatile uint16_t i = 0;
  24. if (txdata->functionCode == ModbusOrder01 || txdata->functionCode == ModbusOrder02 ||
  25. txdata->functionCode == ModbusOrder03 || txdata->functionCode == ModbusOrder04) {
  26. /**
  27. * @brief 01,02 bit
  28. */
  29. //读取多个输出状态
  30. // sendLen =
  31. // add(1byte)+functionCode(1byte)+addNum(1)+crc(2) = 5+numbyte
  32. volatile uint16_t numbyte = txdata->d.O01.bytenum;
  33. _sendlength = 5 + numbyte;
  34. if (length < _sendlength) return;
  35. txbuffer[2] = txdata->d.O01.bytenum;
  36. if (txdata->d.O01.byte_table != NULL) {
  37. for (i = 0; i < numbyte; i++) {
  38. txbuffer[3 + i] = txdata->d.O01.byte_table[i];
  39. }
  40. }
  41. } else if (txdata->functionCode == ModbusOrder0F || txdata->functionCode == ModbusOrder10) {
  42. //写入多个输出
  43. // sendLen = add(1byte)+functionCode(1byte)+startAdd(2)+addNum(2)+crc(2) = 8
  44. _sendlength = 8;
  45. if (length < _sendlength) return;
  46. UINT16ToUINT8(txdata->d.O0F.startbit, &txbuffer[2]);
  47. UINT16ToUINT8(txdata->d.O0F.bitnum, &txbuffer[4]);
  48. } else {
  49. /**
  50. * @brief Not support now
  51. */
  52. }
  53. // calculate crc
  54. if (_sendlength > 2) {
  55. ZGenerateCRC16CheckCodeToPacket(txbuffer, _sendlength);
  56. }
  57. *sendlength = _sendlength;
  58. }
  59. void ModbusCreateExceptionData(uint8_t *txbuffer, uint8_t length, uint16_t *sendlength, uint8_t deviceid,
  60. uint8_t functioncode, ModbusStatus status) {
  61. /**
  62. * @brief TODO:txbuffer长度计算
  63. */
  64. volatile uint16_t _sendlength = 0;
  65. volatile uint16_t i = 0;
  66. if (length < 4) return;
  67. txbuffer[0] = deviceid;
  68. txbuffer[1] = functioncode | 0x80;
  69. txbuffer[2] = (uint8_t)status;
  70. *sendlength = 0;
  71. // sendLen = add(1byte)+functionCode(1byte)+exception(1)+crc(2) = 4
  72. _sendlength = 4;
  73. ZGenerateCRC16CheckCodeToPacket(txbuffer, _sendlength);
  74. *sendlength = _sendlength;
  75. return;
  76. }