25개 이상의 토픽을 선택하실 수 없습니다. Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

157 lines
4.8 KiB

  1. #ifndef MODBUS_RTU_SLAVE_H
  2. #define MODBUS_RTU_SLAVE_H
  3. #include "stm32f4xx_hal.h"
  4. #ifdef __cplusplus
  5. extern "C"
  6. {
  7. #endif
  8. /**
  9. * @brief Modbus 数据模型的最大地址。
  10. *
  11. * 任务要求规定线圈和保持寄存器地址范围均为 0~0x270F,
  12. * 因此每种数据共有 10000 项。
  13. */
  14. #define MODBUS_MAP_LAST_ADDRESS (0x270FU)//保持寄存器或线圈地址
  15. #define MODBUS_MAP_ITEM_COUNT (0x2710U)//保持寄存器或线圈数量
  16. #define MODBUS_SLAVE_DEFAULT_ADDRESS (1U)
  17. #define MODBUS_CONNECTION_TIMEOUT_MS (1000U)
  18. /**
  19. * @brief 与 TouchWin 触摸屏联调使用的演示地址。
  20. *
  21. * 可以直接访问以下地址。
  22. */
  23. #define HMI_REG_DEVICE_ID (0U)
  24. #define HMI_REG_UPTIME_SECONDS (1U)
  25. #define HMI_REG_RX_FRAME_COUNT (2U)
  26. #define HMI_REG_WRITE_TEST (10U)
  27. #define HMI_COIL_WRITE_TEST (0U)
  28. #define MODBUS_RETAINED_D_START (100U)
  29. #define MODBUS_RETAINED_D_END (120U)
  30. #define MODBUS_RETAINED_D_COUNT (21U)
  31. #define MODBUS_BACKUP_MAGIC (0x44313030UL)
  32. typedef struct
  33. {
  34. uint32_t magic;
  35. uint16_t retainedD[MODBUS_RETAINED_D_COUNT];
  36. } MODBUS_BACKUP_DATA;
  37. static volatile MODBUS_BACKUP_DATA *backupData =(volatile MODBUS_BACKUP_DATA *)BKPSRAM_BASE;
  38. /**
  39. * @brief Modbus 从站通信统计信息。
  40. */
  41. typedef struct
  42. {
  43. uint32_t rxEventCount; ///< 串口接收事件总数。
  44. uint32_t validFrameCount; ///< CRC 和从站地址均有效的帧数。
  45. uint32_t txFrameCount; ///< 成功启动 DMA 发送的帧数。
  46. uint32_t crcErrorCount; ///< CRC 校验错误帧数。
  47. uint32_t ignoredAddressCount; ///< 因从站地址不匹配而忽略的帧数。
  48. uint32_t illegalFunctionCount; ///< 非法功能码计数。
  49. uint32_t illegalAddressCount; ///< 非法数据地址计数。
  50. uint32_t illegalValueCount; ///< 非法数据值计数。
  51. uint32_t droppedFrameCount; ///< 接收槽占用或长度错误导致的丢帧数。
  52. uint32_t uartErrorCount; ///< HAL 串口错误计数。
  53. } MODBUS_SLAVE_STATS;
  54. /** @brief Modbus 从站通信统计数据。 */
  55. extern volatile MODBUS_SLAVE_STATS ModbusSlaveStatistics;
  56. /**
  57. * @brief 初始化 Modbus 从站并启动 USART DMA 空闲接收。
  58. * @param[in] huart 已由 HAL 初始化完成的串口句柄。
  59. * @param[in] slaveAddress 从站地址,有效范围为 1~247。
  60. * @retval HAL_OK 初始化成功且 DMA 接收已启动。
  61. * @retval HAL_ERROR 输入参数无效。
  62. * @retval HAL_BUSY 串口或 DMA 当前忙。
  63. */
  64. HAL_StatusTypeDef ModbusSlaveInit(UART_HandleTypeDef *huart,
  65. uint8_t slaveAddress);
  66. /**
  67. * @brief 校验并处理一帧待处理请求。
  68. *
  69. * 本函数应在 uC/OS-II 任务中周期调用。中断只负责接收数据,
  70. * CRC 校验、协议解析和响应发送均在任务上下文中执行。
  71. */
  72. void ModbusSlavePoll(void);
  73. /**
  74. * @brief 处理 HAL 串口 DMA 接收事件。
  75. * @param[in] huart 产生接收事件的串口句柄。
  76. * @param[in] size 本次接收到的字节数。
  77. */
  78. void ModbusSlaveOnRxEvent(UART_HandleTypeDef *huart, uint16_t size);
  79. /**
  80. * @brief 处理 HAL 串口 DMA 发送完成事件。
  81. * @param[in] huart 完成发送的串口句柄。
  82. */
  83. void ModbusSlaveOnTxComplete(UART_HandleTypeDef *huart);
  84. /**
  85. * @brief 处理 HAL 串口错误事件并恢复接收。
  86. * @param[in] huart 发生错误的串口句柄。
  87. */
  88. void ModbusSlaveOnUartError(UART_HandleTypeDef *huart);
  89. /**
  90. * @brief 写入一个保持寄存器。
  91. * @param[in] address 保持寄存器地址。
  92. * @param[in] value 待写入的 16 位数据。
  93. */
  94. uint8_t ModbusSlaveSetHoldingRegister(uint16_t address, uint16_t value);
  95. /**
  96. * @brief 读取一个保持寄存器。
  97. * @param[in] address 保持寄存器地址。
  98. * @param[out] value 用于保存读取结果的指针。
  99. */
  100. uint8_t ModbusSlaveGetHoldingRegister(uint16_t address, uint16_t *value);
  101. /**
  102. * @brief 设置一个线圈的状态。
  103. * @param[in] address 线圈地址。
  104. * @param[in] state 0 表示复位,非 0 表示置位。
  105. */
  106. uint8_t ModbusSlaveSetCoil(uint16_t address, uint8_t state);
  107. /**
  108. * @brief 读取一个线圈的状态。
  109. * @param[in] address 线圈地址。
  110. * @param[out] state 用于保存线圈状态的指针,结果为 0 或 1。
  111. */
  112. uint8_t ModbusSlaveGetCoil(uint16_t address, uint8_t *state);
  113. /**
  114. * @brief 判断指定时间内是否收到过有效请求。
  115. * @param[in] timeoutMs 连接超时时间,单位为毫秒。
  116. * @retval 1 从站在指定时间内收到过有效请求。
  117. * @retval 0 尚未收到有效请求或连接已经超时。
  118. */
  119. uint8_t ModbusSlaveIsConnected(uint32_t timeoutMs);
  120. void ModbusRetainedRegistersLoad(void);
  121. void ModbusRetainedRegistersPoll(void);
  122. #ifdef __cplusplus
  123. }
  124. #endif
  125. #endif /* MODBUS_RTU_SLAVE_H */