diff --git a/protocol.c b/protocol.c index fc1c7c1..1b4e722 100644 --- a/protocol.c +++ b/protocol.c @@ -56,6 +56,13 @@ static const uint16_t crcTable[] = { 0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040 }; +/** + * 计算数据的CRC16校验值 + * + * @param data 需要计算CRC的数据缓冲区 + * @param length 数据长度 + * @return 计算得到的CRC16校验值 + */ uint16_t CalculateCRC16(uint8_t *data, uint16_t length) { uint16_t crc = 0xFFFF; @@ -67,11 +74,21 @@ uint16_t CalculateCRC16(uint8_t *data, uint16_t length) { return crc; } -// 更新下挂设备状态 +/** + * 更新下挂设备状态 + * + * @param status 设备状态值(在线/离线) + */ void updateDeviceStatus(DeviceStatus_t status) { deviceStatus.deviceStatus = status; } -// 更新三通阀状态 + +/** + * 更新三通阀状态 + * + * @param index 阀门索引(1或2) + * @param angle 阀门角度值(120°或210°) + */ void updateValveStatus(uint8_t index, ValveAngle_t angle) { if (index == 1) { deviceStatus.valves.angle1 = angle; @@ -80,7 +97,12 @@ void updateValveStatus(uint8_t index, ValveAngle_t angle) { } } -// 更新泵状态 +/** + * 更新泵运行状态 + * + * @param index 泵索引(1或2) + * @param status 泵状态值(停止/顺时针/逆时针) + */ void updatePumpStatus(uint8_t index, PumpStatus_t status) { if (index == 1) { deviceStatus.pumps.status1 = status; @@ -89,7 +111,12 @@ void updatePumpStatus(uint8_t index, PumpStatus_t status) { } } -// 更新泵速度状态 +/** + * 更新泵速度状态 + * + * @param index 泵索引(1或2) + * @param speed 泵速度值(0-100%) + */ void updatePumpSpeedStatus(uint8_t index, uint8_t speed) { if (index == 1) { deviceStatus.pumps.speed1 = speed; @@ -98,21 +125,38 @@ void updatePumpSpeedStatus(uint8_t index, uint8_t speed) { } } -// 更新气泡传感器读数 +/** + * 更新气泡传感器状态 + * + * @param value 气泡传感器状态值(有/无气泡) + */ void updateBubbleSensor(BubbleStatus_t value) { deviceStatus.bubbleStatus = value; } -// 更新急停状态 +/** + * 更新急停状态 + * + * @param status 急停状态值(正常/按下) + */ void updateEmergencyStop(EstopStatus_t status) { deviceStatus.stopStatus = status; } -// 更新错误码 + +/** + * 更新错误码 + * + * @param errorCode 错误码值 + */ void updateErrorCode(ErrorCode_t errorCode) { deviceStatus.errorCode = errorCode; } -// 更新初始化状态 +/** + * 更新初始化状态 + * + * @param status 初始化状态值(进行中/成功/失败) + */ void updateInitStatus(InitStatus_t status) { deviceStatus.initStatus = status; } @@ -120,14 +164,26 @@ void updateInitStatus(InitStatus_t status) { -//modBUS RTU 写命令 +/** + * ModBUS RTU写命令 + * 通过串口发送ModBUS RTU格式的命令 + * + * @param txBuf 发送数据缓冲区 + * @param txLen 发送数据长度 + */ void writeCMD(uint8_t *txBuf, uint16_t txLen) { } -uint8_t SendToHost(uint8_t *txBuf, uint16_t txLen) { - // 发送数据到主机 - // 具体实现 - return 0; +/** + * 发送数据到主机 + * + * @param txBuf 发送数据缓冲区 + * @param txLen 发送数据长度 + * @return 0:成功 其他:失败 + */ +void sendMsgToHost(uint8_t *txBuf, uint16_t txLen) { + // 发送数据 + HAL_UART_Transmit_DMA(&huart2, txBuf, txLen); } @@ -259,12 +315,35 @@ uint8_t WritePump2Reg(uint8_t index, uint16_t reg, uint32_t value) { +--------------+--------------------------------+ */ +/** + * 设置泵的步进加速度 + * + * @param index 泵索引 + * @param acc 加速度值 + * @return 0:成功 其他:失败 + */ static uint8_t WriteJogAcc(uint8_t index, uint16_t acc) { WritePump1Reg(index, RTU_PUMP_CMD_JA, acc); } + +/** + * 设置泵的步进减速度 + * + * @param index 泵索引 + * @param dec 减速度值 + * @return 0:成功 其他:失败 + */ static uint8_t WriteJogDec(uint8_t index, uint16_t dec) { WritePump1Reg(index, RTU_PUMP_CMD_JL, dec); } + +/** + * 设置泵的步进速度 + * + * @param index 泵索引 + * @param speed 速度值 + * @return 0:成功 其他:失败 + */ static uint8_t WriteJogSpeed(uint8_t index, uint16_t speed) { WritePump1Reg(index, RTU_PUMP_CMD_JS, speed); } @@ -292,68 +371,141 @@ static uint8_t StopJogControl(uint8_t index) { +--------------+--------------------------------+ | 2. | 设置步进DI | +--------------+--------------------------------+ -| 3. | 启动相对位置FL,或绝对位置FP | +| 3. | 动相对位置FL,或绝对位置FP | +--------------+--------------------------------+ | 4. | 停止泵SK | +--------------+--------------------------------+ */ +/** + * 设置泵的步进加速度 + * + * @param index 泵索引 + * @param acc 加速度值 + * @return 0:成功 其他:失败 + */ static uint8_t WriteStepAcc(uint8_t index, uint16_t acc) { WritePump1Reg(index, RTU_PUMP_CMD_AC, acc); } +/** + * 设置泵的步进减速度 + * + * @param index 泵索引 + * @param dec 减速度值 + * @return 0:成功 其他:失败 + */ static uint8_t WriteStepDec(uint8_t index, uint16_t dec) { WritePump1Reg(index, RTU_PUMP_CMD_DE, dec); } +/** + * 设置泵的步进速度 + * 将百分比速度转换为实际速度值 + * + * @param index 泵索引 + * @param speed 速度百分比(0-100) + * @return 0:成功 其他:失败 + */ static uint8_t WriteStepSpeed(uint8_t index, uint16_t speed) { // 目标速度转换为实际速度 speed = (uint16_t)(speed * dp.pump[index].maxSpeed / 100); WritePump1Reg(index, RTU_PUMP_CMD_VE, speed); } +/** + * 设置泵的步进目标位置 + * + * @param index 泵索引 + * @param target 目标位置值 + * @return 0:成功 其他:失败 + */ static uint8_t WriteStepTarget(uint8_t index, uint32_t target) { WritePump2Reg(index, RTU_PUMP_CMD_DI, target); } -// FL=feed length -// 写入命令操作码寄存器(40125)数据0x0066(FL),即执行相对位置控制 +/** + * 执行相对位置控制 + * 写入FL(feed length)命令到操作码寄存器 + * + * @param index 泵索引 + * @return 0:成功 其他:失败 + */ static uint8_t RelativePositionControl(uint8_t index) { WritePump1Reg(index, RTU_PUMP_CMD_CO, 0x0066); } -// FP=feed position -// 写入命令操作码寄存器(40125)数据0x0067(FP),即执行绝对位置控制 +/** + * 执行绝对位置控制 + * 写入FP(feed position)命令到操作码寄存器 + * + * @param index 泵索引 + * @return 0:成功 其他:失败 + */ static uint8_t AbsolutePositionControl(uint8_t index) { WritePump1Reg(index, RTU_PUMP_CMD_CO, 0x0067); } -// SK=Stop Move & Kill Buffer, Max Decel -// 写入命令操作码寄存器(40125)数据0x00E1(SK),即执行停止控制 +/** + * 停止泵运行 + * 写入SK(Stop & Kill)命令到操作码寄存器 + * + * @param index 泵索引 + * @return 0:成功 其他:失败 + */ static uint8_t StopPump(uint8_t index) { WritePump1Reg(index, RTU_PUMP_CMD_CO, 0x00E1); } -// 获取固件版本 +/** + * 读取泵的硬件版本 + * + * @param index 泵索引 + * @return 0:成功 其他:失败 + */ uint8_t ReadHWReg(uint8_t index) { ReadPump1Reg(index, RTU_PUMP_CMD_HW); } -// 设置波特率 +/** + * 设置泵的通信波特率 + * + * @param index 泵索引 + * @param br 波特率值 + * @return 0:成功 其他:失败 + */ uint8_t WriteBRReg(uint8_t index, uint16_t br) { WritePump1Reg(index, RTU_PUMP_CMD_BR, br); } -// 设置通信协议 +/** + * 设置泵的通信协议 + * + * @param index 泵索引 + * @param pr 协议类型值 + * @return 0:成功 其他:失败 + */ uint8_t WritePRReg(uint8_t index, uint16_t pr) { WritePump1Reg(index, RTU_PUMP_CMD_PR, pr); } -// 获取泵状态 +/** + * 读取泵的运行状态 + * + * @param index 泵索引 + */ void ReadPumpStatus(uint8_t index) { ReadPump1Reg(index, RTU_PUMP_CMD_SC); } -// 获取泵告警信息 +/** + * 读取泵的告警信息 + * + * @param index 泵索引 + */ void ReadPumpAlarm(uint8_t index) { ReadPump1Reg(index, RTU_PUMP_CMD_AL); } -// 解码告警信息 +/** + * 解码泵的告警信息 + * + * @param reg4001 告警寄存器值 + */ void DecodePumpAlarmMsg(uint16_t reg4001) { static AlarmCode_t alarmCode = {0}; // 与上次告警信息相同,则不更新,仅打印一次 @@ -383,7 +535,11 @@ void DecodePumpAlarmMsg(uint16_t reg4001) { return 1; } -// 解码状态信息 +/** + * 解码泵的状态信息 + * + * @param reg4002 状态寄存器值 + */ void DecodePumpStatusMsg(uint16_t reg4002) { static StatusCode_t statusCode = {0}; // 与上次状态信息相同,则不更新,仅打印一次 @@ -446,50 +602,158 @@ void (*writeValve2Reg)(uint8_t index, uint16_t reg, uint32_t value) = WritePump2 void (*readValve1Reg)(uint8_t index, uint16_t reg) = ReadPump1Reg; void (*readValve2Reg)(uint8_t index, uint16_t reg) = ReadPump2Reg; +/** + * 设置阀门通信模式 + * + * @param index 阀门索引 + * @param mode 通信模式(如CIA402模式) + * @return 0:成功 其他:失败 + */ static uint8_t SetValveCOMMMode(uint8_t index, uint16_t mode) { WritePump1Reg(index, RTU_VALVE_CMD_CTL_MODE, mode); } + +/** + * 设置阀门运行模式 + * + * @param index 阀门索引 + * @param mode 运行模式(如原点回归模式HM、轮廓位置模式PP) + * @return 0:成功 其他:失败 + */ static uint8_t SetValveRunMode(uint8_t index, uint16_t mode) { WritePump1Reg(index, RTU_VALVE_CMD_RUN_MODE, mode); } // PP=轮廓位置模式 +/** + * 设置阀门轮廓位置 + * + * @param index 阀门索引 + * @param pos 目标位置(用户单位) + * @return 0:成功 其他:失败 + */ static uint8_t SetValvePPPos(uint8_t index, uint32_t pos) { writeValve2Reg(index, RTU_VALVE_CMD_PP_POS, pos); } + +/** + * 设置阀门轮廓速度 + * + * @param index 阀门索引 + * @param speed 运行速度(用户单位/s) + * @return 0:成功 其他:失败 + */ static uint8_t SetValvePPSpeed(uint8_t index, uint32_t speed) { writeValve2Reg(index, RTU_VALVE_CMD_PP_SPEED, speed); } + +/** + * 设置阀门轮廓加速度 + * + * @param index 阀门索引 + * @param acc 加速度值(用户单位/s²) + * @return 0:成功 其他:失败 + */ static uint8_t SetValvePPAcc(uint8_t index, uint32_t acc) { writeValve2Reg(index, RTU_VALVE_CMD_PP_ACCEL, acc); } + +/** + * 设置阀门轮廓减速度 + * + * @param index 阀门索引 + * @param dec 减速度值(用户单位/s²) + * @return 0:成功 其他:失败 + */ static uint8_t SetValvePPDec(uint8_t index, uint32_t dec) { writeValve2Reg(index, RTU_VALVE_CMD_PP_DECEL, dec); } // HM=原点回归模式 +/** + * 设置阀门原点检测模式 + * + * @param index 阀门索引 + * @param mode 检测模式(如负限位、正限位) + * @return 0:成功 其他:失败 + */ static uint8_t SetValveHomeDetectMode(uint8_t index, uint16_t mode) { writeValve1Reg(index, RTU_VALVE_CMD_HOME_MODE, mode); } + +/** + * 设置阀门寻找限位开关速度 + * + * @param index 阀门索引 + * @param speed 寻找速度值 + * @return 0:成功 其他:失败 + */ static uint8_t SetValveHomeSwtSpeed(uint8_t index, uint32_t speed) { writeValve2Reg(index, RTU_VALVE_CMD_HOME_SWT_SPEED, speed); } + +/** + * 设置阀门寻找原点信号速度 + * + * @param index 阀门索引 + * @param speed 寻找速度值 + * @return 0:成功 其他:失败 + */ static uint8_t SetValveHomeOriSpeed(uint8_t index, uint32_t speed) { writeValve2Reg(index, RTU_VALVE_CMD_HOME_ORI_SPEED, speed); } + +/** + * 设置阀门回零加速度 + * + * @param index 阀门索引 + * @param acc 加速度值 + * @return 0:成功 其他:失败 + */ static uint8_t SetValveHomeAcc(uint8_t index, uint32_t acc) { writeValve2Reg(index, RTU_VALVE_CMD_HOME_ACCEL, acc); } + +/** + * 设置阀门功能控制字 + * + * @param index 阀门索引 + * @param func 功能控制字(如准备、使能、运行等) + * @return 0:成功 其他:失败 + */ static uint8_t SetValveFunc(uint8_t index, uint16_t func) { writeValve1Reg(index, RTU_VALVE_CMD_FUNC, func); } + +/** + * 设置阀门原点回归堵转检测力矩 + * + * @param index 阀门索引 + * @param torque 力矩值 + * @return 0:成功 其他:失败 + */ static uint8_t SetValveHomeTorque(uint8_t index, uint16_t torque) { writeValve1Reg(index, RTU_VALVE_CMD_HOME_TORQUE, torque); } + +/** + * 设置阀门原点回归堵转检测时间 + * + * @param index 阀门索引 + * @param time 检测时间(ms) + * @return 0:成功 其他:失败 + */ static uint8_t SetValveHomeTime(uint8_t index, uint16_t time) { writeValve1Reg(index, RTU_VALVE_CMD_HOME_TIME, time); } +/** + * 阀门回归原点控制 + * 包含设置原点回归方式、堵转检测、运行模式等配置 + * + * @param index 阀门索引 + * @return 0:成功 其他:失败 + */ uint8_t ValveBackToOrigin(uint8_t index) { // 1.设置原点回归方式 // (0416h)=37;17=负限位,18=正限位 @@ -514,6 +778,13 @@ uint8_t ValveBackToOrigin(uint8_t index) { SetValveFunc(index, RTU_VALVE_CFG_RUN_ORIGIN); } +/** + * 阀门运行初始化 + * 配置通信模式、运行模式、速度和加减速等参数 + * + * @param index 阀门索引 + * @return 0:成功 其他:失败 + */ uint8_t ValveRunInit(uint8_t index) { // 1.配置模式: // 00B1h=0、运行模式 03C2h=0x01,使设备工作在轮廓位置模式; @@ -532,6 +803,13 @@ uint8_t ValveRunInit(uint8_t index) { SetValveFunc(index, RTU_VALVE_CFG_ENABLE); } +/** + * 控制阀门运行到指定角度 + * + * @param index 阀门索引 + * @param angle 目标角度(0/120/210) + * @return 0:成功 其他:失败 + */ uint8_t ValveRunToAngle(uint8_t index, uint32_t angle) { // 限制角度为0,120,210 if(angle != 0 && angle != 120 && angle != 210) { @@ -547,6 +825,12 @@ uint8_t ValveRunToAngle(uint8_t index, uint32_t angle) { SetValveFunc(index, 0x3F); } +/** + * 初始化阀门参数 + * 设置最大速度、加速度和减速度 + * + * @return 0:成功 其他:失败 + */ uint8_t InitValve(void) { SetValvePPSpeed(dp.valve[0].id, dp.valve[0].maxSpeed); SetValvePPAcc(dp.valve[0].id, dp.valve[0].maxAccel); @@ -557,9 +841,10 @@ uint8_t InitValve(void) { SetValvePPDec(dp.valve[1].id, dp.valve[1].maxDecel); } -// 定时1s更新设备状态 -// 活度计通过网口获取 -// 下挂设备通过485获取 +/** + * 定时更新泵的状态 + * 读取泵的运行状态和告警信息 + */ void UpdatePumpStatus() { // 更新设备状态 ReadPumpStatus(0); @@ -568,6 +853,12 @@ void UpdatePumpStatus() { ReadPumpAlarm(1); } +/** + * 初始化泵参数 + * 设置最大速度、加速度和减速度 + * + * @return 0:成功 其他:失败 + */ uint8_t InitPump(void) { // 初始化泵 log_e("InitPump"); @@ -585,7 +876,11 @@ uint8_t InitPump(void) { WriteStepDec(dp.pump[1].id, dp.pump[1].maxDecel); WriteStepSpeed(dp.pump[1].id, dp.pump[1].maxSpeed); } -// 初始化设备状态 + +/** + * 初始化设备状态 + * 设置设备在线状态、阀门角度、泵运行状态等 + */ void InitDeviceStatus() { // 初始化泵 @@ -602,6 +897,7 @@ void InitDeviceStatus() { updateEmergencyStop(ESTOP_NORMAL); updateInitStatus(INIT_SUCCESS); } + // 初始化处理 static uint8_t HandleInit(void) { // 实现初始化逻辑 @@ -611,15 +907,27 @@ static uint8_t HandleInit(void) { // 状态查询处理 +/** + * 处理状态查询命令 + * + * @return 0:成功 其他:失败 + */ static uint8_t HandleStatusQuery(void) { // 填充并返回数据 uint8_t txBuf[sizeof(DeviceStatus)] = {0}; memcpy(txBuf, &deviceStatus, sizeof(DeviceStatus)); - SendToHost(txBuf, sizeof(txBuf)); + // sendMsgToHost(txBuf, sizeof(txBuf)); return 0; } // 三通阀控制处理 +/** + * 处理三通阀控制命令 + * + * @param Buff 接收到的数据缓冲区 + * @param len 接收到的数据长度 + * @return 0:成功 其他:失败 + */ static uint8_t HandleValveControl(uint8_t *Buff, uint8_t len) { // 实现三通阀控制逻辑 @@ -648,17 +956,31 @@ static uint8_t HandleValveControl(uint8_t *Buff, uint8_t len) { } // 泵时长控制处理 +/** + * 处理泵时长控制命令 + * + * @param Buff 接收到的数据缓冲区 + * @param len 接收到的数据长度 + * @return 0:成功 其他:失败 + */ static uint8_t HandlePumpTimeControl(uint8_t *Buff, uint8_t len) { // 实现泵时长控制逻辑 - // 使用定时器更靠谱 + // 使用步数方式更靠谱,通过时间和速度计算步数,结束时不用发送停止命令 return 1; } // 泵速度设置处理 +/** + * 处理泵速度设置命令 + * + * @param Buff 接收到的数据缓冲区 + * @param len 接收到的数据长度 + * @return 0:成功 其他:失败 + */ static uint8_t HandlePumpSpeedControl(uint8_t *Buff, uint8_t len) { - // 实现泵速度设置逻辑 + // 实现速度设置逻辑 if(len != 4) { log_e("泵速度设置错误"); return 0; @@ -682,6 +1004,14 @@ static uint8_t HandlePumpSpeedControl(uint8_t *Buff, uint8_t len) { return 1; } +// 泵步进控制处理 +/** + * 处理泵步进控制命令 + * + * @param Buff 接收到的数据缓冲区 + * @param len 接收到的数据长度 + * @return 0:成功 其他:失败 + */ static uint8_t HandlePumpStepControl(uint8_t *Buff, uint8_t len) { if(len != 10) { log_e("泵步进设置错误"); @@ -694,7 +1024,13 @@ static uint8_t HandlePumpStepControl(uint8_t *Buff, uint8_t len) { return 0; } -// 软急停功能处理 +/** + * 处理软急停命令 + * + * @param rxBuf 接收到的数据缓冲区 + * @param rxLen 接收到的数据长度 + * @return 0:成功 1:失败 + */ static uint8_t HandleSoftStop(uint8_t *rxBuf, uint16_t rxLen) { if(rxLen != 1) { log_e("软急停设置错误"); @@ -715,14 +1051,25 @@ static uint8_t HandleSoftStop(uint8_t *rxBuf, uint16_t rxLen) { } return 0; } + +/** + * 处理电机相关消息 + * + * @param rxBuf 接收到的数据缓冲区 + * @param rxLen 接收到的数据长度 + */ void ProcessMotorMsg(uint8_t *rxBuf, uint16_t rxLen) { // 实现电机消息处理逻辑 log_d("ProcessMotorMsg"); } -void sendMsgToHost(uint8_t *txBuf, uint16_t txLen) { - // 发送数据 - HAL_UART_Transmit_DMA(&huart2, txBuf, txLen); -} + +/** + * 将消息打包并发送给上位机 + * 帧格式:帧头+功能码(2Byte)+数据长度(1Byte)+具体数据(NByte)+CRC16校验位+帧尾 + * + * @param funcCode 功能码 + * @param isOK 执行结果 + */ void packMsgToHost(uint16_t funcCode, uint8_t isOK) { // 实现打包消息到上位机逻辑 // 帧头+功能码(2Byte)+数据长度(1Byte)+ 具体数据(NByte)+CRC16校验位+帧尾 @@ -763,9 +1110,16 @@ void packMsgToHost(uint16_t funcCode, uint8_t isOK) { sendMsgToHost(msgBuf, len); } +/** + * 检查接收到的命令帧格式是否正确 + * + * @param rxBuf 接收到的数据缓冲区 + * @param rxLen 接收到的数据长度 + * @return 命令帧错误码 + */ CmdFrameError_t checkHostCmd(uint8_t *rxBuf, uint16_t rxLen) { // 检查命令是否正确 - // FRAME_HEADER是按小端序存储的,而rxBuf是按大端序存储的 + // FRAME_HEADER是按小端序存储的,而rxBuf是按大端序存的 uint32_t header; FillBigEndian32(&header, FRAME_HEADER); uint32_t tail; @@ -789,9 +1143,14 @@ CmdFrameError_t checkHostCmd(uint8_t *rxBuf, uint16_t rxLen) { } -// 上位机命令处理函数,采用的自定协议,非modbus协议 -// rxBuf: 接收到的数据 -// rxLen: 接收到的数据长度 +/** + * 处理上位机发送的命令 + * 采用自定义协议,非modbus协议 + * + * @param rxBuf 接收到的数据缓冲区 + * @param rxLen 接收到的数据长度 + * @return 命令帧错误码 + */ CmdFrameError_t ProcessHostCommand(uint8_t *rxBuf, uint16_t rxLen) { CmdFrameError_t error = checkHostCmd(rxBuf, rxLen);