#ifndef MODBUS_ESP_H #define MODBUS_ESP_H #include #include #include #include "freertos/FreeRTOS.h" #include "freertos/task.h" /** * @brief MODBUS功能码定义 */ typedef enum { MODBUS_FUNC_READ_HOLDING_REGISTERS = 0x03, // 读取保持寄存器 } modbus_function_code_t; /** * @brief MODBUS异常码定义 */ typedef enum { MODBUS_EXCEPTION_ILLEGAL_FUNCTION = 0x01, MODBUS_EXCEPTION_ILLEGAL_DATA_ADDRESS = 0x02, MODBUS_EXCEPTION_ILLEGAL_DATA_VALUE = 0x03, MODBUS_EXCEPTION_SERVER_DEVICE_FAILURE = 0x04, } modbus_exception_code_t; /** * @brief MODBUS响应结构体 */ typedef struct { uint8_t slave_addr; // 从机地址 uint8_t function_code; // 功能码 uint8_t byte_count; // 数据字节数 uint16_t *registers; // 寄存器数据(需要调用者释放) uint8_t register_count; // 寄存器数量 bool is_exception; // 是否为异常响应 uint8_t exception_code; // 异常码(如果是异常响应) } modbus_response_t; /** * @brief 计算CRC-16 (MODBUS RTU标准) * * @param data 数据指针 * @param len 数据长度 * @return uint16_t CRC校验值 */ uint16_t modbus_crc16(const uint8_t *data, size_t len); /** * @brief 验证CRC校验 * * @param data 数据指针(包含CRC的完整帧) * @param len 数据长度(包含CRC的2个字节) * @return true CRC校验成功 * @return false CRC校验失败 */ bool modbus_verify_crc(const uint8_t *data, size_t len); /** * @brief 构建MODBUS RTU读取保持寄存器请求帧(功能码03) * * @param slave_addr 从机地址 * @param start_addr 起始寄存器地址 * @param reg_count 读取寄存器数量 * @param frame 输出帧缓冲区(需要至少8字节) * @param frame_len 输出帧长度 * @return true 构建成功 * @return false 构建失败(参数错误) */ bool modbus_build_read_holding_req(uint8_t slave_addr, uint16_t start_addr, uint16_t reg_count, uint8_t *frame, size_t *frame_len); /** * @brief 解析MODBUS RTU响应帧(仅支持功能码03) * * @param frame 接收到的帧数据 * @param frame_len 帧长度 * @param response 解析结果结构体 * @return true 解析成功 * @return false 解析失败(CRC错误、格式错误等) */ bool modbus_parse_response(const uint8_t *frame, size_t frame_len, modbus_response_t *response); /** * @brief 释放MODBUS响应结构体中的寄存器内存 * * @param response MODBUS响应结构体 */ void modbus_free_response(modbus_response_t *response); /** * @brief MODBUS轮询配置结构体 */ typedef struct { int channel_num; // RS485通道号 (0 或 1) uint8_t slave_addr; // 从机地址 uint16_t start_addr; // 起始寄存器地址 uint16_t reg_count; // 读取寄存器数量 uint32_t poll_interval_ms; // 轮询间隔(毫秒) bool enabled; // 是否启用 } modbus_poll_config_t; /** * @brief 启动MODBUS轮询任务 * * @param config 轮询配置指针 * @param priority 任务优先级 * @param stack_size 任务栈大小 * @return BaseType_t pdTRUE 成功, pdFALSE 失败 */ BaseType_t modbus_start_poll_task(modbus_poll_config_t *config, UBaseType_t priority, uint32_t stack_size); /** * @brief 停止MODBUS轮询任务 * * @return 无返回值 */ void modbus_stop_poll_task(void); /** * @brief 更新轮询配置 * * @param config 新的轮询配置 * @return true 更新成功 * @return false 更新失败 */ bool modbus_update_poll_config(modbus_poll_config_t *config); /** * @brief 获取当前轮询配置 * * @return modbus_poll_config_t* 当前配置指针 */ modbus_poll_config_t* modbus_get_current_config(void); #endif // MODBUS_ESP_H