modbus_slave.c 3.7 KB

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