modbus_slave.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. //
  2. // Created by DELL on 2024/10/18.
  3. //
  4. #include "modbus_slave.h"
  5. #include "port.h"
  6. #include "mb.h"
  7. #include "cmsis_os2.h"
  8. USHORT usSRegHoldStart = S_REG_HOLDING_START;
  9. static USHORT usSRegHoldBuf[S_REG_HOLDING_NREGS];
  10. const static osThreadAttr_t task_attributes = {
  11. .name = "slave_485_task",
  12. .stack_size = 128 * 4,
  13. .priority = (osPriority_t) osPriorityHigh,
  14. };
  15. /**
  16. * 输入型寄存器读写回调函数
  17. * @param pucRegBuffer
  18. * @param usAddress
  19. * @param usNRegs
  20. * @return
  21. */
  22. eMBErrorCode eMBRegInputCB(UCHAR *pucRegBuffer, USHORT usAddress, USHORT usNRegs)
  23. {
  24. return MB_ENOERR;
  25. }
  26. /**
  27. * 保持型寄存器读写回调函数
  28. * @param pucRegBuffer
  29. * @param usAddress
  30. * @param usNRegs
  31. * @param eMode
  32. * @return
  33. */
  34. eMBErrorCode eMBRegHoldingCB(UCHAR *pucRegBuffer, USHORT usAddress, USHORT usNRegs, eMBRegisterMode eMode)
  35. {
  36. eMBErrorCode eStatus = MB_ENOERR;
  37. USHORT iRegIndex;
  38. USHORT *pusRegHoldingBuf;
  39. USHORT REG_HOLDING_START;
  40. USHORT REG_HOLDING_NREGS;
  41. USHORT usRegHoldStart;
  42. pusRegHoldingBuf = usSRegHoldBuf;
  43. REG_HOLDING_START = S_REG_HOLDING_START;
  44. REG_HOLDING_NREGS = S_REG_HOLDING_NREGS;
  45. usRegHoldStart = usSRegHoldStart;
  46. /* it already plus one in modbus function method. */
  47. usAddress--;
  48. if ((usAddress >= REG_HOLDING_START)
  49. && (usAddress + usNRegs <= REG_HOLDING_START + REG_HOLDING_NREGS))
  50. {
  51. iRegIndex = usAddress - usRegHoldStart;
  52. switch (eMode)
  53. {
  54. /* read current register values from the protocol stack. */
  55. case MB_REG_READ:
  56. while (usNRegs > 0)
  57. {
  58. *pucRegBuffer++ = (UCHAR) (pusRegHoldingBuf[iRegIndex] >> 8);
  59. *pucRegBuffer++ = (UCHAR) (pusRegHoldingBuf[iRegIndex] & 0xFF);
  60. iRegIndex++;
  61. usNRegs--;
  62. }
  63. break;
  64. /* write current register values with new values from the protocol stack. */
  65. case MB_REG_WRITE:
  66. while (usNRegs > 0)
  67. {
  68. pusRegHoldingBuf[iRegIndex] = *pucRegBuffer++ << 8;
  69. pusRegHoldingBuf[iRegIndex] |= *pucRegBuffer++;
  70. iRegIndex++;
  71. usNRegs--;
  72. }
  73. break;
  74. }
  75. } else
  76. {
  77. eStatus = MB_ENOREG;
  78. }
  79. return eStatus;
  80. }
  81. uint16_t get_reg_value(uint16_t addr)
  82. {
  83. if (addr >= S_REG_HOLDING_NREGS)
  84. {
  85. return 0;
  86. }
  87. return usSRegHoldBuf[addr];
  88. }
  89. void set_reg_value(uint16_t addr, uint16_t value)
  90. {
  91. if (addr >= S_REG_HOLDING_NREGS)
  92. {
  93. return;
  94. }
  95. usSRegHoldBuf[addr] = value;
  96. }
  97. /**
  98. * 从机任务
  99. * @param pv
  100. */
  101. _Noreturn static void slave_485_task(void *pv)
  102. {
  103. eMBErrorCode code;
  104. uint8_t slave_addr = (uint8_t) pv;
  105. eMBInit(MB_RTU, slave_addr, 3, 9600, MB_PAR_NONE);
  106. eMBEnable();
  107. for (;;)
  108. {
  109. eMBPoll();
  110. osDelay(5);
  111. }
  112. }
  113. void start_485_slave(uint8_t address)//启动485从机
  114. {
  115. usSRegHoldBuf[0] = address; // init current communication address
  116. osThreadNew(slave_485_task, (void *) address, &task_attributes);
  117. }