#include "bl_usart.h" #include "parameter.h" #include "chargControlTypes.h" #include "configParameter.h" #include "string.h" #include "pDebug.h" #include "bl_chargControl.h" #include "interruptSend.h" #include "inFlash.h" #include "SOE.h" /* 状态机 */ typedef enum { wait = 0, /* 串口状态机初始状态 */ startFlagSL, /* 接收到SL帧头 */ addressSL, /* 接收到设备地址 */ functionCodeSL, /* 接收到SL功能码 */ readRegStartAddressSL, /* 接收到SL读取寄存器起始地址 */ readRegStartNumberSL, /* 接收到SL读取寄存器个数 */ crcCheckBitSL, /* 接收到SL校验位 */ endFlagSL, /* 接收到SL帧尾 */ writeRegStartAddressSL, /* 接收到SL写入寄存器起始地址 */ writeRegStartNumberSL, /* 接收到SL写入寄存器个数 */ regLengthSL, /* 接收到SL寄存器长度 */ regStatusSL, /* 接收到SL寄存器状态 */ cfgFramesNumSL, /* 接收到SL配置文件帧数 */ cfgLengthSL, /* 接收到SL配置文件长度 */ readCfgLengthSL, /* 接收到SL读取配置文件长度 */ readSOEStartAddr, /* 接收到SOE起始读取位 */ readSOELength, /* 接收到SOE读取长度 */ } uartStateMachine; /* 功能码 */ typedef enum { SL_Function_Code_Read_Register = 0x30, /* 读寄存器数据 */ SL_Function_Code_Write_Register = 0x10, /* 写寄存器数据 */ SL_Function_Code_Broadcast_Scan = 0xA0, /* 广播扫描 */ SL_Function_Code_Registration_request = 0xA1, /* 注册请求 */ SL_Function_Code_Distribution_Profile = 0xD0, /* 配置文件下发 */ SL_Function_Code_Read_Profile = 0xD1, /* 配置文件读取 */ SL_Function_Code_Read_SOE = 0x05, /* 读取SOE */ }SL_MsgFunctionCode; /* 寄存器地址 */ typedef enum { SL_Register_Registration_Status = 0x0000, /* 注册状态 */ SL_Register_address = 0x0001, /* 地址 */ SL_Register_Access_Node_Type = 0x0002, /* 接入节点类型 */ SL_Register_Communication_Methods = 0x0003, /* 通信方式 */ SL_Register_Solar_Open_Circuit_Voltage = 0x0100, /* 太阳能开路电压 */ SL_Register_Solar_Input_Voltage = 0x0101, /* 太阳能输入电压 */ SL_Register_Output_Voltage = 0x0102, /* 电池电压 */ SL_Register_Battery_Voltage = 0x0103, /* 电池电压 */ SL_Register_Charg_Current = 0x0104, /* 充电电流(流向电池+负载) */ SL_Register_Discharg_Current = 0x0105, /* 放电电流(流向负载) */ SL_Register_HighSideMos_Temperature = 0x0106, /* 高端mos的温度 */ SL_Register_SOC = 0x0107, /* 剩余电量 */ SL_Register_chargState = 0x0108, /* 充电状态 */ SL_Register_totalChargCapacity = 0x0109, /* 总充电量 */ SL_Register_totalElectricityConsumption = 0x010A, /* 总放电量 */ SL_Register_MPPT_Mode = 0x010B, /* 工作模式 */ SL_Register_eliminateStatistical = 0x010C, /* 消除统计 */ SL_Register_Charg_Control = 0x010D, /* 充电控制 */ }SL_Mppt_MsgRegister; /* 配置文件数据类型表 */ typedef enum { unique_Device_ID = 0x0000, /* (7字节)唯一设备标识码 */ SL_Protocol_Communication_Baud_Rate_Up = 0x0001, /* (1字节)SL协议对上通信波特率(01H:4800;02H:9600;03H:19200;04H:38400;05H:57600;06H:115200) */ SL_Protocol_Communication_Baud_Rate_Down= 0x0002, /* (1字节)SL协议对下通信波特率(01H:4800;02H:9600;03H:19200;04H:38400;05H:57600;06H:115200) */ power_Box_Type = 0x0100, /* (1字节)电源盒类型(00H:带网关; FFH:仅充电) */ constant_Voltage_V = 0x0101, /* (2字节)恒压充电阈值电压(*10再强转u16(V)) */ float_I = 0x0102, /* (2字节)浮充充电阈值电流(*10再强转u16(A)) */ start_Solar_Open_Circuit_V = 0x0103, /* (2字节)启动充电太阳能板开路电压(*10再强转u16(A)) */ stop_Solar_Output_Circuit_V = 0x0104, /* (2字节)停止充电太阳能板输出电压(*10再强转u16(A)) */ check_Can_Start_Time = 0x0105, /* (2字节)检测能否启动间隔时间(S) */ short_Circuit_Judgment_Delay = 0x0106, /* (2字节)短路判断延时(S) */ input_Power_Low_Judgment_Delay = 0x0107, /* (2字节)前端输入功率不足判断延时(S) */ input_Power_Low_Again_Output_Delay = 0x0108, /* (2字节)前端输入功率不足再次输出延时(S) */ first_Stage_Protection_Delay = 0x0109, /* (2字节)第一段保护延时(10uS) */ first_Stage_Protection_Curr = 0x010A, /* (2字节)第一段保护电流(*10再强转u16(A)) */ second_Stage_Protection_Delay = 0x010B, /* (2字节)第二段保护延时(100uS) */ second_Stage_Protection_Curr = 0x010C, /* (2字节)第二段保护电流(*10再强转u16(A)) */ third_Stage_Protection_Delay = 0x010D, /* (4字节)第三段保护延时(100uS) */ third_Stage_Protection_Curr = 0x010E, /* (2字节)第三段保护电流(*10再强转u16(A)) */ input_Power_Low_Detection_Delay = 0x010F, /* (2字节)前端输入功率不足检测延时(100uS) */ input_Power_Low_Detection_Volt = 0x0110, /* (2字节)前端输入功率不足检测电压(*10再强转u16(V)) */ max_Open_Solar_Output_Circuit_V = 0x0111, /* (2字节)最大太阳能板输出电压(*10再强转u16(V)) */ max_Charg_Curr = 0x0112, /* (2字节)最大充电电流(*10再强转u16(A)) */ min_Check_Loop_Impedance_Charg_Curr = 0x0113, /* (2字节)检测回路阻抗时的最小充电电流(*10再强转u16(A)) */ full_Power_Output_Temperature = 0x0114, /* (2字节)满功率输出温度(*10再强转u16(℃)) */ reduce_Power_Output_Temperature = 0x0115, /* (2字节)降功率输出温度(*10再强转u16(℃)) */ stop_PowerOutput_Temperature = 0x0116, /* (2字节)停止输出温度(*10再强转u16(℃)) */ constant_Voltage_Charge_V = 0x0117, /* (2字节)恒压充电时的输出电压(*10再强转u16(V)) */ float_ChargeV = 0x0118, /* (2字节)浮充充电时的输出电压(*10再强转u16(V)) */ collect_OpenCircuit_Voltage_Time = 0x0119, /* (2字节)充电时采集开路电压的间隔时间(S) */ }cfgFileType; #define gw485RxBufferSize 256 /* 计时参数,2min后没解析整个配置文件,丢掉当前数据 */ static uint32_t gw485CfgTime = 0; static uint8_t gw485CfgFlag = 0; //0:解析完成或未下发配置文件 1:下发配置文件中 2:上次配置文件下发时间过长 /* 计时参数,一秒后没解析出数据,丢掉当前数据 */ static uint32_t gw485RxTime = 0; /* 储存gw485数据 */ static uint8_t gw485RxBuffer[gw485RxBufferSize]; static uint16_t gw485RxBufferIndex = 0; /* 状态机状态机变量 */ static uartStateMachine state = wait; static uint16_t frameLength = 0; static void stateMachine(device_handle device); static BOOL checkCrcSl(void); /* 状态机函数 */ static BOOL analysisWait(void); static BOOL analysisStartFlagSL(void); static BOOL analysisAddressSL(void); static BOOL analysisFunctionCodeSL(void); static BOOL analysisReadRegStartAddressSL(void); static BOOL analysisReadRegStartNumberSL(void); static BOOL analysisCrcCheckBitSL(void); static void analysisEndFlagSL(device_handle device); static BOOL analysisWriteRegStartAddressSL(void); static BOOL analysisWriteRegStartNumberSL(void); static BOOL analysisRegLengthSL(void); static BOOL analysisRegStatusSL(void); static BOOL analysisCfgFramesNumSL(void); static BOOL analysiscfgLengthSL(void); static BOOL analysisReadCfgLengthSL(void); static BOOL analysisReadSOEStartAddr(void); static BOOL analysisReadSOELength(void); /* SL协议寄存器解析 */ static uint16_t SL_ReadRegisterSolarOpenCircuitVoltage(void *pMsg); static uint16_t SL_ReadRegisterSolarInputVoltage(void *pMsg); static uint16_t SL_ReadRegisterOutputVoltage(void *pMsg); static uint16_t SL_ReadRegisterBatteryVoltage(void *pMsg); static uint16_t SL_ReadRegisterChargCurrent(void *pMsg); static uint16_t SL_ReadRegisterDischargCurrent(void *pMsg); static uint16_t SL_ReadRegisterHighSideMosTemperature(void *pMsg); static uint16_t SL_ReadRegisterSOC(void *pMsg); static uint16_t SL_ReadRegisterChargState(void *pMsg); static uint16_t SL_ReadRegisterTotalChargCapacity(void *pMsg); static uint16_t SL_ReadRegisterTotalElectricityConsumption(void *pMsg); static uint16_t SL_ReadRegisterMPPT_Mode(void *pMsg); static uint16_t SL_WriteRegisterEliminateStatistical(void *pMsg); static uint16_t SL_WriteRegisterChargControl(void *pMsg); /* 寄存器处理表 */ typedef uint16_t (*RegProcFunc)(void*); typedef struct _SL_RegProcTable{ uint32_t regId; RegProcFunc pRegProc; }SL_RegProcTable; /* 寄存器处理表 */ SL_RegProcTable g_RegTblR[] = { // {SL_Register_Registration_Status, SL_ReadRegisterRegistrationStatus}, // {SL_Register_address, SL_ReadRegisteraddress}, // {SL_Register_Access_Node_Type, SL_ReadRegisterAccessNodeType}, // {SL_Register_Communication_Methods, SL_ReadRegisterCommunicationMethods}, {SL_Register_Solar_Open_Circuit_Voltage, SL_ReadRegisterSolarOpenCircuitVoltage}, {SL_Register_Solar_Input_Voltage, SL_ReadRegisterSolarInputVoltage}, {SL_Register_Output_Voltage, SL_ReadRegisterOutputVoltage}, {SL_Register_Battery_Voltage, SL_ReadRegisterBatteryVoltage}, {SL_Register_Charg_Current, SL_ReadRegisterChargCurrent}, {SL_Register_Discharg_Current, SL_ReadRegisterDischargCurrent}, {SL_Register_HighSideMos_Temperature, SL_ReadRegisterHighSideMosTemperature}, {SL_Register_SOC, SL_ReadRegisterSOC}, {SL_Register_chargState, SL_ReadRegisterChargState}, {SL_Register_totalChargCapacity, SL_ReadRegisterTotalChargCapacity}, {SL_Register_totalElectricityConsumption, SL_ReadRegisterTotalElectricityConsumption}, {SL_Register_MPPT_Mode, SL_ReadRegisterMPPT_Mode}, }; /* 寄存器处理表 */ SL_RegProcTable g_RegTblW[] = { // {SL_Register_Registration_Status, SL_WriteRegisterRegistrationStatus}, // {SL_Register_address, SL_WriteRegisteraddress}, // {SL_Register_Access_Node_Type, SL_WriteRegisterAccessNodeType}, // {SL_Register_Communication_Methods, SL_WriteRegisterCommunicationMethods}, {SL_Register_eliminateStatistical, SL_WriteRegisterEliminateStatistical}, {SL_Register_Charg_Control, SL_WriteRegisterChargControl}, }; /* 配置文件解析函数 */ static uint8_t *analysisDistributionProfile(uint8_t *pMsg, config_info *temp); static uint8_t *analysisReadProfile(uint8_t *pMsg, uint8_t **outData, uint16_t *dataLen); /* 解析出来指令对应函数 */ static void SL_MsgProcFunc_Read_Register(device_handle device, void *pMsg, uint32_t MsgLen); static void SL_MsgProcFunc_Write_Register(device_handle device, void *pMsg, uint32_t MsgLen); static void SL_MsgProcFunc_Broadcast_Scan(device_handle device, void *pMsg, uint32_t MsgLen); static void SL_MsgProcFunc_Registration_request(device_handle device, void *pMsg, uint32_t MsgLen); static void SL_MsgProcFunc_Distribution_Profile(device_handle device, void *pMsg, uint32_t MsgLen); static void SL_MsgProcFunc_Read_Profile(device_handle device, void *pMsg, uint32_t MsgLen); static void SL_MsgProcFunc_Read_SOE(device_handle device, void *pMsg, uint32_t MsgLen); /** * @brief modbus的crc校验 * @param *arr_buff 需要校验的数据 * len 数据长度 * @retval crc 校验的结果 */ uint16_t checkModebusCrc(uint8_t *arr_buff, uint8_t len) { uint16_t crc = 0xFFFF; uint16_t i, j; for (j = 0; j < len; ++j) { crc = crc ^ (*arr_buff++); for (i = 0; i < 8; ++i) { if ((crc&0x0001) > 0) { crc = crc >> 1; crc = crc ^ 0xa001; } else { crc = crc >> 1; } } } return crc; } /** * @brief SL协议的crc校验 * @param * @retval */ BOOL checkCrcSl(void) { static uint16_t maxLen = 0; maxLen = frameLength - 1; /* crc校验 */ if (gw485RxBufferIndex >= maxLen) { uint32_t tempCrc = 0; tempCrc = (gw485RxBuffer[frameLength - 3] << 8) | gw485RxBuffer[frameLength - 2]; if (tempCrc == checkModebusCrc(gw485RxBuffer, frameLength - 3)) { state = crcCheckBitSL; return TRUE; } } if (gw485RxBufferIndex < maxLen) { return FALSE; } state = wait; gw485RxBufferIndex--; memcpy(gw485RxBuffer, gw485RxBuffer + 1, gw485RxBufferIndex); return FALSE; } /** * @brief 状态机函数 * @param * @retval */ void stateMachine(device_handle device) { if (state == wait) { if (analysisWait() == TRUE) { gw485RxTime = 0; } } else if (state == startFlagSL) { analysisStartFlagSL(); } else if (state == addressSL) { analysisAddressSL(); } else if (state == functionCodeSL) { analysisFunctionCodeSL(); } else if (state == readRegStartAddressSL) { analysisReadRegStartAddressSL(); } else if (state == readRegStartNumberSL) { analysisReadRegStartNumberSL(); } else if (state == crcCheckBitSL) { analysisCrcCheckBitSL(); } else if (state == endFlagSL) { analysisEndFlagSL(device); } else if (state == writeRegStartAddressSL) { analysisWriteRegStartAddressSL(); } else if (state == writeRegStartNumberSL) { analysisWriteRegStartNumberSL(); } else if (state == regLengthSL) { analysisRegLengthSL(); } else if (state == regStatusSL) { analysisRegStatusSL(); } else if (state == cfgFramesNumSL) { analysisCfgFramesNumSL(); } else if (state == cfgLengthSL) { analysiscfgLengthSL(); } else if (state == readCfgLengthSL) { analysisReadCfgLengthSL(); } else if (state == readSOEStartAddr) { analysisReadSOEStartAddr(); } else if (state == readSOELength) { analysisReadSOELength(); } } void gw485DataAnalysis(device_handle device) { /* 每次函数最多执行5ms */ static uint32_t tickstart = 0U; tickstart = HAL_GetTick(); /* 1S未解析出来一帧数据,将数据清零 */ gw485RxTime++; if (gw485RxTime >= 100) { gw485RxTime = 0; gw485RxBufferIndex = 0; state = wait; } /* 60S所有配置文件未传输完成,将数据清零 */ if (gw485CfgFlag == 1) { gw485CfgTime++; if (gw485CfgTime >= 6000) { gw485CfgTime = 0; gw485CfgFlag = 2; } } while (uart_dev_char_present(device) == 1 && ((HAL_GetTick() - tickstart) < 5)) { gw485RxBuffer[gw485RxBufferIndex++] = uart_dev_in_char(device); stateMachine(device); } // tickstart = HAL_GetTick(); // while (gw485RxBufferIndex != 0 && ((HAL_GetTick() - tickstart) < 5) ) { stateMachine(device); // } } /** * @brief 状态 wait * @param * @retval TRUE:解析成功 FALSE:解析失败 */ BOOL analysisWait(void) { static uint16_t maxLen = 2; /* 解析SL协议的包头 */ if (gw485RxBufferIndex >= 2) { if (gw485RxBuffer[0] == 'S' && gw485RxBuffer[1] == 'L') { state = startFlagSL; return TRUE; } } if (gw485RxBufferIndex < maxLen) { return FALSE; } state = wait; gw485RxBufferIndex--; memcpy(gw485RxBuffer, gw485RxBuffer + 1, gw485RxBufferIndex); return FALSE; } /** * @brief 状态 StartFlagSL * @param * @retval TRUE:解析成功 FALSE:解析失败 */ BOOL analysisStartFlagSL(void) { static uint16_t maxLen = 9; /* 解析SL协议设备地址 */ if (gw485RxBufferIndex >= 9) { if (gw485RxBuffer[2] == g_cfgParameter.uniqueDeviceID[0] && gw485RxBuffer[3] == g_cfgParameter.uniqueDeviceID[1] && gw485RxBuffer[4] == g_cfgParameter.uniqueDeviceID[2] && gw485RxBuffer[5] == g_cfgParameter.uniqueDeviceID[3] && gw485RxBuffer[6] == g_cfgParameter.uniqueDeviceID[4] && gw485RxBuffer[7] == g_cfgParameter.uniqueDeviceID[5] && gw485RxBuffer[8] == g_cfgParameter.uniqueDeviceID[6]) { state = addressSL; return TRUE; } if (gw485RxBuffer[2] == 0xFF && gw485RxBuffer[3] == 0xFF && gw485RxBuffer[4] == 0xFF && gw485RxBuffer[5] == 0xFF && gw485RxBuffer[6] == 0xFF && gw485RxBuffer[7] == 0xFF && gw485RxBuffer[8] == 0xFF) { state = addressSL; return TRUE; } } if (gw485RxBufferIndex < maxLen) { return FALSE; } state = wait; gw485RxBufferIndex--; memcpy(gw485RxBuffer, gw485RxBuffer + 1, gw485RxBufferIndex); return FALSE; } /** * @brief 状态 addressSL * @param * @retval TRUE:解析成功 FALSE:解析失败 */ BOOL analysisAddressSL(void) { static uint16_t maxLen = 10; /* 解析SL功能码 */ if (gw485RxBufferIndex >= 10) { /* 判断地址是否为广播ID */ uint8_t temp = 0; if (gw485RxBuffer[2] == 0xFF && gw485RxBuffer[3] == 0xFF && gw485RxBuffer[4] == 0xFF && gw485RxBuffer[5] == 0xFF && gw485RxBuffer[6] == 0xFF && gw485RxBuffer[7] == 0xFF && gw485RxBuffer[8] == 0xFF) { temp = 1; } else { temp = 0; } /* 判断功能码类型 */ if (temp == 0) { if (gw485RxBuffer[9] == SL_Function_Code_Read_Register || gw485RxBuffer[9] == SL_Function_Code_Write_Register || gw485RxBuffer[9] == SL_Function_Code_Registration_request || gw485RxBuffer[9] == SL_Function_Code_Distribution_Profile || gw485RxBuffer[9] == SL_Function_Code_Read_Profile || gw485RxBuffer[9] == SL_Function_Code_Read_SOE){ state = functionCodeSL; return TRUE; } } else { if (gw485RxBuffer[9] == SL_Function_Code_Broadcast_Scan) { state = functionCodeSL; frameLength = 13; return TRUE; } } } if (gw485RxBufferIndex < maxLen) { return FALSE; } state = wait; gw485RxBufferIndex--; memcpy(gw485RxBuffer, gw485RxBuffer + 1, gw485RxBufferIndex); return FALSE; } /** * @brief 状态 functionCodeSL * @param * @retval TRUE:解析成功 FALSE:解析失败 */ BOOL analysisFunctionCodeSL(void) { static uint16_t maxLen = 12; /* 解析读取寄存器起始位置 */ if ((gw485RxBufferIndex >= 12) && (gw485RxBuffer[9] == SL_Function_Code_Read_Register)) { uint32_t tempAddrStart = 0; tempAddrStart = (gw485RxBuffer[10] << 8) | gw485RxBuffer[11]; if (tempAddrStart >= minReadRegAddrMacro && tempAddrStart <= maxReadRegAddrMacro) { state = readRegStartAddressSL; return TRUE; } } /* 解析写入寄存器起始位置 */ if ((gw485RxBufferIndex >= 12) && (gw485RxBuffer[9] == SL_Function_Code_Write_Register)) { uint32_t tempAddrStart = 0; tempAddrStart = (gw485RxBuffer[10] << 8) | gw485RxBuffer[11]; if (tempAddrStart >= minWriteRegAddrMacro && tempAddrStart <= maxWriteRegAddrMacro) { state = writeRegStartAddressSL; return TRUE; } } /* 解析扫描广播帧crc校验 */ if ((gw485RxBufferIndex >= 12) && (gw485RxBuffer[9] == SL_Function_Code_Broadcast_Scan)) { uint32_t tempCrc = 0; tempCrc = (gw485RxBuffer[frameLength - 3] << 8) | gw485RxBuffer[frameLength - 2]; if (tempCrc == checkModebusCrc(gw485RxBuffer, frameLength - 3)) { state = crcCheckBitSL; return TRUE; } } /* 解析注册回复帧寄存器长度 */ if ((gw485RxBufferIndex >= 12) && (gw485RxBuffer[9] == SL_Function_Code_Registration_request)) { uint32_t tempRegLen = 0; tempRegLen = (gw485RxBuffer[10] << 8) | gw485RxBuffer[11]; if (tempRegLen < RegAddrNumMacro && tempRegLen > 0) { state = regLengthSL; frameLength = 17; return TRUE; } } /* 解析配置文件下发帧数 */ if ((gw485RxBufferIndex >= 12) && (gw485RxBuffer[9] == SL_Function_Code_Distribution_Profile)) { if (gw485RxBuffer[10] <= gw485RxBuffer[11]) { state = cfgFramesNumSL; return TRUE; } } /* 解析配置文件读取内容的长度 */ if ((gw485RxBufferIndex >= 12) && (gw485RxBuffer[9] == SL_Function_Code_Read_Profile)) { uint32_t tempCfgLen = 0; tempCfgLen = (gw485RxBuffer[10] << 8) | gw485RxBuffer[11]; if (tempCfgLen < RegAddrNumMacro && tempCfgLen > 0) { state = readCfgLengthSL; frameLength = 15 + tempCfgLen; return TRUE; } } /* 解析SOE读取的起始读取位 */ // if ((gw485RxBufferIndex >= 11) && (gw485RxBuffer[9] == SL_Function_Code_Read_SOE)) { if (gw485RxBuffer[9] == SL_Function_Code_Read_SOE) { // if (gw485RxBuffer[10] < 100 && gw485RxBuffer[10] >= 0) { if (gw485RxBuffer[10] < 100) { state = readSOEStartAddr; frameLength = 15; return TRUE; } } if (gw485RxBufferIndex < maxLen) { return FALSE; } state = wait; gw485RxBufferIndex--; memcpy(gw485RxBuffer, gw485RxBuffer + 1, gw485RxBufferIndex); return FALSE; } /** * @brief 状态 readRegStartAddressSL * @param * @retval TRUE:解析成功 FALSE:解析失败 */ BOOL analysisReadRegStartAddressSL(void) { static uint16_t maxLen = 14; /* 解析读取寄存器长度 */ if (gw485RxBufferIndex >= 14) { uint32_t tempAddrNumber = 0; tempAddrNumber = (gw485RxBuffer[12] << 8) | gw485RxBuffer[13]; if (tempAddrNumber >= 1 && tempAddrNumber <= maxReadRegAddrNumMacro) { state = readRegStartNumberSL; frameLength = 17; return TRUE; } } if (gw485RxBufferIndex < maxLen) { return FALSE; } state = wait; gw485RxBufferIndex--; memcpy(gw485RxBuffer, gw485RxBuffer + 1, gw485RxBufferIndex); return FALSE; } /** * @brief 状态 readRegStartNumberSL * @param * @retval TRUE:解析成功 FALSE:解析失败 */ BOOL analysisReadRegStartNumberSL(void) { // static uint16_t maxLen = 16; // /* crc校验 */ // if (gw485RxBufferIndex >= 16) { // uint32_t tempCrc = 0; // tempCrc = (gw485RxBuffer[14] << 8) | gw485RxBuffer[15]; // if (tempCrc == checkModebusCrc(gw485RxBuffer, 14)) { // state = crcCheckBitSL; // return TRUE; // } // } // if (gw485RxBufferIndex < maxLen) { // return FALSE; // } // state = wait; // gw485RxBufferIndex--; // memcpy(gw485RxBuffer, gw485RxBuffer + 1, gw485RxBufferIndex); // return FALSE; return checkCrcSl(); } /** * @brief 状态 crcCheckBitSL * @param * @retval TRUE:解析成功 FALSE:解析失败 */ BOOL analysisCrcCheckBitSL(void) { /* 结束标志校验校验 */ if (gw485RxBufferIndex == frameLength) { if (gw485RxBuffer[frameLength - 1] == 0x16) { state = endFlagSL; return TRUE; } } state = wait; gw485RxBufferIndex--; memcpy(gw485RxBuffer, gw485RxBuffer + 1, gw485RxBufferIndex); return FALSE; } /** * @brief 状态 endFlagSL * @param device 串口设备 * @retval TRUE:解析成功 FALSE:解析失败 */ void analysisEndFlagSL(device_handle device) { /* 数据为读取寄存器 */ if (gw485RxBuffer[9] == SL_Function_Code_Read_Register) { SL_MsgProcFunc_Read_Register(device, gw485RxBuffer, frameLength); } /* 数据为写入寄存器 */ else if (gw485RxBuffer[9] == SL_Function_Code_Write_Register) { SL_MsgProcFunc_Write_Register(device, gw485RxBuffer, frameLength); } /* 数据为扫描广播帧 */ else if (gw485RxBuffer[9] == SL_Function_Code_Broadcast_Scan) { SL_MsgProcFunc_Broadcast_Scan(device, gw485RxBuffer, frameLength); } /* 数据为注册回复帧 */ else if (gw485RxBuffer[9] == SL_Function_Code_Registration_request) { SL_MsgProcFunc_Registration_request(device, gw485RxBuffer, frameLength); } /* 数据为下发配置文件 */ else if (gw485RxBuffer[9] == SL_Function_Code_Distribution_Profile) { SL_MsgProcFunc_Distribution_Profile(device, gw485RxBuffer, frameLength); } /* 数据为读取配置文件 */ else if (gw485RxBuffer[9] == SL_Function_Code_Read_Profile) { SL_MsgProcFunc_Read_Profile(device, gw485RxBuffer, frameLength); } /* 数据为读取SOE */ else if (gw485RxBuffer[9] == SL_Function_Code_Read_SOE) { SL_MsgProcFunc_Read_SOE(device, gw485RxBuffer, frameLength); } state = wait; gw485RxBufferIndex = 0; // memcpy(gw485RxBuffer, gw485RxBuffer + gw485RxBufferIndex, ); } /** * @brief 状态 writeRegStartAddressSL * @param * @retval TRUE:解析成功 FALSE:解析失败 */ BOOL analysisWriteRegStartAddressSL(void) { static uint16_t maxLen = 14; /* 解析写入寄存器长度 */ if (gw485RxBufferIndex >= 14) { uint32_t tempAddrNumber = 0; tempAddrNumber = (gw485RxBuffer[12] << 8) | gw485RxBuffer[13]; if (tempAddrNumber >= 1 && tempAddrNumber <= maxWriteRegAddrNumMacro) { state = writeRegStartNumberSL; frameLength = 17 + tempAddrNumber * 2; return TRUE; } } if (gw485RxBufferIndex < maxLen) { return FALSE; } state = wait; gw485RxBufferIndex--; memcpy(gw485RxBuffer, gw485RxBuffer + 1, gw485RxBufferIndex); return FALSE; } /** * @brief 状态 writeRegStartNumberSL * @param * @retval TRUE:解析成功 FALSE:解析失败 */ BOOL analysisWriteRegStartNumberSL(void) { // static uint16_t maxLen; // maxLen = frameLength - 1; // /* crc校验 */ // if (gw485RxBufferIndex >= maxLen) { // // log_error("crcCheckBitSL error : gw485RxBuffer[12] = 0x%x, gw485RxBuffer[13] = 0x%x"\ // // , gw485RxBuffer[12], gw485RxBuffer[13]); // // log_error("crcCheckBitSL error : gw485RxBuffer[14] = 0x%x, gw485RxBuffer[15] = 0x%x"\ // // , gw485RxBuffer[14], gw485RxBuffer[15]); // // log_error("crcCheckBitSL error : gw485RxBuffer[16] = 0x%x, gw485RxBuffer[17] = 0x%x"\ // // , gw485RxBuffer[16], gw485RxBuffer[17]); // uint32_t tempCrc = 0; // tempCrc = (gw485RxBuffer[frameLength - 3] << 8) | gw485RxBuffer[frameLength - 2]; // // tempCrc = (gw485RxBuffer[14] << 8) | gw485RxBuffer[15]; // if (tempCrc == checkModebusCrc(gw485RxBuffer, frameLength - 3)) { // state = crcCheckBitSL; // return TRUE; // } // log_error("frameLength : %d", frameLength); // log_error("crcCheckBitSL error : tempCrc = 0x%x, checkModebusCrc = 0x%x"\ // , tempCrc, checkModebusCrc(gw485RxBuffer, frameLength - 3)); // } // if (gw485RxBufferIndex < maxLen) { // return FALSE; // } // state = wait; // gw485RxBufferIndex--; // memcpy(gw485RxBuffer, gw485RxBuffer + 1, gw485RxBufferIndex); // return FALSE; return checkCrcSl(); } /** * @brief 状态 regLengthSL * @param * @retval TRUE:解析成功 FALSE:解析失败 */ BOOL analysisRegLengthSL(void) { static uint16_t maxLen = 12; /* crc校验 */ if (gw485RxBufferIndex >= 12) { uint32_t tempRegStatus = 0; tempRegStatus = (gw485RxBuffer[12] << 8) | gw485RxBuffer[13]; if (tempRegStatus == UNREGISTER || tempRegStatus == REGISTER_FAIL || tempRegStatus == REGISTER_SUCCESS) { state = regStatusSL; return TRUE; } } if (gw485RxBufferIndex < maxLen) { return FALSE; } state = wait; gw485RxBufferIndex--; memcpy(gw485RxBuffer, gw485RxBuffer + 1, gw485RxBufferIndex); return FALSE; } /** * @brief 状态 regStatusSL * @param * @retval TRUE:解析成功 FALSE:解析失败 */ BOOL analysisRegStatusSL(void) { // static uint16_t maxLen = 16; // /* crc校验 */ // if (gw485RxBufferIndex >= 16) { // uint32_t tempCrc = 0; // tempCrc = (gw485RxBuffer[frameLength - 3] << 8) | gw485RxBuffer[frameLength - 2]; // if (tempCrc == checkModebusCrc(gw485RxBuffer, frameLength - 3)) { // state = crcCheckBitSL; // return TRUE; // } // } // if (gw485RxBufferIndex < maxLen) { // return FALSE; // } // state = wait; // gw485RxBufferIndex--; // memcpy(gw485RxBuffer, gw485RxBuffer + 1, gw485RxBufferIndex); // return FALSE; return checkCrcSl(); } /** * @brief 状态 cfgFramesNumSL * @param * @retval TRUE:解析成功 FALSE:解析失败 */ BOOL analysisCfgFramesNumSL(void) { static uint16_t maxLen = 14; /* 解析下发配置文件数据内容长度 */ if (gw485RxBufferIndex >= maxLen) { uint32_t tempLen = 0; tempLen = (gw485RxBuffer[12] << 8) | gw485RxBuffer[13]; if (tempLen > 0 && tempLen <= maxDistributionCfgLen) { state = cfgLengthSL; frameLength = 17 + tempLen; // log_error("cfgFramesNumSL error : tempLen = %d \n", tempLen); return TRUE; } } if (gw485RxBufferIndex < maxLen) { return FALSE; } state = wait; gw485RxBufferIndex--; memcpy(gw485RxBuffer, gw485RxBuffer + 1, gw485RxBufferIndex); return FALSE; } /** * @brief 状态 cfgLengthSL * @param * @retval TRUE:解析成功 FALSE:解析失败 */ BOOL analysiscfgLengthSL(void) { // static uint16_t maxLen = 16; // /* crc校验 */ // if (gw485RxBufferIndex >= 16) { // uint32_t tempCrc = 0; // tempCrc = (gw485RxBuffer[frameLength - 3] << 8) | gw485RxBuffer[frameLength - 2]; // if (tempCrc == checkModebusCrc(gw485RxBuffer, frameLength - 3)) { // state = crcCheckBitSL; // return TRUE; // } // } // if (gw485RxBufferIndex < maxLen) { // return FALSE; // } // state = wait; // gw485RxBufferIndex--; // memcpy(gw485RxBuffer, gw485RxBuffer + 1, gw485RxBufferIndex); // return FALSE; return checkCrcSl(); } /** * @brief 状态 readCfgLengthSL * @param * @retval TRUE:解析成功 FALSE:解析失败 */ BOOL analysisReadCfgLengthSL(void) { return checkCrcSl(); } /** * @brief 状态 readSOEStartAddr * @param * @retval TRUE:解析成功 FALSE:解析失败 */ BOOL analysisReadSOEStartAddr(void) { if (gw485RxBuffer[10] + gw485RxBuffer[11] < 100 && gw485RxBuffer[11] > 0){ state = readSOELength; return TRUE; } state = wait; gw485RxBufferIndex--; memcpy(gw485RxBuffer, gw485RxBuffer + 1, gw485RxBufferIndex); return FALSE; } /** * @brief 状态 readSOELength * @param * @retval TRUE:解析成功 FALSE:解析失败 */ BOOL analysisReadSOELength(void) { return checkCrcSl(); } /* 读取寄存器 */ /** * @brief 读取太阳能开路电压 * @param * @retval 太阳能开路电压(* floatMagnification保留为整数) */ uint16_t SL_ReadRegisterSolarOpenCircuitVoltage(void *pMsg) { return (uint16_t)(getSolarOpenCircuitVoltage() * floatMagnification); } /** * @brief 读取太阳能输入电压 * @param * @retval 太阳能输入电压(* floatMagnification保留为整数) */ uint16_t SL_ReadRegisterSolarInputVoltage(void *pMsg) { return (uint16_t)(getSolarInCircuitVoltage() * floatMagnification); } /** * @brief 读取输出电压 * @param * @retval 电池电压(* floatMagnification保留为整数) */ uint16_t SL_ReadRegisterOutputVoltage(void *pMsg) { return (uint16_t)(getOutputVoltage() * floatMagnification); } /** * @brief 读取电池电压 * @param * @retval 电池电压(* floatMagnification保留为整数) */ uint16_t SL_ReadRegisterBatteryVoltage(void *pMsg) { return (uint16_t)(getBatteryVoltage() * floatMagnification); } /** * @brief 读取充电电流 * @param * @retval 充电电流(* floatMagnification保留为整数) */ uint16_t SL_ReadRegisterChargCurrent(void *pMsg) { return (uint16_t)(getChargCurrent() * floatMagnification); } /** * @brief 读取放电电流 * @param * @retval 放电电流(* floatMagnification保留为整数) */ uint16_t SL_ReadRegisterDischargCurrent(void *pMsg) { return (uint16_t)(getDischargCurrent() * floatMagnification); } /** * @brief 读取MOS管温度 * @param * @retval MOS管温度(* floatMagnification保留为整数) */ uint16_t SL_ReadRegisterHighSideMosTemperature(void *pMsg) { return (uint16_t)(getHighSideMosTemperature() * floatMagnification); } /** * @brief 读取SOC * @param * @retval SOC */ uint16_t SL_ReadRegisterSOC(void *pMsg) { return (uint16_t)(getSOC() * 100); } /** * @brief 读取充放电状态 * @param * @retval 充放电状态 */ uint16_t SL_ReadRegisterChargState(void *pMsg) { uint16_t temp = 0; if (getDutyRatio() > 0 && getChargControlFlag() == TRUE) { temp |= 0xFF00; } if (getDischargMosState() == TRUE) { temp |= 0xFF; } return temp; } /** * @brief 读取充电量 * @param * @retval 充电量(* floatMagnification保留为整数) */ uint16_t SL_ReadRegisterTotalChargCapacity(void *pMsg) { volatile uint16_t temp = 0; temp = (uint16_t)(getTotalChargCapacity() * floatMagnification); totalChargCapacityInt(0); return temp; } /** * @brief 读取放电量 * @param * @retval 放电量(* floatMagnification保留为整数) */ uint16_t SL_ReadRegisterTotalElectricityConsumption(void *pMsg) { volatile uint16_t temp = 0; temp = (uint16_t)(getTotalElectricityConsumption() * floatMagnification); totalElectricityConsumptionInt(0); return temp; } /** * @brief 读取控制盒工作模式 * @param * @retval 控制盒工作模式 */ uint16_t SL_ReadRegisterMPPT_Mode(void *pMsg) { return getMPPT_Mode(); } /* 写入寄存器 */ /** * @brief 清除统计电量 * @param * @retval */ uint16_t SL_WriteRegisterEliminateStatistical(void *pMsg) { debug_printf("SL_WriteRegisterEliminateStatistical\n"); totalChargCapacityInt(0); totalElectricityConsumptionInt(0); return 0; } /** * @brief 控制充电状态 * @param * @retval */ uint16_t SL_WriteRegisterChargControl(void *pMsg) { debug_printf("SL_WriteRegisterChargControl\n"); if ((*(uint16_t*)pMsg) == 0xFFFF) { stopChargWork(); } else if ((*(uint16_t*)pMsg) == 0x0000) { beginChargWork(); } return 0; } /** * @brief 解析下发的配置文件 * @param pMsg 需要解析的内容 * @retval NULL解析失败 其他:下次解析的位置 */ uint8_t *analysisDistributionProfile(uint8_t *pMsg, config_info *temp) { uint16_t dataType; dataType = (*pMsg << 8) | *(pMsg + 1); /* 配置 unique_Device_ID */ if (dataType == unique_Device_ID) { temp->uniqueDeviceID[0] = pMsg[2]; temp->uniqueDeviceID[1] = pMsg[3]; temp->uniqueDeviceID[2] = pMsg[4]; temp->uniqueDeviceID[3] = pMsg[5]; temp->uniqueDeviceID[4] = pMsg[6]; temp->uniqueDeviceID[5] = pMsg[7]; temp->uniqueDeviceID[6] = pMsg[8]; return (pMsg + 9); } /* 配置 对上通信波特率 */ else if (dataType == SL_Protocol_Communication_Baud_Rate_Up) { switch (pMsg[2]) { case 0x01: temp->gw485_Baud = 4800; return (pMsg + 3); case 0x02: temp->gw485_Baud = 9600; return (pMsg + 3); case 0x03: temp->gw485_Baud = 19200; return (pMsg + 3); case 0x04: temp->gw485_Baud = 38400; return (pMsg + 3); case 0x05: temp->gw485_Baud = 57600; return (pMsg + 3); case 0x06: temp->gw485_Baud = 115200; return (pMsg + 3); default: return NULL; } } /* 配置 对下通信波特率 */ else if (dataType == SL_Protocol_Communication_Baud_Rate_Down) { switch (pMsg[2]) { case 0x01: temp->bat485_Baud = 4800; return (pMsg + 3); case 0x02: temp->bat485_Baud = 9600; return (pMsg + 3); case 0x03: temp->bat485_Baud = 19200; return (pMsg + 3); case 0x04: temp->bat485_Baud = 38400; return (pMsg + 3); case 0x05: temp->bat485_Baud = 57600; return (pMsg + 3); case 0x06: temp->bat485_Baud = 115200; return (pMsg + 3); default: return NULL; } } /* 配置 充电控制盒类型 */ else if (dataType == power_Box_Type) { switch (pMsg[2]) { case 0x00: temp->bat485_Baud = 0x00; return (pMsg + 3); case 0xFF: temp->bat485_Baud = 0xFF; return (pMsg + 3); default: return NULL; } } /* 配置 恒压充电阈值电压 */ else if (dataType == constant_Voltage_V) { float tempFloat = ((*(pMsg + 2) << 8) | *(pMsg + 3)) / floatMagnification; if (tempFloat > 14.4f || tempFloat < 13.5f) { return NULL; } temp->constantVoltageV = tempFloat; return (pMsg + 4); } /* 配置 浮充充电阈值电流 */ else if (dataType == float_I) { float tempFloat = ((*(pMsg + 2) << 8) | *(pMsg + 3)) / floatMagnification; if (tempFloat > 0.3f || tempFloat < 0.01f) { return NULL; } temp->floatI = tempFloat; return (pMsg + 4); } /* 配置 启动充电太阳能板开路电压 */ else if (dataType == start_Solar_Open_Circuit_V) { float tempFloat = ((*(pMsg + 2) << 8) | *(pMsg + 3)) / floatMagnification; if (tempFloat > 18.0f || tempFloat < 15.5f) { return NULL; } temp->startSolarOpenCircuitV = tempFloat; return (pMsg + 4); } /* 配置 关闭充电太阳能板输出电压 */ else if (dataType == stop_Solar_Output_Circuit_V) { float tempFloat = ((*(pMsg + 2) << 8) | *(pMsg + 3)) / floatMagnification; if (tempFloat > 16 || tempFloat < 15) { return NULL; } temp->stopSolarOutputCircuitV = tempFloat; return (pMsg + 4); } /* 配置 启动时能否启动间隔 */ else if (dataType == check_Can_Start_Time) { uint16_t tempU16 = (*(pMsg + 2) << 8) | *(pMsg + 3); if (tempU16 > 1000 || tempU16 < 5) { return NULL; } temp->checkCanStartTime = tempU16; return (pMsg + 4); } /* 配置 前端输入功率不足判断延时 */ else if (dataType == input_Power_Low_Judgment_Delay) { uint16_t tempU16 = (*(pMsg + 2) << 8) | *(pMsg + 3); if (tempU16 > 1000 || tempU16 < 5) { return NULL; } temp->inputPowerLowJudgmentDelay = tempU16; return (pMsg + 4); } /* 配置 前端输入功率不足再次输出延时 */ else if (dataType == input_Power_Low_Again_Output_Delay) { uint16_t tempU16 = (*(pMsg + 2) << 8) | *(pMsg + 3); if (tempU16 > 10000 || tempU16 < 100) { return NULL; } temp->inputPowerLowAgainOutputDelay = tempU16; return (pMsg + 4); } /* 配置 软件第一段保护延时 */ else if (dataType == first_Stage_Protection_Delay) { uint16_t tempU16 = (*(pMsg + 2) << 8) | *(pMsg + 3); if (tempU16 > 100 || tempU16 < 1) { return NULL; } temp->firstStageProtectionDelay = tempU16; return (pMsg + 4); } /* 配置 软件第一段保护阈值电流 */ else if (dataType == first_Stage_Protection_Curr) { float tempFloat = ((*(pMsg + 2) << 8) | *(pMsg + 3)) / floatMagnification; if (tempFloat > 60 || tempFloat < 1) { return NULL; } temp->firstStageProtectionCurr = tempFloat; return (pMsg + 4); } /* 配置 软件第二段保护延时 */ else if (dataType == second_Stage_Protection_Delay) { uint16_t tempU16 = (*(pMsg + 2) << 8) | *(pMsg + 3); if (tempU16 > 10000 || tempU16 < 10) { return NULL; } temp->secondStageProtectionDelay = tempU16; return (pMsg + 4); } /* 配置 软件第二段保护阈值电流 */ else if (dataType == second_Stage_Protection_Curr) { float tempFloat = ((*(pMsg + 2) << 8) | *(pMsg + 3)) / floatMagnification; if (tempFloat > 50 || tempFloat < 1) { return NULL; } temp->secondStageProtectionCurr = tempFloat; return (pMsg + 4); } /* 配置 软件第三段保护延时 */ else if (dataType == third_Stage_Protection_Delay) { uint16_t tempU16 = (*(pMsg + 2) << 8) | *(pMsg + 3); if (tempU16 > 10000 || tempU16 < 10) { return NULL; } temp->thirdStageProtectionDelay = tempU16; return (pMsg + 4); } /* 配置 软件第三段保护阈值电流 */ else if (dataType == third_Stage_Protection_Curr) { float tempFloat = ((*(pMsg + 2) << 8) | *(pMsg + 3)) / floatMagnification; if (tempFloat > 50 || tempFloat < 1) { return NULL; } temp->thirdStageProtectionCurr = tempFloat; return (pMsg + 4); } /* 配置 前端输入功率不足检测延时 */ else if (dataType == input_Power_Low_Detection_Delay) { uint16_t tempU16 = (*(pMsg + 2) << 8) | *(pMsg + 3); if (tempU16 > 1000 || tempU16 < 2) { return NULL; } temp->inputPowerLowDetectionDelay = tempU16; return (pMsg + 4); } /* 配置 前端输入功率不足检测电压 */ else if (dataType == input_Power_Low_Detection_Volt) { float tempFloat = ((*(pMsg + 2) << 8) | *(pMsg + 3)) / floatMagnification; if (tempFloat > 13 || tempFloat < 8) { return NULL; } temp->inputPowerLowDetectionVolt = tempFloat; return (pMsg + 4); } /* 配置 最大太阳能板输出电压 */ else if (dataType == max_Open_Solar_Output_Circuit_V) { float tempFloat = ((*(pMsg + 2) << 8) | *(pMsg + 3)) / floatMagnification; if (tempFloat > 27 || tempFloat < 22) { return NULL; } temp->maxOpenSolarOutputCircuitV = tempFloat; return (pMsg + 4); } /* 配置 最大充电电流 */ else if (dataType == max_Charg_Curr) { float tempFloat = ((*(pMsg + 2) << 8) | *(pMsg + 3)) / floatMagnification; if (tempFloat > 40 || tempFloat < 30) { return NULL; } temp->maxChargCurr = tempFloat; return (pMsg + 4); } /* 配置 满功率输出温度 */ else if (dataType == full_Power_Output_Temperature) { float tempFloat = ((*(pMsg + 2) << 8) | *(pMsg + 3)) / floatMagnification; if (tempFloat > 100 || tempFloat < 30) { return NULL; } temp->fullPowerOutputTemperature = tempFloat; return (pMsg + 4); } /* 配置 降功率输出温度 */ else if (dataType == reduce_Power_Output_Temperature) { float tempFloat = ((*(pMsg + 2) << 8) | *(pMsg + 3)) / floatMagnification; if (tempFloat > 100 || tempFloat < 30) { return NULL; } temp->reducePowerOutputTemperature = tempFloat; return (pMsg + 4); } /* 配置 停止输出温度 */ else if (dataType == stop_PowerOutput_Temperature) { float tempFloat = ((*(pMsg + 2) << 8) | *(pMsg + 3)) / floatMagnification; if (tempFloat > 100 || tempFloat < 30) { return NULL; } temp->stopPowerOutputTemperature = tempFloat; return (pMsg + 4); } /* 配置 恒压充电输出电压 */ else if (dataType == constant_Voltage_Charge_V) { float tempFloat = ((*(pMsg + 2) << 8) | *(pMsg + 3)) / floatMagnification; if (tempFloat > 14.5f || tempFloat < 14) { return NULL; } temp->constantVoltageChargeV = tempFloat; return (pMsg + 4); } /* 配置 浮充充电输出电压 */ else if (dataType == float_ChargeV) { float tempFloat = ((*(pMsg + 2) << 8) | *(pMsg + 3)) / floatMagnification; if (tempFloat > 14.5f || tempFloat < 13) { return NULL; } temp->FloatChargeV = tempFloat; return (pMsg + 4); } /* 配置 充电时采集开路电压的间隔时间 */ else if (dataType == collect_OpenCircuit_Voltage_Time) { uint16_t tempU16 = (*(pMsg + 2) << 8) | *(pMsg + 3); if (tempU16 > 10000 || tempU16 < 1000) { return NULL; } temp->collectOpenCircuitVoltageTime = tempU16; return (pMsg + 4); } return NULL; } /** * @brief 解析下发的配置文件 * @param pMsg 需要解析的内容 * dataLen 解析得到的数据长度 * @retval NULL解析失败 其他:下次解析的位置 */ uint8_t *analysisReadProfile(uint8_t *pMsg, uint8_t **outData, uint16_t *dataLen) { /* 数据类型 */ *(*outData + 0) = *pMsg; *(*outData + 1) = *(pMsg + 1); uint16_t dataType; dataType = (*pMsg << 8) | *(pMsg + 1); // debug_printf("dataType:%d \n", dataType); /* 读取 unique_Device_ID */ if (dataType == unique_Device_ID) { /* 数据 */ *(*outData + 2) = g_cfgParameter.uniqueDeviceID[0]; *(*outData + 3) = g_cfgParameter.uniqueDeviceID[1]; *(*outData + 4) = g_cfgParameter.uniqueDeviceID[2]; *(*outData + 5) = g_cfgParameter.uniqueDeviceID[3]; *(*outData + 6) = g_cfgParameter.uniqueDeviceID[4]; *(*outData + 7) = g_cfgParameter.uniqueDeviceID[5]; *(*outData + 8) = g_cfgParameter.uniqueDeviceID[6]; *outData += 9; *dataLen += 9; return (pMsg + 2); } /* 读取 对上通信波特率 */ else if (dataType == SL_Protocol_Communication_Baud_Rate_Up) { switch (g_cfgParameter.gw485_Baud) { case 4800: *(*outData + 2) = 0x01; *outData += 3; *dataLen += 3; return (pMsg + 2); case 9600: *(*outData + 2) = 0x02; *outData += 3; *dataLen += 3; return (pMsg + 2); case 19200: *(*outData + 2) = 0x03; *outData += 3; *dataLen += 3; return (pMsg + 2); case 38400: *(*outData + 2) = 0x04; *outData += 3; *dataLen += 3; return (pMsg + 2); case 57600: *(*outData + 2) = 0x05; *outData += 3; *dataLen += 3; return (pMsg + 2); case 115200: *(*outData + 2) = 0x06; *outData += 3; *dataLen += 3; return (pMsg + 2); default: return NULL; } } /* 读取 对下通信波特率 */ else if (dataType == SL_Protocol_Communication_Baud_Rate_Down) { switch (g_cfgParameter.bat485_Baud) { case 4800: *(*outData + 2) = 0x01; *outData += 3; *dataLen += 3; return (pMsg + 2); case 9600: *(*outData + 2) = 0x02; *outData += 3; *dataLen += 3; return (pMsg + 2); case 19200: *(*outData + 2) = 0x03; *outData += 3; *dataLen += 3; return (pMsg + 2); case 38400: *(*outData + 2) = 0x04; *outData += 3; *dataLen += 3; return (pMsg + 2); case 57600: *(*outData + 2) = 0x05; *outData += 3; *dataLen += 3; return (pMsg + 2); case 115200: *(*outData + 2) = 0x06; *outData += 3; *dataLen += 3; return (pMsg + 2); default: return NULL; } } /* 读取 电源盒类型 */ else if (dataType == power_Box_Type) { *(*outData + 2) = g_cfgParameter.powerBoxType; *outData += 3; *dataLen += 3; return (pMsg + 2); } /* 读取 恒压充电阈值电压 */ else if (dataType == constant_Voltage_V) { uint16_t tempU16 = (uint16_t)(g_cfgParameter.constantVoltageV * floatMagnification); *(*outData + 2) = (uint8_t)(tempU16 >> 8); *(*outData + 3) = (uint8_t)(tempU16 & 0x00FF); *outData += 4; *dataLen += 4; return (pMsg + 2); } /* 读取 浮充充电阈值电流 */ else if (dataType == float_I) { uint16_t tempU16 = (uint16_t)(g_cfgParameter.floatI * floatMagnification); *(*outData + 2) = (uint8_t)(tempU16 >> 8); *(*outData + 3) = (uint8_t)(tempU16 & 0x00FF); *outData += 4; *dataLen += 4; return (pMsg + 2); } /* 读取 启动充电太阳能板开路电压 */ else if (dataType == start_Solar_Open_Circuit_V) { uint16_t tempU16 = (uint16_t)(g_cfgParameter.startSolarOpenCircuitV * floatMagnification); *(*outData + 2) = (uint8_t)(tempU16 >> 8); *(*outData + 3) = (uint8_t)(tempU16 & 0x00FF); *outData += 4; *dataLen += 4; return (pMsg + 2); } /* 读取 电源盒类型 */ else if (dataType == stop_Solar_Output_Circuit_V) { uint16_t tempU16 = (uint16_t)(g_cfgParameter.stopSolarOutputCircuitV * floatMagnification); *(*outData + 2) = (uint8_t)(tempU16 >> 8); *(*outData + 3) = (uint8_t)(tempU16 & 0x00FF); *outData += 4; *dataLen += 4; return (pMsg + 2); } /* 读取 检测能否启动间隔时间 */ else if (dataType == check_Can_Start_Time) { uint16_t tempU16 = g_cfgParameter.checkCanStartTime; *(*outData + 2) = (uint8_t)(tempU16 >> 8); *(*outData + 3) = (uint8_t)(tempU16 & 0x00FF); *outData += 4; *dataLen += 4; return (pMsg + 2); } /* 读取 短路判断延时 */ else if (dataType == short_Circuit_Judgment_Delay) { uint16_t tempU16 = g_cfgParameter.shortCircuitJudgmentDelay; *(*outData + 2) = (uint8_t)(tempU16 >> 8); *(*outData + 3) = (uint8_t)(tempU16 & 0x00FF); *outData += 4; *dataLen += 4; return (pMsg + 2); } /* 读取 前端输入功率不足判断延时 */ else if (dataType == input_Power_Low_Judgment_Delay) { uint16_t tempU16 = g_cfgParameter.inputPowerLowJudgmentDelay; *(*outData + 2) = (uint8_t)(tempU16 >> 8); *(*outData + 3) = (uint8_t)(tempU16 & 0x00FF); *outData += 4; *dataLen += 4; return (pMsg + 2); } /* 读取 前端输入功率不足再次输出延时 */ else if (dataType == input_Power_Low_Again_Output_Delay) { uint16_t tempU16 = g_cfgParameter.inputPowerLowAgainOutputDelay; *(*outData + 2) = (uint8_t)(tempU16 >> 8); *(*outData + 3) = (uint8_t)(tempU16 & 0x00FF); *outData += 4; *dataLen += 4; return (pMsg + 2); } /* 读取 第一段保护延时 */ else if (dataType == first_Stage_Protection_Delay) { uint16_t tempU16 = g_cfgParameter.firstStageProtectionDelay; *(*outData + 2) = (uint8_t)(tempU16 >> 8); *(*outData + 3) = (uint8_t)(tempU16 & 0x00FF); *outData += 4; *dataLen += 4; return (pMsg + 2); } /* 读取 第一段保护电流 */ else if (dataType == first_Stage_Protection_Curr) { uint16_t tempU16 = (uint16_t)(g_cfgParameter.firstStageProtectionCurr * floatMagnification); *(*outData + 2) = (uint8_t)(tempU16 >> 8); *(*outData + 3) = (uint8_t)(tempU16 & 0x00FF); *outData += 4; *dataLen += 4; return (pMsg + 2); } /* 读取 第二段保护延时 */ else if (dataType == second_Stage_Protection_Delay) { uint16_t tempU16 = g_cfgParameter.secondStageProtectionDelay; *(*outData + 2) = (uint8_t)(tempU16 >> 8); *(*outData + 3) = (uint8_t)(tempU16 & 0x00FF); *outData += 4; *dataLen += 4; return (pMsg + 2); } /* 读取 第二段保护电流 */ else if (dataType == second_Stage_Protection_Curr) { uint16_t tempU16 = (uint16_t)(g_cfgParameter.secondStageProtectionCurr * floatMagnification); *(*outData + 2) = (uint8_t)(tempU16 >> 8); *(*outData + 3) = (uint8_t)(tempU16 & 0x00FF); *outData += 4; *dataLen += 4; return (pMsg + 2); } /* 读取 第三段保护延时 */ else if (dataType == third_Stage_Protection_Delay) { uint32_t tempU32 = g_cfgParameter.thirdStageProtectionDelay; *(*outData + 2) = (uint8_t)(tempU32 >> 24); *(*outData + 3) = (uint8_t)(tempU32 >> 16); *(*outData + 4) = (uint8_t)(tempU32 >> 8); *(*outData + 5) = (uint8_t)(tempU32 & 0x00FF); *outData += 6; *dataLen += 6; return (pMsg + 2); } /* 读取 第三段保护电流 */ else if (dataType == third_Stage_Protection_Curr) { uint16_t tempU16 = (uint16_t)(g_cfgParameter.thirdStageProtectionCurr * floatMagnification); *(*outData + 2) = (uint8_t)(tempU16 >> 8); *(*outData + 3) = (uint8_t)(tempU16 & 0x00FF); *outData += 4; *dataLen += 4; return (pMsg + 2); } /* 读取 前端输入功率不足检测延时 */ else if (dataType == input_Power_Low_Detection_Delay) { uint16_t tempU16 = g_cfgParameter.inputPowerLowDetectionDelay; *(*outData + 2) = (uint8_t)(tempU16 >> 8); *(*outData + 3) = (uint8_t)(tempU16 & 0x00FF); *outData += 4; *dataLen += 4; return (pMsg + 2); } /* 读取 前端输入功率不足检测电压 */ else if (dataType == input_Power_Low_Detection_Volt) { uint16_t tempU16 = (uint16_t)(g_cfgParameter.inputPowerLowDetectionVolt * floatMagnification); *(*outData + 2) = (uint8_t)(tempU16 >> 8); *(*outData + 3) = (uint8_t)(tempU16 & 0x00FF); *outData += 4; *dataLen += 4; return (pMsg + 2); } /* 读取 最大太阳能板输出电压 */ else if (dataType == max_Open_Solar_Output_Circuit_V) { uint16_t tempU16 = (uint16_t)(g_cfgParameter.maxOpenSolarOutputCircuitV * floatMagnification); *(*outData + 2) = (uint8_t)(tempU16 >> 8); *(*outData + 3) = (uint8_t)(tempU16 & 0x00FF); *outData += 4; *dataLen += 4; return (pMsg + 2); } /* 读取 最大充电电流 */ else if (dataType == max_Charg_Curr) { uint16_t tempU16 = (uint16_t)(g_cfgParameter.maxChargCurr * floatMagnification); *(*outData + 2) = (uint8_t)(tempU16 >> 8); *(*outData + 3) = (uint8_t)(tempU16 & 0x00FF); *outData += 4; *dataLen += 4; return (pMsg + 2); } /* 读取 检测回路阻抗时的最小充电电流 */ else if (dataType == min_Check_Loop_Impedance_Charg_Curr) { uint16_t tempU16 = (uint16_t)(g_cfgParameter.minCheckLoopImpedanceChargCurr * floatMagnification); *(*outData + 2) = (uint8_t)(tempU16 >> 8); *(*outData + 3) = (uint8_t)(tempU16 & 0x00FF); *outData += 4; *dataLen += 4; return (pMsg + 2); } /* 读取 满功率输出温度 */ else if (dataType == full_Power_Output_Temperature) { uint16_t tempU16 = (uint16_t)(g_cfgParameter.minCheckLoopImpedanceChargCurr * floatMagnification); *(*outData + 2) = (uint8_t)(tempU16 >> 8); *(*outData + 3) = (uint8_t)(tempU16 & 0x00FF); *outData += 4; *dataLen += 4; return (pMsg + 2); } /* 读取 停止输出温度 */ else if (dataType == reduce_Power_Output_Temperature) { uint16_t tempU16 = (uint16_t)(g_cfgParameter.reducePowerOutputTemperature * floatMagnification); *(*outData + 2) = (uint8_t)(tempU16 >> 8); *(*outData + 3) = (uint8_t)(tempU16 & 0x00FF); *outData += 4; *dataLen += 4; return (pMsg + 2); } /* 读取 停止输出温度 */ else if (dataType == stop_PowerOutput_Temperature) { uint16_t tempU16 = (uint16_t)(g_cfgParameter.stopPowerOutputTemperature * floatMagnification); *(*outData + 2) = (uint8_t)(tempU16 >> 8); *(*outData + 3) = (uint8_t)(tempU16 & 0x00FF); *outData += 4; *dataLen += 4; return (pMsg + 2); } /* 读取 恒压充电时的输出电压 */ else if (dataType == constant_Voltage_Charge_V) { uint16_t tempU16 = (uint16_t)(g_cfgParameter.constantVoltageChargeV * floatMagnification); *(*outData + 2) = (uint8_t)(tempU16 >> 8); *(*outData + 3) = (uint8_t)(tempU16 & 0x00FF); *outData += 4; *dataLen += 4; return (pMsg + 2); } /* 读取 浮充充电时的输出电压 */ else if (dataType == float_ChargeV) { uint16_t tempU16 = (uint16_t)(g_cfgParameter.FloatChargeV * floatMagnification); *(*outData + 2) = (uint8_t)(tempU16 >> 8); *(*outData + 3) = (uint8_t)(tempU16 & 0x00FF); *outData += 4; *dataLen += 4; return (pMsg + 2); } /* 读取 充电时采集开路电压的间隔时间 */ else if (dataType == collect_OpenCircuit_Voltage_Time) { uint16_t tempU16 = (uint16_t)(g_cfgParameter.collectOpenCircuitVoltageTime * floatMagnification); *(*outData + 2) = (uint8_t)(tempU16 >> 8); *(*outData + 3) = (uint8_t)(tempU16 & 0x00FF); *outData += 4; *dataLen += 4; return (pMsg + 2); } return NULL; } /** * @brief 赛联协议读取寄存器 * @param device 串口设备 * pMsg 数据内容 * MsgLen 数据长度 * @retval */ void SL_MsgProcFunc_Read_Register(device_handle device, void *pMsg, uint32_t MsgLen) { // debug_printf("SL_MsgProcFunc_Read_Register\n"); uint16_t Start_Address_16 = (gw485RxBuffer[10] << 8) | gw485RxBuffer[11]; uint16_t Register_Number_16 = (gw485RxBuffer[12] << 8) | gw485RxBuffer[13]; /* 读取数据 */ uint16_t reply_Data_Content[maxReadRegAddrNumMacro] = {0}; for ( uint16_t pos = 0; pos < Register_Number_16; pos++) { for (uint16_t var = 0; var < sizeof(g_RegTblR) / sizeof(SL_RegProcTable); var++) { if (g_RegTblR[var].regId == (Start_Address_16 + pos)) { reply_Data_Content[pos] = g_RegTblR[var].pRegProc(NULL); } } } uint8_t *replay_pack = getInsertData(); /* 起始标志 */ *(replay_pack) = g_cfgParameter.startFlagSL[0]; *(replay_pack + 1) = g_cfgParameter.startFlagSL[1]; /* 地址 */ replay_pack += 2; *(replay_pack) = g_cfgParameter.uniqueDeviceID[0]; *(replay_pack + 1) = g_cfgParameter.uniqueDeviceID[1]; *(replay_pack + 2) = g_cfgParameter.uniqueDeviceID[2]; *(replay_pack + 3) = g_cfgParameter.uniqueDeviceID[3]; *(replay_pack + 4) = g_cfgParameter.uniqueDeviceID[4]; *(replay_pack + 5) = g_cfgParameter.uniqueDeviceID[5]; *(replay_pack + 6) = g_cfgParameter.uniqueDeviceID[6]; /* 功能码 */ replay_pack += 7; *replay_pack = SL_Function_Code_Read_Register; /* 回复字节数长度 */ replay_pack += 1; *replay_pack = (uint8_t)((Register_Number_16 * 2) >> 8); *(replay_pack + 1) = (uint8_t)(Register_Number_16 * 2); /* 回复数据内容 */ replay_pack += 2; for (uint8_t var = 0; var < Register_Number_16 * 2; var++) { if (0 == (var & 0x01)) { *(replay_pack + var) = (uint8_t)(reply_Data_Content[var / 2] >> 8); } else { *(replay_pack + var) = (uint8_t)(reply_Data_Content[var / 2]); } } /* 校验位 */ replay_pack += Register_Number_16 * 2; uint16_t packLen = 2 + 7 + 1 + 2 + Register_Number_16 * 2 + 3; uint16_t crc_temp = checkModebusCrc(getInsertData(), packLen - 3); *replay_pack = (uint8_t)(crc_temp >> 8); replay_pack += 1; *replay_pack = (uint8_t)crc_temp; /* 结束标志 */ replay_pack += 1; *replay_pack = g_cfgParameter.endFlagSL; uart_insertDataSend(device, packLen); } /** * @brief 赛联协议写入寄存器 * @param device 串口设备 * pMsg 数据内容 * MsgLen 数据长度 * @retval */ void SL_MsgProcFunc_Write_Register(device_handle device, void *pMsg, uint32_t MsgLen) { // debug_printf("SL_MsgProcFunc_Write_Register\n"); uint16_t Register_Start_Address = (gw485RxBuffer[10] << 8) | gw485RxBuffer[11]; uint16_t Register_Number = (gw485RxBuffer[12] << 8) | gw485RxBuffer[13]; /* 将指令中的数据读取出来 */ uint16_t content[maxWriteRegAddrNumMacro] = {0}; for (uint16_t var = 0; var < Register_Number; var++) { content[var] = gw485RxBuffer[14 + 2 * var] << 8 | gw485RxBuffer[14 + 2 * var + 1]; } // debug_printf("Register_Start_Address : %x \n", Register_Start_Address); // debug_printf("Register_Number : %x \n", Register_Number); // debug_printf("content : %x \n", content[0]); /* 将数据写入到寄存器中 */ for ( uint16_t pos = 0; pos < Register_Number; pos++) { for (uint16_t i = 0; i < sizeof(g_RegTblW) / sizeof(SL_RegProcTable); i++) { // debug_printf("g_RegTblW[i].regId : %x \n", g_RegTblW[i].regId); // debug_printf("Register_Start_Address : %x \n", (Register_Start_Address + pos)); if (g_RegTblW[i].regId == (Register_Start_Address + pos)) { g_RegTblW[i].pRegProc(&content[pos]); } } } } /** * @brief 赛联协议扫描广播帧 * @param device 串口设备 * pMsg 数据内容 * MsgLen 数据长度 * @retval */ void SL_MsgProcFunc_Broadcast_Scan(device_handle device, void *pMsg, uint32_t MsgLen) { debug_printf("SL_MsgProcFunc_Broadcast_Scan\n"); } /** * @brief 赛联协议注册回复帧 * @param device 串口设备 * pMsg 数据内容 * MsgLen 数据长度 * @retval */ void SL_MsgProcFunc_Registration_request(device_handle device, void *pMsg, uint32_t MsgLen) { debug_printf("SL_MsgProcFunc_Registration_request\n"); } /** * @brief 赛联协议写入配置文件 * @param device 串口设备 * pMsg 数据内容 * MsgLen 数据长度 * @retval */ void SL_MsgProcFunc_Distribution_Profile(device_handle device, void *pMsg, uint32_t MsgLen) { debug_printf("SL_MsgProcFunc_Distribution_Profile\n"); /* 确保帧不乱序,依次发完 */ static uint8_t flag = 0; static config_info cfgInfo = {0}; // config_info cfgInfo = {0}; uint8_t *replay_pack = getInsertData(); if (replay_pack == NULL) { return; } uint16_t crc_temp; uint8_t *analysisData; uint32_t tickstart1; /* 起始标志 */ *(replay_pack) = g_cfgParameter.startFlagSL[0]; *(replay_pack + 1) = g_cfgParameter.startFlagSL[1]; /* 地址 */ replay_pack += 2; *(replay_pack) = g_cfgParameter.uniqueDeviceID[0]; *(replay_pack + 1) = g_cfgParameter.uniqueDeviceID[1]; *(replay_pack + 2) = g_cfgParameter.uniqueDeviceID[2]; *(replay_pack + 3) = g_cfgParameter.uniqueDeviceID[3]; *(replay_pack + 4) = g_cfgParameter.uniqueDeviceID[4]; *(replay_pack + 5) = g_cfgParameter.uniqueDeviceID[5]; *(replay_pack + 6) = g_cfgParameter.uniqueDeviceID[6]; /* 功能码 */ replay_pack += 7; *replay_pack = SL_Function_Code_Distribution_Profile; /* 回复字节数长度 */ replay_pack += 1; *replay_pack = 0x00; replay_pack += 1; *replay_pack = 0x01; /* 一分钟内都未接收到完整的配置文件,之前下发的配置文件都丢弃 */ if (gw485CfgFlag == 2) { flag = 0; gw485CfgFlag = 0; // goto wholePackageError; } /* 传输帧的顺序不对 */ if (*((uint8_t *)pMsg + 10) <= flag || (*((uint8_t *)pMsg + 10) > *((uint8_t *)pMsg + 11))) { flag = 0; goto wholePackageError; } /* 传输的第一帧数据 */ if (*((uint8_t *)pMsg + 10) == 1) { gw485CfgTime = 0; gw485CfgFlag = 1; readFlashContent(&cfgInfo); } analysisData = pMsg; analysisData += 14; /* 解析一包的时间小于2ms */ tickstart1 = HAL_GetTick(); while ((analysisData != (((uint8_t *)pMsg + MsgLen) - 3)) && (analysisData != NULL) && ((HAL_GetTick() - tickstart1) < 100)) { analysisData = analysisDistributionProfile(analysisData, &cfgInfo); } if (((HAL_GetTick() - tickstart1) >= 100) || (analysisData == NULL)) { goto singlePackageError; } else if (*((uint8_t *)pMsg + 10) < *((uint8_t *)pMsg + 11)) { flag++; goto singlePackageCorrect; } else { flag = 0; // gw485CfgTime = 0; gw485CfgFlag = 0; goto wholePackageCorrect; } /* 整个数据包正确 */ wholePackageCorrect: /* 回复内容 */ replay_pack += 1; *replay_pack = 0xAA; /* 校验位 */ replay_pack += 1; crc_temp = checkModebusCrc(getInsertData(), 13); *replay_pack = (uint8_t)(crc_temp >> 8); replay_pack += 1; *replay_pack = (uint8_t)crc_temp; /* 结束标志 */ replay_pack += 1; *replay_pack = g_cfgParameter.endFlagSL; uart_insertDataSend(device, 16); cfgInfo.crc = checkModebusCrc((uint8_t *)&cfgInfo, CONFIG_INFO_SIZE - 2); saveConfigInfo(&cfgInfo); // float tempF; // tempF = getTotalElectricityConsumption(); // savetotalElectricityConsumption(&tempF); // tempF = getTotalChargCapacity(); // savetotalChargCapacity(&tempF); // timeInfo time; // time = getLastTime(); // saveTime(&time); return; /* 整个数据包错误 */ wholePackageError: /* 回复内容 */ replay_pack += 1; *replay_pack = 0x00; /* 校验位 */ crc_temp = checkModebusCrc(getInsertData(), 13); replay_pack += 1; *replay_pack = (uint8_t)(crc_temp >> 8); replay_pack += 1; *replay_pack = (uint8_t)crc_temp; /* 结束标志 */ replay_pack += 1; *replay_pack = g_cfgParameter.endFlagSL; uart_insertDataSend(device, 16); return; /* 当前数据包正确 */ singlePackageCorrect: /* 回复内容 */ replay_pack += 1; *replay_pack = 0x55; /* 校验位 */ crc_temp = checkModebusCrc(getInsertData(), 13); replay_pack += 1; *replay_pack = (uint8_t)(crc_temp >> 8); replay_pack += 1; *replay_pack = (uint8_t)crc_temp; /* 结束标志 */ replay_pack += 1; *replay_pack = g_cfgParameter.endFlagSL; uart_insertDataSend(device, 16); return; /* 当前数据包错误 */ singlePackageError: /* 回复内容 */ replay_pack += 1; *replay_pack = *((uint8_t *)pMsg + 10); /* 校验位 */ crc_temp = checkModebusCrc(getInsertData(), 13); replay_pack += 1; *replay_pack = (uint8_t)(crc_temp >> 8); replay_pack += 1; *replay_pack = (uint8_t)crc_temp; /* 结束标志 */ replay_pack += 1; *replay_pack = g_cfgParameter.endFlagSL; uart_insertDataSend(device, 16); return; } /** * @brief 赛联协议读取配置文件 * @param device 串口设备 * pMsg 数据内容 * MsgLen 数据长度 * @retval */ void SL_MsgProcFunc_Read_Profile(device_handle device, void *pMsg, uint32_t MsgLen) { debug_printf("SL_MsgProcFunc_Read_Profile\n"); uint8_t *replay_pack = getInsertData(); if (replay_pack == NULL) { return; } /* 起始标志 */ *(replay_pack) = g_cfgParameter.startFlagSL[0]; *(replay_pack + 1) = g_cfgParameter.startFlagSL[1]; /* 地址 */ replay_pack += 2; *(replay_pack) = g_cfgParameter.uniqueDeviceID[0]; *(replay_pack + 1) = g_cfgParameter.uniqueDeviceID[1]; *(replay_pack + 2) = g_cfgParameter.uniqueDeviceID[2]; *(replay_pack + 3) = g_cfgParameter.uniqueDeviceID[3]; *(replay_pack + 4) = g_cfgParameter.uniqueDeviceID[4]; *(replay_pack + 5) = g_cfgParameter.uniqueDeviceID[5]; *(replay_pack + 6) = g_cfgParameter.uniqueDeviceID[6]; /* 功能码 */ replay_pack += 7; *replay_pack = SL_Function_Code_Read_Profile; replay_pack += 1; replay_pack += 2; uint16_t replayPackDatalen = 0; uint8_t *analysisData = pMsg; analysisData += 12; /* 解析一包的时间小于100ms */ uint16_t tickstart1 = HAL_GetTick(); while ((analysisData != (((uint8_t *)pMsg + MsgLen) - 3)) && (analysisData != NULL) && ((HAL_GetTick() - tickstart1) < 100)) { analysisData = analysisReadProfile(analysisData, &replay_pack, &replayPackDatalen); } if (((HAL_GetTick() - tickstart1) >= 100) || (analysisData == NULL)) { return; } uint8_t *replay_pack1 = getInsertData(); *(replay_pack1 + 10) = (uint8_t)(replayPackDatalen >> 8); *(replay_pack1 + 11) = (uint8_t)(replayPackDatalen); /* 校验位 */ // replay_pack += replayPackDatalen; uint16_t crc_temp = checkModebusCrc(getInsertData(), 12 + replayPackDatalen); // replay_pack += 1; *replay_pack = (uint8_t)(crc_temp >> 8); replay_pack += 1; *replay_pack = (uint8_t)crc_temp; /* 结束标志 */ replay_pack += 1; *replay_pack = g_cfgParameter.endFlagSL; uart_insertDataSend(device, 15 + replayPackDatalen); } /** * @brief 赛联协议读取SOE * @param device 串口设备 * pMsg 数据内容 * MsgLen 数据长度 * @retval */ void SL_MsgProcFunc_Read_SOE(device_handle device, void *pMsg, uint32_t MsgLen) { debug_printf("SL_MsgProcFunc_Read_SOE\n"); uint8_t *replay_pack = getInsertData(); if (replay_pack == NULL) { return; } /* 起始标志 */ *(replay_pack) = g_cfgParameter.startFlagSL[0]; *(replay_pack + 1) = g_cfgParameter.startFlagSL[1]; /* 地址 */ replay_pack += 2; *(replay_pack) = g_cfgParameter.uniqueDeviceID[0]; *(replay_pack + 1) = g_cfgParameter.uniqueDeviceID[1]; *(replay_pack + 2) = g_cfgParameter.uniqueDeviceID[2]; *(replay_pack + 3) = g_cfgParameter.uniqueDeviceID[3]; *(replay_pack + 4) = g_cfgParameter.uniqueDeviceID[4]; *(replay_pack + 5) = g_cfgParameter.uniqueDeviceID[5]; *(replay_pack + 6) = g_cfgParameter.uniqueDeviceID[6]; /* 功能码 */ replay_pack += 7; *replay_pack = SL_Function_Code_Read_SOE; /* 数据内容长度 */ uint16_t replayPackDatalen = (*((uint8_t *)pMsg + 11)) * getSoeDataInfoSize(); replay_pack += 1; *replay_pack = (uint8_t)(replayPackDatalen >> 8); replay_pack += 1; *replay_pack = (uint8_t)replayPackDatalen; /* 数据内容 */ replay_pack += 1; for (uint16_t i = 1; i <= (*((uint8_t *)pMsg + 11)); i++) { readEventsOrderRecord((*((uint8_t *)pMsg + 10)) + i, replay_pack); replay_pack += getSoeDataInfoSize(); } /* 校验位 */ uint16_t crc_temp = checkModebusCrc(getInsertData(), 12 + replayPackDatalen); *replay_pack = (uint8_t)(crc_temp >> 8); replay_pack += 1; *replay_pack = (uint8_t)crc_temp; /* 结束标志 */ replay_pack += 1; *replay_pack = g_cfgParameter.endFlagSL; uart_insertDataSend(device, 15 + replayPackDatalen); }