面向对象编程思想--UART设备(Modbus AND AT)

        现在设计一个UART设备的驱动框架,针对AT指令模块和Modbus协议。要整合状态机、时间窗机制,同时满足各种AT指令设备的需求,并且考虑Modbus的解析。

        首先,AT指令设备包括ESP32、NB-IoT模块、4G模块等,这些都是通过UART使用AT指令控制的。另外还需要支持Modbus协议,所以框架需要兼容不同协议。

        AT指令通常需要状态机来处理异步响应,比如发送AT命令后等待OK或ERROR。同时,多个模块可能同时使用UART,需要考虑如何管理并发请求,需要队列机制。时间窗口机制可能用于处理超时,比如发送指令后在一定时间内没有响应则认为失败。此外,不同的AT模块可能有不同的响应格式,需要可配置的解析方法。

        Modbus协议基于主从架构,有固定的报文结构,所以解析部分需要与AT指令分开处理。可能需要不同的解析回调函数。

        接下来,需要设计UART驱动结构体,包含基本的发送接收函数,并且支持DMA。设备结构体需要包含AT指令的状态机、命令队列、超时处理,以及Modbus相关的解析参数。状态机的设计是关键。每个AT指令可能需要多个状态:发送命令、等待响应、处理响应、错误处理等。需要通用的状态转移机制,允许用户注册自定义的状态处理函数。

        那么对于Modbus,需要处理RTU和ASCII模式,校验计算,超时管理。需要在设备结构体中包含Modbus的专用配置,如从机地址、功能码处理函数等。另外,需要考虑缓冲区管理,接收不定长的数据,如何分割不同的响应帧。环形缓冲区是一个好的选择,同时结合事件触发解析。

        现在需要统一的事件处理机制,比如数据接收完成事件、超时事件,触发相应的解析函数。对于AT指令,可能需要将接收到的数据按行分割,逐行处理;而Modbus则需要按报文长度或帧间隔来解析。在代码结构上,驱动层负责底层的UART传输,设备层分为AT指令设备和Modbus设备,各自实现不同的解析逻辑。使用链表管理所有UART设备,当接收到数据时,根据设备配置分发到对应的处理函数。

        那么实际在测试过程中,多个设备共享同一个UART端口时的冲突,需要硬件或软件上的片选机制,但UART通常没有硬件片选,所以需要软件控制不同的使能引脚,或者在协议层通过地址区分。需要处理AT指令的并发问题,比如上一个命令还未完成响应,又发送新命令。这时需要命令队列来管理待发送的指令,确保顺序执行。超时处理需要定时器支持,当发送命令后启动定时器,若超时则触发重试或错误回调。时间窗机制可能涉及动态调整超时时间,根据历史响应时间优化。

        对于Modbus,需要处理主站和从站的不同角色,但大多数情况下这些模块作为主站,所以框架可能需要支持主站功能,包括生成请求帧和解析响应帧。

1. 定义UART驱动结构体,包含初始化、发送、接收等基本操作,支持中断/DMA。

2. 定义UART设备基类结构体,包含接收缓冲区、事件处理回调、协议类型(AT或Modbus)。

3. 对于AT指令设备,设计状态机、命令队列、超时管理,允许注册自定义命令和响应处理。

4. 对于Modbus设备,设计RTU/ASCII模式支持,校验计算,请求/响应解析函数。

5. 使用链表管理所有设备,数据接收时根据设备配置分发到对应的解析函数。

6. 实现状态机引擎,处理AT指令的状态转移和超时。

7. 实现Modbus协议解析器,处理帧的组装和拆分。

8. 提供统一的API接口,如发送AT命令、发送Modbus请求,处理异步响应。

 直接上代码:

#include "stm32f1xx_hal.h"
#include 
#include 

/* 协议类型枚举 */
typedef enum {
    PROTOCOL_AT,        // AT指令协议
    PROTOCOL_MODBUS     // Modbus协议
} UART_ProtocolType;

/* 事件类型定义 */
typedef enum {
    EVENT_UART_RX_DATA,     // 接收到数据
    EVENT_UART_TX_COMPLETE, // 发送完成
    EVENT_TIMEOUT,          // 超时事件
    EVENT_MODBUS_MSG        // Modbus报文事件
} UART_EventType;

/* UART驱动结构体 */
typedef struct {
    UART_HandleTypeDef *huart;      // HAL UART句柄
    DMA_HandleTypeDef *hdma_rx;     // DMA接收句柄
    DMA_HandleTypeDef *hdma_tx;     // DMA发送句柄
    
    // 方法抽象
    int (*init)(struct UARTDriver *driver);
    int (*send)(struct UARTDriver *driver, uint8_t *data, uint16_t len);
    int (*receive)(struct UARTDriver *driver, uint16_t len);
} UARTDriver;

/* 通用UART设备基类 */
typedef struct UARTDevice {
    char dev_name[16];             // 设备标识
    UARTDriver *driver;            // 关联的驱动
    UART_ProtocolType protocol;    // 协议类型
    struct list_head list;         // 链表节点
    
    // 接收缓冲区管理
    uint8_t *rx_buffer;            // 环形缓冲区
    uint16_t buf_size;             // 缓冲区大小
    volatile uint16_t wr_idx;      // 写索引
    volatile uint16_t rd_idx;      // 读索引
    
    // 事件回调
    void (*eventHandler)(struct UARTDevice *dev, UART_EventType event);
    
    // 协议相关联合体
    union {
        struct { /* AT指令协议专用 */
            struct ATCommand *cmd_queue;   // 命令队列
            uint8_t q_size;               // 队列容量
            uint8_t q_front;              // 队首索引
            uint8_t q_rear;               // 队尾索引
            uint8_t retry_count;          // 当前重试次数
            uint32_t timeout;             // 超时时间(ms)
            void (*responseParser)(struct UARTDevice *dev, char *response);
        } at;
        
        struct { /* Modbus协议专用 */
            uint8_t slave_addr;           // 从机地址
            uint32_t last_req_time;       // 最后请求时间
            uint16_t crc_error_count;     // CRC错误计数
            void (*modbusHandler)(struct UARTDevice *dev, uint8_t func_code, 
                                 uint16_t reg_addr, uint16_t data);
        } modbus;
    };
} UARTDevice;

/******************** AT指令状态机实现 ********************/
typedef enum {
    AT_STATE_IDLE,          // 空闲状态
    AT_STATE_SENDING,       // 发送中
    AT_STATE_WAIT_RESPONSE, // 等待响应
    AT_STATE_ERROR          // 错误状态
} AT_State;

typedef struct ATCommand {
    char *command;          // AT命令字符串
    char *expect_response;  // 预期响应
    uint8_t max_retries;    // 最大重试次数
    void (*callback)(struct UARTDevice *dev, int result); // 完成回调
    uint32_t timeout;       // 命令超时时间
} ATCommand;

/* AT指令状态机上下文 */
typedef struct {
    AT_State current_state;
    ATCommand current_cmd;
    uint32_t state_timer;
} AT_StateMachine;

/* AT指令队列操作 */
int AT_Enqueue_Command(UARTDevice *dev, ATCommand cmd) {
    if((dev->at.q_rear + 1) % dev->at.q_size == dev->at.q_front) {
        return -1; // 队列满
    }
    dev->cmd_queue[dev->at.q_rear] = cmd;
    dev->at.q_rear = (dev->at.q_rear + 1) % dev->at.q_size;
    return 0;
}

/******************** Modbus协议处理 ********************/
typedef enum {
    MODBUS_RTU,
    MODBUS_ASCII
} ModbusMode;

/* Modbus帧结构 */
typedef struct {
    uint8_t slave_addr;
    uint8_t func_code;
    uint16_t start_addr;
    uint16_t reg_count;
    uint16_t crc;
} ModbusFrame;

/* CRC16计算 */
uint16_t Modbus_CRC16(uint8_t *data, uint16_t len) {
    uint16_t crc = 0xFFFF;
    for(int pos = 0; pos < len; pos++) {
        crc ^= (uint16_t)data[pos];
        for(int i = 8; i != 0; i--) {
            if((crc & 0x0001) != 0) {
                crc >>= 1;
                crc ^= 0xA001;
            } else {
                crc >>= 1;
            }
        }
    }
    return crc;
}

/* Modbus帧解析 */
int Modbus_Parse_Frame(UARTDevice *dev) {
    // 实现帧完整性检查和解析
    // 返回0表示有效帧,-1表示错误
}

/******************** 通用驱动实现 ********************/
/* 环形缓冲区操作 */
uint16_t UART_Get_Rx_Data(UARTDevice *dev, uint8_t *buf, uint16_t max_len) {
    uint16_t available = (dev->wr_idx >= dev->rd_idx) ? 
        (dev->wr_idx - dev->rd_idx) : 
        (dev->buf_size - dev->rd_idx + dev->wr_idx);
    
    uint16_t to_read = (available > max_len) ? max_len : available;
    for(int i=0; irx_buffer[(dev->rd_idx + i) % dev->buf_size];
    }
    dev->rd_idx = (dev->rd_idx + to_read) % dev->buf_size;
    return to_read;
}

/* UART接收完成回调 */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {
    // 遍历设备链表查找匹配的驱动
    struct list_head *pos;
    UARTDevice *dev;
    list_for_each(pos, &uart_dev_list) {
        dev = list_entry(pos, UARTDevice, list);
        if(dev->driver->huart == huart) {
            dev->eventHandler(dev, EVENT_UART_RX_DATA);
        }
    }
}

/******************** AT指令状态机处理 ********************/
void AT_State_Machine_Handler(UARTDevice *dev) {
    AT_StateMachine *sm = &dev->state_machine;
    
    switch(sm->current_state) {
        case AT_STATE_IDLE:
            if(dev->at.q_front != dev->at.q_rear) {
                sm->current_cmd = dev->cmd_queue[dev->at.q_front];
                dev->at.q_front = (dev->at.q_front + 1) % dev->at.q_size;
                dev->driver->send(dev->driver, 
                                 (uint8_t*)sm->current_cmd.command, 
                                 strlen(sm->current_cmd.command));
                sm->current_state = AT_STATE_SENDING;
                sm->state_timer = HAL_GetTick();
            }
            break;
            
        case AT_STATE_SENDING:
            if(dev->last_event == EVENT_UART_TX_COMPLETE) {
                sm->current_state = AT_STATE_WAIT_RESPONSE;
                sm->state_timer = HAL_GetTick();
            }
            break;
            
        case AT_STATE_WAIT_RESPONSE:
            if(HAL_GetTick() - sm->state_timer > sm->current_cmd.timeout) {
                if(++dev->at.retry_count >= sm->current_cmd.max_retries) {
                    sm->current_state = AT_STATE_ERROR;
                    if(sm->current_cmd.callback) {
                        sm->current_cmd.callback(dev, -1);
                    }
                } else {
                    sm->current_state = AT_STATE_IDLE; // 重试
                }
            }
            // 响应处理在数据接收事件中完成
            break;
            
        case AT_STATE_ERROR:
            // 错误恢复处理
            break;
    }
}

/******************** Modbus协议处理 ********************/
void Modbus_Process_Frame(UARTDevice *dev) {
    uint8_t frame[256];
    uint16_t len = UART_Get_Rx_Data(dev, frame, sizeof(frame));
    
    if(Modbus_Parse_Frame(dev, frame, len) == 0) {
        dev->eventHandler(dev, EVENT_MODBUS_MSG);
    }
}

/******************** 设备事件分发 ********************/
void UART_Device_EventHandler(UARTDevice *dev, UART_EventType event) {
    switch(dev->protocol) {
        case PROTOCOL_AT:
            if(event == EVENT_UART_RX_DATA) {
                char response[256];
                uint16_t len = UART_Get_Rx_Data(dev, (uint8_t*)response, sizeof(response)-1);
                response[len] = '\0';
                dev->at.responseParser(dev, response);
            }
            AT_State_Machine_Handler(dev);
            break;
            
        case PROTOCOL_MODBUS:
            if(event == EVENT_UART_RX_DATA) {
                Modbus_Process_Frame(dev);
            }
            break;
    }
}

/******************** 应用示例 ********************/
/* ESP8266 AT指令响应解析示例 */
void ESP8266_Response_Parser(UARTDevice *dev, char *response) {
    if(strstr(response, "OK")) {
        // 处理成功响应
    } else if(strstr(response, "ERROR")) {
        // 处理错误响应
    }
}

/* Modbus处理函数示例 */
void Modbus_Read_Holding_Regs(UARTDevice *dev, uint8_t func_code, 
                             uint16_t reg_addr, uint16_t data) {
    if(func_code == 0x03) {
        // 处理保持寄存器读取
    }
}

int main(void) {
    // 初始化HAL库、时钟、UART等
    
    /* 初始化UART驱动 */
    UARTDriver uart1_driver = {
        .huart = &huart1,
        .init = UART_Driver_Init,
        .send = UART_Driver_Send,
        .receive = UART_Driver_Receive
    };
    uart1_driver.init(&uart1_driver);
    
    /* 注册ESP8266设备 */
    UARTDevice esp8266 = {
        .dev_name = "ESP8266",
        .driver = &uart1_driver,
        .protocol = PROTOCOL_AT,
        .rx_buffer = malloc(256),
        .buf_size = 256,
        .eventHandler = UART_Device_EventHandler,
        .at = {
            .cmd_queue = malloc(sizeof(ATCommand)*5),
            .q_size = 5,
            .responseParser = ESP8266_Response_Parser,
            .timeout = 2000
        }
    };
    UART_Device_Register(&esp8266);
    
    /* 注册Modbus设备 */
    UARTDevice modbus_sensor = {
        .dev_name = "MB_SENSOR",
        .driver = &uart1_driver,
        .protocol = PROTOCOL_MODBUS,
        .rx_buffer = malloc(128),
        .buf_size = 128,
        .eventHandler = UART_Device_EventHandler,
        .modbus = {
            .slave_addr = 0x01,
            .modbusHandler = Modbus_Read_Holding_Regs
        }
    };
    UART_Device_Register(&modbus_sensor);
    
    /* 发送AT指令示例 */
    ATCommand wifi_cmd = {
        .command = "AT+CWMODE=1\r\n",
        .expect_response = "OK",
        .max_retries = 3,
        .timeout = 1000,
        .callback = NULL
    };
    AT_Enqueue_Command(&esp8266, wifi_cmd);
    
    /* 主循环 */
    while(1) {
        // 处理超时事件
        if(HAL_GetTick() - last_tick > 100) {
            Process_Timeout_Events();
            last_tick = HAL_GetTick();
        }
    }
}

/******************** 高级功能扩展 ********************/
/* 多协议混合解析 */
void Advanced_Protocol_Parser(UARTDevice *dev) {
    // 自动检测协议类型
    if(dev->rx_buffer[0] == 'A' && dev->rx_buffer[1] == 'T') {
        dev->protocol = PROTOCOL_AT;
    } else if(dev->rx_buffer[0] == dev->modbus.slave_addr) {
        dev->protocol = PROTOCOL_MODBUS;
    }
}

/* 自动重连机制 */
typedef struct {
    uint32_t connect_interval;
    uint8_t max_retries;
    void (*reset_procedure)(UARTDevice *dev);
} AutoReconnectCfg;

void Auto_Reconnect_Handler(UARTDevice *dev) {
    static uint32_t last_attempt = 0;
    if(HAL_GetTick() - last_attempt > dev->auto_reconnect.connect_interval) {
        dev->auto_reconnect.reset_procedure(dev);
        last_attempt = HAL_GetTick();
    }
}

/* 流量控制实现 */
typedef struct {
    uint8_t rts_pin;
    uint8_t cts_pin;
    GPIO_TypeDef *flow_port;
    void (*flow_control)(struct UARTDevice *dev, uint8_t state);
} FlowControlCfg;

void Hardware_Flow_Control(UARTDevice *dev, uint8_t state) {
    HAL_GPIO_WritePin(dev->flow.flow_port, dev->flow.rts_pin, state);
}

 关键设计说明

一、分层架构设计

/* 系统架构层次划分 */
+-----------------------+
|     应用层            |  // AT指令应用、Modbus业务逻辑
+-----------------------+
|   协议处理层          |  // AT状态机、Modbus解析
+-----------------------+
|   设备驱动层          |  // UART驱动、DMA管理
+-----------------------+
|  硬件抽象层(HAL)      |  // STM32 HAL库
+-----------------------+

二、AT指令状态机初始化

/* 增强型状态机设计 */
typedef struct {
    AT_State state;
    uint32_t timer;
    uint8_t retries;
    ATCommand *cmd;
    void (*transition)(struct StateMachine *sm, UART_EventType event);
} StateMachine;

/* 状态转移表示例 */
const StateTransition transitions[] = {
    {AT_STATE_IDLE, EVENT_CMD_QUEUED, AT_STATE_SENDING, SendCommand},
    {AT_STATE_SENDING, EVENT_TX_COMPLETE, AT_STATE_WAITING, StartTimeout},
    {AT_STATE_WAITING, EVENT_RX_MATCH, AT_STATE_IDLE, ProcessSuccess},
    {AT_STATE_WAITING, EVENT_TIMEOUT, AT_STATE_RETRY, HandleRetry}
};

三、Modbus协议

/* Modbus高级功能 */
typedef struct {
    uint8_t func_code;
    uint16_t (*data_formatter)(uint8_t *raw, uint16_t len);
    void (*exception_handler)(uint8_t code);
} ModbusFunctionHandler;

const ModbusFunctionHandler func_handlers[] = {
    {0x03, FormatReadRegisters, HandleReadException},
    {0x06, FormatWriteRegister, HandleWriteException},
    {0x10, FormatWriteRegisters, HandleMultiWriteException}
};

 四、流量控制实现

/* 软件流控制配置 */
typedef struct {
    uint8_t xon_char;
    uint8_t xoff_char;
    uint16_t high_watermark;
    uint16_t low_watermark;
} SoftwareFlowControl;

void Check_Flow_Control(UARTDevice *dev) {
    if(dev->rx_available > dev->flow.high_watermark) {
        Send_XOFF(dev);
    } else if(dev->rx_available < dev->flow.low_watermark) {
        Send_XON(dev);
    }
}

五、同一配置接口

/* 设备配置接口 */
typedef struct {
    int (*set_baudrate)(UARTDevice *dev, uint32_t baud);
    int (*set_parity)(UARTDevice *dev, uint32_t parity);
    int (*load_config)(UARTDevice *dev, void *config);
    int (*save_config)(UARTDevice *dev, void *config);
} UARTConfigAPI;

const UARTConfigAPI config_ops = {
    .set_baudrate = UART_Set_Baudrate,
    .set_parity = UART_Set_Parity,
    .load_config = Load_Device_Config,
    .save_config = Save_Device_Config
};

后续明天写,还有很多要讲,这里面东西还是不少的,拜拜。 

    你可能感兴趣的:(面向对象编程,网络,stm32,嵌入式硬件,单片机)