2324 lines
72 KiB
C
2324 lines
72 KiB
C
|
||
#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);
|
||
}
|
||
|