Non puoi selezionare più di 25 argomenti Gli argomenti devono iniziare con una lettera o un numero, possono includere trattini ('-') e possono essere lunghi fino a 35 caratteri.
 
 
 
 
 

81 righe
2.5 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. #endif
  7. /*
  8. * 任务文档规定线圈和保持寄存器地址范围均为0~0x270F。
  9. * 因此地址总数是0x2710,即10000个。
  10. */
  11. #define MODBUS_MAP_LAST_ADDRESS 0x270FU
  12. #define MODBUS_MAP_ITEM_COUNT 0x2710U
  13. #define MODBUS_SLAVE_DEFAULT_ADDRESS 1U
  14. #define MODBUS_CONNECTION_TIMEOUT_MS 1000U
  15. /*
  16. * 供第一次与触摸屏联调使用的演示地址。
  17. * TouchWin选择“起始地址为0”的Modbus RTU主站协议后,可直接访问这些地址。
  18. */
  19. #define HMI_REG_DEVICE_ID 0U
  20. #define HMI_REG_UPTIME_SECONDS 1U
  21. #define HMI_REG_RX_FRAME_COUNT 2U
  22. #define HMI_REG_WRITE_TEST 10U
  23. #define HMI_COIL_WRITE_TEST 0U
  24. typedef struct
  25. {
  26. uint32_t rx_event_count;
  27. uint32_t valid_frame_count;
  28. uint32_t tx_frame_count;
  29. uint32_t crc_error_count;
  30. uint32_t ignored_address_count;
  31. uint32_t illegal_function_count;
  32. uint32_t illegal_address_count;
  33. uint32_t illegal_value_count;
  34. uint32_t dropped_frame_count;
  35. uint32_t uart_error_count;
  36. } ModbusSlaveStats;
  37. extern volatile ModbusSlaveStats g_modbus_slave_stats;
  38. /*
  39. * 初始化从站并启动USART DMA空闲接收。
  40. * 必须在MX_USART1_UART_Init()和DMA初始化完成后调用。
  41. */
  42. HAL_StatusTypeDef ModbusSlave_Init(UART_HandleTypeDef *huart,
  43. uint8_t slave_address);
  44. /*
  45. * 在uC/OS-II任务中周期调用,用于校验并处理一帧请求。
  46. * 中断只负责搬运数据,协议解析留在任务上下文中执行。
  47. */
  48. void ModbusSlave_Poll(void);
  49. /* 以下三个接口由STM32 HAL串口回调调用。 */
  50. void ModbusSlave_OnRxEvent(UART_HandleTypeDef *huart, uint16_t size);
  51. void ModbusSlave_OnTxComplete(UART_HandleTypeDef *huart);
  52. void ModbusSlave_OnUartError(UART_HandleTypeDef *huart);
  53. /* 应用层访问保持寄存器和线圈的接口。返回0表示地址非法。 */
  54. uint8_t ModbusSlave_SetHoldingRegister(uint16_t address, uint16_t value);
  55. uint8_t ModbusSlave_GetHoldingRegister(uint16_t address, uint16_t *value);
  56. uint8_t ModbusSlave_SetCoil(uint16_t address, uint8_t state);
  57. uint8_t ModbusSlave_GetCoil(uint16_t address, uint8_t *state);
  58. /*
  59. * 在timeout_ms时间内收到过有效请求即认为触摸屏在线。
  60. * 该状态适用于实现任务要求中的连接/断线判断。
  61. */
  62. uint8_t ModbusSlave_IsConnected(uint32_t timeout_ms);
  63. #ifdef __cplusplus
  64. }
  65. #endif
  66. #endif