injectorCTL/protocol.c
CSSC-WORK\murmur 37f4581ebb init version
2024-12-10 20:01:16 +08:00

276 lines
8.2 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "protocol.h"
#include <string.h>
static DeviceStatus deviceStatus = {0};
// CRC16 查表法实现
static const uint16_t crcTable[] = {
0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241,
0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440,
0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40,
0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841,
0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40,
0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41,
0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641,
0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040,
0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240,
0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441,
0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41,
0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840,
0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41,
0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40,
0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640,
0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041,
0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240,
0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441,
0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41,
0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840,
0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41,
0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40,
0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640,
0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041,
0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241,
0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440,
0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40,
0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841,
0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40,
0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41,
0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641,
0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040
};
uint16_t CalculateCRC16(uint8_t *data, uint16_t length) {
uint16_t crc = 0xFFFF;
for (uint16_t i = 0; i < length; i++) {
uint8_t index = (crc ^ data[i]) & 0xFF;
crc = (crc >> 8) ^ crcTable[index];
}
return crc;
}
// 更新下挂设备状态
void updateDeviceStatus(DeviceStatus_t status) {
deviceStatus.deviceStatus = status;
}
// 更新三通阀状态
void updateValveStatus(uint8_t index, ValveAngle_t angle) {
if (index == 1) {
deviceStatus.valves.angle1 = angle;
} else if (index == 2) {
deviceStatus.valves.angle2 = angle;
}
}
// 更新泵状态
void updatePumpStatus(uint8_t index, PumpStatus_t status) {
if (index == 1) {
deviceStatus.pumps.status1 = status;
} else if (index == 2) {
deviceStatus.pumps.status2 = status;
}
}
// 更新泵速度状态
void updatePumpSpeedStatus(uint8_t index, uint8_t speed) {
if (index == 1) {
deviceStatus.pumps.speed1 = speed;
} else if (index == 2) {
deviceStatus.pumps.speed2 = speed;
}
}
// 更新气泡传感器读数
void updateBubbleSensor(BubbleStatus_t value) {
deviceStatus.bubbleStatus = value;
}
// 更新急停状态
void updateEmergencyStop(EstopStatus_t status) {
deviceStatus.stopStatus = status;
}
// 更新错误码
void updateErrorCode(ErrorCode_t errorCode) {
deviceStatus.errorCode = errorCode;
}
// 更新初始化状态
void updateInitStatus(InitStatus_t status) {
deviceStatus.initStatus = status;
}
// 初始化设备状态
void InitDeviceStatus() {
// 更新设备状态
updateDeviceStatus(DEVICE_ONLINE);
updateValveStatus(1, 120);
updateValveStatus(2, 210);
updatePumpStatus(1, PUMP_CLOCKWISE);
updatePumpStatus(2, PUMP_ANTICLOCKWISE);
updatePumpSpeedStatus(1, 100);
updatePumpSpeedStatus(2, 100);
updateBubbleSensor(BUBBLE_DETECTED);
updateEmergencyStop(ESTOP_NORMAL);
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() {
uint32_t num = 0x12345678;
return ((*(uint8_t*)&num) == 0x12);
}
// 将数据按大端序填充
static void FillBigEndian32(uint8_t *data, uint16_t len, uint32_t value) {
if(!IsBigEndian()) {
for(uint16_t i = 0; i < len; i++) {
data[i] = (value >> ((len - i - 1) * 8)) & 0xFF;
}
}
}
static void FillBigEndian16(uint8_t *data, uint16_t len, uint16_t value) {
if(!IsBigEndian()) {
for(uint16_t i = 0; i < len; i++) {
data[i] = (value >> ((len - i - 1) * 8)) & 0xFF;
}
}
}
// 泵步进设置处理
static uint8_t HandlePumpStep(uint8_t index, int32_t step) {
// 实现泵步进设置逻辑
RTU_Frame frame;
frame.data_cnt = 2;
uint8_t len = sizeof(RTU_Frame)+frame.data_cnt*sizeof(uint8_t);
frame.device_id = 1;
frame.func = RTU_PUMP_FUNC_WRITE_REG;
frame.reg_addr[0] = RTU_PUMP_CMD_DI>>8;
frame.reg_addr[1] = RTU_PUMP_CMD_DI&0xFF;
frame.reg_cnt[0] = 0;
frame.reg_cnt[1] = 2;
// step为int32正负表示方向绝对值表示步数
if(step > 0) {
frame.data[0] = step>>24;
frame.data[1] = step>>16;
frame.data[2] = step>>8;
frame.data[3] = step;
} else {
frame.data[0] = 0;
frame.data[1] = 0;
frame.data[2] = 0;
frame.data[3] = 0;
}
uint16_t crc = CalculateCRC16(&frame.func, len -sizeof(frame.device_id)-sizeof(frame.crc));
// 大端序填充
frame.crc[0] = (crc >> 8) & 0xFF;
frame.crc[1] = crc & 0xFF;
writeCMD(&frame, len);
return 1;
}
// 初始化处理
static uint8_t HandleInit(uint8_t *rxBuf, uint8_t *txBuf, uint16_t *txLen) {
// 实现初始化逻辑
*txLen = 1;
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;
switch(cmdCode) {
case CMD_STATUS_QUERY:
result = HandleStatusQuery(data, txBuf, txLen);
break;
case CMD_VALVE_CTRL:
result = HandleValveControl(data, txBuf, txLen);
break;
case CMD_PUMP_RUN_TIME:
result = HandlePumpTimeControl(data, txBuf, txLen);
break;
case CMD_PUMP_RUN_SPEED:
result = HandlePumpSpeedControl(data, txBuf, txLen);
break;
case CMD_SOFT_STOP:
result = HandleSoftStop(data, txBuf, txLen);
break;
case CMD_PUMP_RUN_STEP:
result = HandlePumpStep(data, txBuf, txLen);
break;
case CMD_SYSTEM_INIT:
result = HandleInit(data, txBuf, txLen);
break;
default:
*txLen = 1;
txBuf[0] = 0;
result = 0;
break;
}
return result;
}