137 lines
3.7 KiB
C
137 lines
3.7 KiB
C
#ifndef MODBUS_ESP_H
|
||
#define MODBUS_ESP_H
|
||
|
||
#include <stdint.h>
|
||
#include <stddef.h>
|
||
#include <stdbool.h>
|
||
#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
|