update function

This commit is contained in:
CSSC-WORK\murmur 2024-12-11 10:32:35 +08:00
parent 375412545f
commit a71606de2e
2 changed files with 318 additions and 106 deletions

View File

@ -117,56 +117,13 @@ void InitDeviceStatus() {
updateInitStatus(INIT_SUCCESS);
}
// 定时1s更新设备状态
// 活度计通过网口获取
// 下挂设备通过485获取
void UpdateDeviceStatus() {
// 更新设备状态
}
// 状态查询处理
static uint8_t HandleStatusQuery(uint8_t *txBuf) {
// 填充并返回数据
memcpy(txBuf, &deviceStatus, sizeof(DeviceStatus));
return sizeof(DeviceStatus);
}
//modBUS RTU 写命令
void writeCMD(uint8_t *txBuf, uint16_t *txLen) {
}
// 三通阀控制处理
static uint8_t HandleValveControl(uint8_t index, ValveAngle_t angle) {
// 实现三通阀控制逻辑
updateValveStatus(index, angle);
return 1;
}
// 泵时长控制处理
static uint8_t HandlePumpTimeControl(uint8_t *rxBuf, uint8_t *txBuf, uint16_t *txLen) {
// 实现泵时长控制逻辑
*txLen = 1;
return 1;
}
// 泵速度设置处理
static uint8_t HandlePumpSpeedControl(uint8_t *rxBuf, uint8_t *txBuf, uint16_t *txLen) {
// 实现泵速度设置逻辑
*txLen = 1;
return 1;
}
// 软急停功能处理
static uint8_t HandleSoftStop(uint8_t *rxBuf, uint8_t *txBuf, uint16_t *txLen) {
// 实现软急停功能逻辑
*txLen = 1;
return 1;
}
// 判断系统大端序还是小端序
static uint8_t IsBigEndian() {
@ -200,7 +157,7 @@ static void FillBigEndian16(uint8_t *data, uint16_t value) {
}
// 泵加速、减速处理
static uint8_t HandlePumpAccDec(uint8_t index, uint8_t acc, uint8_t dec) {
static uint8_t WritePumpAccDec(uint8_t index, uint8_t acc, uint8_t dec) {
// 实现泵加速、减速逻辑
RTU_Frame frame;
@ -225,7 +182,7 @@ static uint8_t HandlePumpAccDec(uint8_t index, uint8_t acc, uint8_t dec) {
}
// 泵速度设置处理
static uint8_t HandlePumpSpeed(uint8_t index, uint8_t speed) {
static uint8_t WritePumpSpeed(uint8_t index, uint8_t speed) {
// 实现泵速度设置逻辑
RTU_Frame frame;
@ -247,7 +204,7 @@ static uint8_t HandlePumpSpeed(uint8_t index, uint8_t speed) {
}
// 泵步进设置处理
static uint8_t HandlePumpStep(uint8_t index, int32_t step) {
static uint8_t WritePumpStep(uint8_t index, int32_t step) {
// 实现泵步进设置逻辑
RTU_Frame frame;
@ -279,48 +236,274 @@ static uint8_t HandlePumpStep(uint8_t index, int32_t step) {
return 1;
}
// 初始化处理
static uint8_t HandleInit(uint8_t *rxBuf, uint8_t *txBuf, uint16_t *txLen) {
// 实现初始化逻辑
*txLen = 1;
// pump 读寄存器
uint16_t ReadPump1Reg(uint8_t index, uint16_t reg) {
// 读取保存寄存器不能直接使用RTU_Frame因为无数据位
uint8_t data[8] = {0};
data[0] = index;
data[1] = RTU_PUMP_FUNC_READ_REG;
FillBigEndian16(&data[2], reg);
FillBigEndian16(&data[4], 1);
uint16_t crc = CalculateCRC16(data, 6);
// 大端序填充
FillBigEndian16(&data[6], crc);
writeCMD(data, 8);
}
// 获取泵状态
void ReadPumpStatus(uint8_t index) {
ReadPump1Reg(index, RTU_PUMP_CMD_SC);
}
// 获取泵告警信息
void ReadPumpAlarm(uint8_t index) {
ReadPump1Reg(index, RTU_PUMP_CMD_AL);
}
// 解码告警信息
void DecodePumpAlarmMsg(uint16_t reg4001) {
static AlarmCode_t alarmCode = {0};
// 与上次告警信息相同,则不更新,仅打印一次
if (alarmCode.all == reg4001)
{
return 0;
}
alarmCode.all = reg4001;
if(alarmCode.all == 0) {
//暂时屏蔽,避免刷屏
// printf("\r\n%s无报警信息\r\n", pumpName[index]);
return 0;
}
// 打印表格头部
printf("\r\n+--------+------------------+\r\n");
printf("| 告警位 | 告警信息 |\r\n");
printf("+--------+------------------+\r\n");
for(uint16_t i = 0; i < 16; i++) {
if(alarmCode.all & (1 << i)) {
printf("| %6d | %-14s |\r\n", i, alarmInfo[i]);
printf("+--------+------------------+\r\n");
}
}
return 1;
}
// 主命令处理函数
uint8_t ProcessCommand(uint8_t *rxBuf, uint16_t rxLen, uint8_t *txBuf, uint16_t *txLen) {
uint16_t cmdCode = (rxBuf[0] << 8) | rxBuf[1];
uint8_t dataLen = rxBuf[2];
uint8_t *data = &rxBuf[3];
uint8_t result = 0;
// 解码状态信息
void DecodePumpStatusMsg(uint16_t reg4002) {
static StatusCode_t statusCode = {0};
// 与上次状态信息相同,则不更新,仅打印一次
if (statusCode.all == reg4002)
{
return 1;
}
statusCode.all = reg4002;
printf("\r\n+--------+------------------+\r\n");
printf("| 状态位 | 状态信息 |\r\n");
printf("+--------+------------------+\r\n");
for(uint16_t i = 0; i < 16; i++) {
if(statusCode.all & (1 << i)) {
printf("| %6d | %-14s |\r\n", i, statusInfo[i]);
printf("+--------+------------------+\r\n");
}
}
return 0;
}
// 定时1s更新设备状态
// 活度计通过网口获取
// 下挂设备通过485获取
void UpdatePumpStatus() {
// 更新设备状态
ReadPumpStatus(0);
ReadPumpStatus(1);
ReadPumpAlarm(0);
ReadPumpAlarm(1);
}
// 初始化处理
static uint8_t HandleInit(uint8_t *rxBuf, uint8_t *txBuf, uint16_t *txLen) {
// 实现初始化逻辑
InitDeviceStatus();
return 1;
}
// 状态查询处理
static uint8_t HandleStatusQuery(uint8_t *txBuf) {
// 填充并返回数据
memcpy(txBuf, &deviceStatus, sizeof(DeviceStatus));
return sizeof(DeviceStatus);
}
// 三通阀控制处理
static uint8_t HandleValveControl(uint8_t *Buff, uint8_t len) {
// 实现三通阀控制逻辑
if(len != 8) {
printf("三通阀控制错误\r\n");
return 0;
}
uint8_t index = Buff[0];
uint8_t direction = Buff[1];
uint16_t angle = (Buff[2]<<8) | Buff[3];
if(angle > 360) {
printf("三通阀控制错误\r\n");
return 1;
}
if (angle != VALVE_ANGLE_120 && angle != VALVE_ANGLE_210) {
printf("三通阀控制错误\r\n");
return 1;
}
// 具体实现
// 更新三通阀状态
updateValveStatus(index, angle);
return 0;
}
// 泵时长控制处理
static uint8_t HandlePumpTimeControl(uint8_t *Buff, uint8_t len) {
// 实现泵时长控制逻辑
// 暂未知控制方法,是直接设置泵运行时间,还是设置泵运行步数
return 1;
}
// 泵速度设置处理
static uint8_t HandlePumpSpeedControl(uint8_t *Buff, uint8_t len) {
// 实现泵速度设置逻辑
if(len != 4) {
printf("泵速度设置错误\r\n");
return 0;
}
uint8_t index = Buff[0];
uint8_t speed = Buff[1];
if (speed > 100) {
printf("泵速度设置错误\r\n");
return 0;
}
WritePumpSpeed(index, speed);
index = Buff[2];
speed = Buff[3];
if (speed > 100) {
printf("泵速度设置错误\r\n");
return 0;
}
WritePumpSpeed(index, speed);
return 1;
}
static uint8_t HandlePumpStepControl(uint8_t *Buff, uint8_t len) {
if(len != 10) {
printf("泵步进设置错误\r\n");
return 0;
}
uint8_t index = Buff[0];
int32_t step = (Buff[1]<<24) | (Buff[2]<<16) | (Buff[3]<<8) | Buff[4];
WritePumpStep(index, step);
index = Buff[5];
step = (Buff[6]<<24) | (Buff[7]<<16) | (Buff[8]<<8) | Buff[9];
WritePumpStep(index, step);
return 1;
}
// 软急停功能处理
static uint8_t HandleSoftStop(uint8_t *rxBuf, uint16_t rxLen) {
if(rxLen != 1) {
printf("软急停设置错误\r\n");
return 1;
}
// 实现软急停功能逻辑
if(rxBuf[0] == 0) {
// 正常状态
updateEmergencyStop(ESTOP_NORMAL);
}
else {
// 急停状态
updateEmergencyStop(ESTOP_PRESSED);
}
return 0;
}
CmdFrameError_t checkHostCmd(uint8_t *rxBuf, uint16_t rxLen) {
// 检查命令是否正确
if (memcmp(rxBuf, FRAME_HEADER, 4) != 0)
{
return CMD_FRAME_HEADER_ERROR;
}
if (memcmp(rxBuf + rxLen - 4, FRAME_TAIL, 4) != 0)
{
return CMD_FRAME_TAIL_ERROR;
}
uint16_t crc = CalculateCRC16(rxBuf+4, rxLen - 8);// 计算crc不包含帧头和帧尾
if (memcmp(rxBuf + rxLen - 4, &crc, 2) != 0)
{
return CMD_FRAME_CHECK_ERROR;
}
return CMD_FRAME_OK;
}
// 上位机命令处理函数采用的自定协议非modbus协议
// rxBuf: 接收到的数据
// rxLen: 接收到的数据长度
CmdFrameError_t ProcessHostCommand(uint8_t *rxBuf, uint16_t rxLen) {
CmdFrameError_t error = checkHostCmd(rxBuf, rxLen);
if (error != CMD_FRAME_OK)
{
return error;
}
uint16_t cmdCode = (rxBuf[sizeof(FRAME_HEADER)] << 8) | rxBuf[sizeof(FRAME_HEADER)+1];//提取命令码
uint8_t dataLen = rxBuf[sizeof(FRAME_HEADER)+2];//提取数据长度
uint8_t *data = &rxBuf[sizeof(FRAME_HEADER)+3];//提取数据
switch(cmdCode) {
case CMD_STATUS_QUERY:
result = HandleStatusQuery(data, txBuf, txLen);
error = HandleStatusQuery(data, dataLen);
break;
case CMD_VALVE_CTRL:
result = HandleValveControl(data, txBuf, txLen);
error = HandleValveControl(data, dataLen);
break;
case CMD_PUMP_RUN_TIME:
result = HandlePumpTimeControl(data, txBuf, txLen);
error = HandlePumpTimeControl(data, dataLen);
break;
case CMD_PUMP_RUN_SPEED:
result = HandlePumpSpeedControl(data, txBuf, txLen);
error = HandlePumpSpeedControl(data, dataLen);
break;
case CMD_SOFT_STOP:
result = HandleSoftStop(data, txBuf, txLen);
error = HandleSoftStop(data, dataLen);
break;
case CMD_PUMP_RUN_STEP:
result = HandlePumpStep(data, txBuf, txLen);
error = HandlePumpStep(data, dataLen);
break;
case CMD_SYSTEM_INIT:
result = HandleInit(data, txBuf, txLen);
error = HandleInit(data, dataLen);
break;
default:
*txLen = 1;
txBuf[0] = 0;
result = 0;
error = CMD_FRAME_CMD_ERROR;
break;
}
return result;
return error;
}

View File

@ -15,6 +15,15 @@
#define CMD_SOFT_STOP 0x0005 // 软急停功能
#define CMD_PUMP_RUN_STEP 0x0006 // 泵步进设置
#define CMD_SYSTEM_INIT 0x0007 // 系统初始化
// 命令帧错误码定义
typedef enum {
CMD_FRAME_OK = 0,
CMD_FRAME_HEADER_ERROR = -1,
CMD_FRAME_TAIL_ERROR = -2,
CMD_FRAME_CHECK_ERROR = -3,
CMD_FRAME_CMD_ERROR = -4,
} CmdFrameError_t;
// MOONS驱动器支持的Modbus功能码如下
@ -46,26 +55,33 @@
14 Q程序段为空
15
*/
// 使用联合体表示
typedef enum {
ALARM_POSITION_ERROR = 0,
ALARM_CCW_LIMIT = 1,
ALARM_CW_LIMIT = 2,
ALARM_OVER_TEMP = 3,
ALARM_INTERNAL_VOLTAGE_ERROR = 4,
ALARM_OVER_VOLTAGE = 5,
ALARM_UNDER_VOLTAGE = 6,
ALARM_OVER_CURRENT = 7,
ALARM_MOTOR_WINDING_SWITCH = 8,
ALARM_MOTOR_ENCODER_ERROR = 9,
ALARM_COMMUNICATION_ERROR = 10,
ALARM_PARAMETER_SAVE_FAILED = 11,
ALARM_MOTOR_UNDER_LOAD = 13,
ALARM_EMPTY_Q_PROGRAM = 14,
ALARM_MEMORY_ERROR = 15,
} AlarmCode_t;
// 告警寄存器联合体定义
typedef union {
struct {
uint16_t position_error:1; // 位0: 位置误差超限
uint16_t ccw_limit:1; // 位1: CCW方向禁止限位
uint16_t cw_limit:1; // 位2: CW方向禁止限位
uint16_t over_temp:1; // 位3: 驱动器过温
uint16_t voltage_error:1; // 位4: 驱动器内部电压错误
uint16_t over_voltage:1; // 位5: 驱动器过压
uint16_t under_voltage:1; // 位6: 驱动器欠压
uint16_t over_current:1; // 位7: 驱动器过流
uint16_t winding_switch:1; // 位8: 电机绕组开关
uint16_t encoder_error:1; // 位9: 电机编码器信号错误
uint16_t comm_error:1; // 位10: 通讯异常
uint16_t param_save_failed:1; // 位11: 参数保存失败
uint16_t motor_disabled:1; // 位12: 在电机未使能时命令其运转
uint16_t motor_overload:1; // 位13: 电机重载状态
uint16_t empty_q_program:1; // 位14: 调用的Q程序段为空
uint16_t memory_error:1; // 位15: 存储器错误
} bits;
uint16_t all; // 访问完整的16位寄存器
}AlarmCode_t;
const uint8_t armInfo[16][32]={
// 用于输出具体的告警信息字符串
const uint8_t alarmInfo[16][32]={
"位置误差超限",
"CCW方向禁止限位",
"CW方向禁止限位",
@ -109,22 +125,25 @@ const uint8_t armInfo[16][32]={
15
*/
typedef enum {
STATUS_ENABLE = 0,
STATUS_SAMPLE = 1,
STATUS_FAULT = 2,
STATUS_POSITION_REACHED = 3,
STATUS_MOVING = 4,
STATUS_POINT_MOVE = 5,
STATUS_DECELERATING = 6,
STATUS_WAIT_INPUT = 7,
STATUS_PARAMETER_SAVE = 8,
STATUS_ALARM = 9,
STATUS_RETURN_HOME = 10,
STATUS_WAIT_TIME = 11,
STATUS_ENCODER_CHECK = 13,
STATUS_Q_PROGRAM_RUN = 14,
STATUS_INIT = 15,
typedef union {
struct {
uint16_t enable:1; // 位0: 使能
uint16_t sample:1; // 位1: 采样中(软件示波器功能开启)
uint16_t fault:1; // 位2: 驱动器报故障
uint16_t position_reached:1; // 位3: 运动到位
uint16_t moving:1; // 位4: 运动中
uint16_t point_move:1; // 位5: 点动运行中
uint16_t decelerating:1; // 位6: 减速中
uint16_t wait_input:1; // 位7: 等待输入信号例如执行WI指令
uint16_t parameter_save:1; // 位8: 参数保存中
uint16_t alarm:1; // 位9: 驱动器报警告
uint16_t return_home:1; // 位10: 回原点中
uint16_t wait_time:1; // 位11: 等待时间例如执行WT、WD指令
uint16_t encoder_check:1; // 位12: 编码器检测中
uint16_t q_program_run:1; // 位13: Q程序运行中
uint16_t init:1; // 位14: 初始化(步进系),伺服准备好(伺服系)
} bits;
uint16_t all;
} StatusCode_t;
const uint8_t statusInfo[16][32]={
"使能",
@ -170,6 +189,8 @@ const uint8_t statusInfo[16][32]={
#define RTU_PUMP_CMD_VE 0x001D // 速度
#define RTU_PUMP_CMD_DI 0x001E // 目标位置
#define RTU_PUMP_CMD_SC 0x4002 // 状态寄存器
#define RTU_PUMP_CMD_AL 0x4001 // 告警寄存器
// 错误码定义
typedef enum {
@ -249,6 +270,11 @@ typedef struct {
} DeviceStatus;
static uint8_t pumpName[2][10] = {
"Pump1",
"Pump2"
};
// 定义协议消息结构
typedef struct {
uint8_t device_id;
@ -256,13 +282,16 @@ typedef struct {
uint8_t reg_addr[2];
uint8_t reg_cnt[2];
uint8_t data_cnt;
uint8_t data[0];//柔性数组大小由data_cnt决定
uint8_t crc[2];
uint8_t data[];//柔性数组大小由data_cnt决定
// uint8_t crc[2];
} RTU_Frame;
// 函数声明
uint8_t ProcessCommand(uint8_t *rxBuf, uint16_t rxLen, uint8_t *txBuf, uint16_t *txLen);
uint16_t CalculateCRC16(uint8_t *data, uint16_t length);
CmdFrameError_t ProcessHostCommand(uint8_t *rxBuf, uint16_t rxLen);
// uint16_t CalculateCRC16(uint8_t *data, uint16_t length);
void InitDeviceStatus();
void DecodePumpAlarmMsg(uint16_t reg4001);
void DecodePumpStatusMsg(uint16_t reg4002);
void UpdatePumpStatus();
#endif // PROTOCOL_H