From bccfc0c450326a45d4742f3c17c94bdd3b352700 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B5=B7=E5=BA=8A=E5=B0=B1=E7=8A=AF=E5=9B=B0?= <11730503+psx123456@user.noreply.gitee.com> Date: Wed, 8 Jan 2025 17:50:37 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E6=95=B0=E6=8D=AE=E8=A7=A3?= =?UTF-8?q?=E6=9E=90=E6=96=B9=E5=BC=8F=EF=BC=8C=E6=B7=BB=E5=8A=A0=E9=85=8D?= =?UTF-8?q?=E7=BD=AE=E6=96=87=E4=BB=B6=E8=AF=BB=E5=8F=96=E5=92=8C=E4=B8=8B?= =?UTF-8?q?=E5=8F=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- APP/application/Src/start.c | 70 +- APP/businessLogic/Inc/bl_usart.h | 9 +- APP/businessLogic/Inc/inFlash.h | 163 ++- APP/businessLogic/Inc/interruptSend.h | 3 + APP/businessLogic/Inc/parameter.h | 90 +- APP/businessLogic/Src/Init.c | 5 +- APP/businessLogic/Src/abnormalManage.c | 11 +- APP/businessLogic/Src/bl_chargControl.c | 8 +- APP/businessLogic/Src/bl_usart.c | 1645 ++++++++++++++++++++++- APP/businessLogic/Src/inFlash.c | 240 ++-- APP/businessLogic/Src/interruptSend.c | 55 +- APP/businessLogic/Src/parameter.c | 57 +- APP/businessLogic/Src/task.c | 74 +- APP/functionalModule/Inc/capture.h | 1 + APP/functionalModule/Src/FM_GPIO.c | 3 +- APP/functionalModule/Src/capture.c | 23 +- tools/chargControlTypes.h | 5 +- tools/pDebug.h | 4 +- 18 files changed, 2068 insertions(+), 398 deletions(-) diff --git a/APP/application/Src/start.c b/APP/application/Src/start.c index 0815962..b48d966 100644 --- a/APP/application/Src/start.c +++ b/APP/application/Src/start.c @@ -7,49 +7,51 @@ #include "parameter.h" #include "FM_TIM.h" + void startInfo(void) { + log_info("uniqueDeviceID : 0x%x%x%x%x%x%x%x \n", g_cfgParameter.uniqueDeviceID[0] + , g_cfgParameter.uniqueDeviceID[1] + , g_cfgParameter.uniqueDeviceID[2] + , g_cfgParameter.uniqueDeviceID[3] + , g_cfgParameter.uniqueDeviceID[4] + , g_cfgParameter.uniqueDeviceID[5] + , g_cfgParameter.uniqueDeviceID[6]); + log_info("gw485_Baud : %d \n", g_cfgParameter.gw485_Baud); + log_info("bat485_Baud : %d \n", g_cfgParameter.bat485_Baud); + log_info("powerBoxType : 0x%x \n", g_cfgParameter.powerBoxType); log_info("constantVoltageV : %f \n", g_cfgParameter.constantVoltageV); log_info("floatI : %f \n", g_cfgParameter.floatI); log_info("startSolarOpenCircuitV : %f \n", g_cfgParameter.startSolarOpenCircuitV); - log_info("stopSolarOpenCircuitV : %f \n", g_cfgParameter.stopSolarOpenCircuitV); + log_info("stopSolarOutputCircuitV : %f \n", g_cfgParameter.stopSolarOutputCircuitV); + log_info("checkCanStartTime : %d \n", g_cfgParameter.checkCanStartTime); + log_info("shortCircuitJudgmentDelay : %d \n", g_cfgParameter.shortCircuitJudgmentDelay); + log_info("inputPowerLowJudgmentDelay : %d \n", g_cfgParameter.inputPowerLowJudgmentDelay); + log_info("inputPowerLowAgainOutputDelay : %d \n", g_cfgParameter.inputPowerLowAgainOutputDelay); + log_info("firstStageProtectionDelay : %d \n", g_cfgParameter.firstStageProtectionDelay); + log_info("firstStageProtectionValue : %d \n", g_cfgParameter.firstStageProtectionValue); + log_info("firstStageProtectionCurr : %f \n", g_cfgParameter.firstStageProtectionCurr); + log_info("secondStageProtectionDelay : %d \n", g_cfgParameter.secondStageProtectionDelay); + log_info("secondStageProtectionCurr : %f \n", g_cfgParameter.secondStageProtectionCurr); + log_info("thirdStageProtectionDelay : %d \n", g_cfgParameter.thirdStageProtectionDelay); + log_info("thirdStageProtectionCurr : %f \n", g_cfgParameter.thirdStageProtectionCurr); + log_info("inputPowerLowDetectionDelay : %d \n", g_cfgParameter.inputPowerLowDetectionDelay); + log_info("inputPowerLowDetectionVolt : %f \n", g_cfgParameter.inputPowerLowDetectionVolt); + log_info("maxOpenSolarOutputCircuitV : %f \n", g_cfgParameter.maxOpenSolarOutputCircuitV); + log_info("maxChargCurr : %f \n", g_cfgParameter.maxChargCurr); + log_info("minCheckLoopImpedanceChargCurr : %f \n", g_cfgParameter.minCheckLoopImpedanceChargCurr); + log_info("fullPowerOutputTemperature : %f \n", g_cfgParameter.fullPowerOutputTemperature); + log_info("reducePowerOutputTemperature : %f \n", g_cfgParameter.reducePowerOutputTemperature); + log_info("stopPowerOutputTemperature : %f \n", g_cfgParameter.stopPowerOutputTemperature); log_info("constantVoltageChargeV : %f \n", g_cfgParameter.constantVoltageChargeV); - log_info("FloatV : %f \n", g_cfgParameter.FloatV); - log_info("loopImpedance : %f \n", g_cfgParameter.loopImpedance); - log_info("HighSideMosTemperature_stop : %f \n", g_cfgParameter.HighSideMosTemperature_stop); - log_info("HighSideMosTemperature_end : %f \n", g_cfgParameter.HighSideMosTemperature_end); - log_info("HighSideMosTemperature_start : %f \n", g_cfgParameter.HighSideMosTemperature_start); - log_info("outputAgainFlagTime : %d \n", g_cfgParameter.outputAgainFlagTime); - log_info("excessiveLoadFlagTime : %d \n", g_cfgParameter.excessiveLoadFlagTime); + log_info("FloatChargeV : %f \n", g_cfgParameter.FloatChargeV); log_info("collectOpenCircuitVoltageTime : %d \n", g_cfgParameter.collectOpenCircuitVoltageTime); - log_info("Access_Node_Type : %d \n", g_cfgParameter.Access_Node_Type); - log_info("Communication_Methods : %d \n", g_cfgParameter.Communication_Methods); - log_info("Registration_Status : %d \n", g_cfgParameter.Registration_Status); - log_info("address : 0x%x%x%x%x%x%x%x \n", g_cfgParameter.address[0] - , g_cfgParameter.address[1] - , g_cfgParameter.address[2] - , g_cfgParameter.address[3] - , g_cfgParameter.address[4] - , g_cfgParameter.address[5] - , g_cfgParameter.address[6]); + log_info("Access_Node_Type : %x \n", g_cfgParameter.Access_Node_Type); + log_info("Communication_Methods : %x \n", g_cfgParameter.Communication_Methods); log_info("startFlagSL : 0x%x%x \n", g_cfgParameter.startFlagSL[0], g_cfgParameter.startFlagSL[1]); log_info("endFlagSL : 0x%x \n", g_cfgParameter.endFlagSL); - log_info("hardwareID : 0x%x%x%x%x%x%x \n", g_cfgParameter.hardwareID[0] - , g_cfgParameter.hardwareID[1] - , g_cfgParameter.hardwareID[2] - , g_cfgParameter.hardwareID[3] - , g_cfgParameter.hardwareID[4] - , g_cfgParameter.hardwareID[5]); - log_info("communicationID : 0x%x%x%x%x \n", g_cfgParameter.communicationID[0] - , g_cfgParameter.communicationID[1] - , g_cfgParameter.communicationID[2] - , g_cfgParameter.communicationID[3]); - log_info("protocolType : 0x%x \n", g_cfgParameter.protocolType); - log_info("startFlagHY : 0x%x \n", g_cfgParameter.startFlagHY); - log_info("endFlagHY : 0x%x \n", g_cfgParameter.endFlagHY); - log_info("onlyPower : 0x%x \n", g_cfgParameter.onlyPower); - log_info("gw485_Baud : %d \n", g_cfgParameter.gw485_Baud); - log_info("gw485_Baud : %d \n", g_cfgParameter.gw485_Baud); + + log_info("loopImpedance : %f \n", getLoopImpedance()); } diff --git a/APP/businessLogic/Inc/bl_usart.h b/APP/businessLogic/Inc/bl_usart.h index e07cabb..7f54be5 100644 --- a/APP/businessLogic/Inc/bl_usart.h +++ b/APP/businessLogic/Inc/bl_usart.h @@ -24,15 +24,16 @@ /* SL协议写入寄存器最大长度 */ #define maxWriteRegAddrNumMacro 10 - /* SL协议寄存器长度 */ #define RegAddrNumMacro 32 +/* SL协议下发配置文件内容最长长度 */ +#define maxDistributionCfgLen 230 +/* SL协议读取配置文件内容最长长度 */ +#define maxReadCfgLen 32 - - - +#define floatMagnification 10.0f uint16_t checkModebusCrc(uint8_t *arr_buff, uint8_t len); diff --git a/APP/businessLogic/Inc/inFlash.h b/APP/businessLogic/Inc/inFlash.h index b27e8ee..818e3bf 100644 --- a/APP/businessLogic/Inc/inFlash.h +++ b/APP/businessLogic/Inc/inFlash.h @@ -9,82 +9,112 @@ #pragma pack(push, 1) -/* 高字节在前,低字节在后 */ -typedef struct _recv_config_info{ - uint8_t start_Flag[2]; /* 开始标志 */ - /* SL */ - uint8_t address[7]; /* 地址 */ - // uint8_t Access_Node_Type[2]; /* 接入节点类型 */ - // uint8_t Communication_Methods[2]; /* 通信方式 */ - uint8_t gw485_Baud[4]; /* 串口波特率 */ - uint8_t bat485_Baud[4]; /* 串口波特率,为0代表bms不支持通信 */ +// /* 高字节在前,低字节在后 */ +// typedef struct _recv_config_info{ +// uint8_t start_Flag[2]; /* 开始标志 */ +// /* SL */ +// uint8_t address[7]; /* 地址 */ +// // uint8_t Access_Node_Type[2]; /* 接入节点类型 */ +// // uint8_t Communication_Methods[2]; /* 通信方式 */ +// uint8_t gw485_Baud[4]; /* 串口波特率 */ +// uint8_t bat485_Baud[4]; /* 串口波特率,为0代表bms不支持通信 */ - /* HY */ - uint8_t hardwareID[6]; /* 硬件ID */ - uint8_t communicationID[4]; /* 通信ID */ - uint8_t protocolType; /* 协议类型; 0x01表示:汇源协议(波特率9600) 0x02表示:南瑞协议(波特率115200)*/ +// /* HY */ +// uint8_t hardwareID[6]; /* 硬件ID */ +// uint8_t communicationID[4]; /* 通信ID */ +// uint8_t protocolType; /* 协议类型; 0x01表示:汇源协议(波特率9600) 0x02表示:南瑞协议(波特率115200)*/ - uint8_t CommunicationProtocolType; /* 0x00:SL - 0x01:HY*/ - uint8_t onlyPower; /* 是否只充当电源板:0x00:不是 - 0x01:是*/ +// uint8_t CommunicationProtocolType; /* 0x00:SL +// 0x01:HY*/ +// uint8_t onlyPower; /* 是否只充当电源板:0x00:不是 +// 0x01:是*/ - uint8_t ConstantVoltageV[2]; /* 高于该(电压 / 100)且电流大于FloatI * 100进行恒压充电 */ - uint8_t FloatI[2]; /* 高于该(电压 / 100)且电流低于FloatI * 100进行浮充充电 */ - uint8_t startSolarOpenCircuitV[2]; /* 高于该(电压 / 100)开始充电 */ - uint8_t stopSolarOpenCircuitV[2]; /* 太阳能板开路电压高于该电压停止充电 (V) */ - uint8_t constantVoltageChargeV[2]; /* 恒压充电时的输出电压 (V) */ - uint8_t FloatChargeV[2]; /* 浮充充电时的输出电压 (V) */ - uint8_t HighSideMosTemperature_stop[2]; /* 当上桥温度达到该值时,停止输出 (°C) */ - uint8_t HighSideMosTemperature_end[2]; /* 当上桥温度上升到该值时,降低功率运行 (°C) */ - uint8_t HighSideMosTemperature_start[2];/* 当上桥温度降低到该值时,按照正常情况输出 (°C) */ +// uint8_t ConstantVoltageV[2]; /* 高于该(电压 / 100)且电流大于FloatI * 100进行恒压充电 */ +// uint8_t FloatI[2]; /* 高于该(电压 / 100)且电流低于FloatI * 100进行浮充充电 */ +// uint8_t startSolarOpenCircuitV[2]; /* 高于该(电压 / 100)开始充电 */ +// uint8_t stopSolarOpenCircuitV[2]; /* 太阳能板开路电压高于该电压停止充电 (V) */ +// uint8_t constantVoltageChargeV[2]; /* 恒压充电时的输出电压 (V) */ +// uint8_t FloatChargeV[2]; /* 浮充充电时的输出电压 (V) */ +// uint8_t HighSideMosTemperature_stop[2]; /* 当上桥温度达到该值时,停止输出 (°C) */ +// uint8_t HighSideMosTemperature_end[2]; /* 当上桥温度上升到该值时,降低功率运行 (°C) */ +// uint8_t HighSideMosTemperature_start[2];/* 当上桥温度降低到该值时,按照正常情况输出 (°C) */ - // uint8_t checkSolarOpenCircuitVTime[2]; /* 启动任务中太阳能板开路电压检测间隔时间 (S) */ - // uint8_t sensorEnableBroadcastTime[2]; /* 传感器运行再次注册的间隔 (S) */ - uint8_t outputAgainFlagTime[2]; /* 出现短路保护后延长该段时间再次检测是否短路,仍然短路则关闭输出 (S) */ - uint8_t excessiveLoadFlagTime[2]; /* 出现过载后,在该间隔时间中多次(2次)出现过载,则关闭输出 (S) */ - uint8_t eLAgainTime[2]; /* 出现过载过载保护后,在该间隔段时间后,再次尝试输出 (S) */ - uint8_t crc[2]; /* 校验 */ - uint8_t end_Flag; /* 结束标志 */ -}recv_config_info; -#define RECV_CONFIG_INFO sizeof(recv_config_info) +// // uint8_t checkSolarOpenCircuitVTime[2]; /* 启动任务中太阳能板开路电压检测间隔时间 (S) */ +// // uint8_t sensorEnableBroadcastTime[2]; /* 传感器运行再次注册的间隔 (S) */ +// uint8_t outputAgainFlagTime[2]; /* 出现短路保护后延长该段时间再次检测是否短路,仍然短路则关闭输出 (S) */ +// uint8_t excessiveLoadFlagTime[2]; /* 出现过载后,在该间隔时间中多次(2次)出现过载,则关闭输出 (S) */ +// uint8_t eLAgainTime[2]; /* 出现过载过载保护后,在该间隔段时间后,再次尝试输出 (S) */ +// uint8_t crc[2]; /* 校验 */ +// uint8_t end_Flag; /* 结束标志 */ +// }recv_config_info; +// #define RECV_CONFIG_INFO sizeof(recv_config_info) typedef struct _config_info{ - /* SL */ - uint8_t address[7]; /* 地址 */ - // uint16_t Access_Node_Type; /* 接入节点类型 */ - // uint16_t Communication_Methods; /* 通信方式 */ - uint32_t gw485_Baud; /* 串口波特率,为0代表bms不支持通信 */ - uint32_t bat485_Baud; /* 串口波特率 */ + // /* SL */ + // uint8_t address[7]; /* 地址 */ + // // uint16_t Access_Node_Type; /* 接入节点类型 */ + // // uint16_t Communication_Methods; /* 通信方式 */ + // uint32_t gw485_Baud; /* 串口波特率,为0代表bms不支持通信 */ + // uint32_t bat485_Baud; /* 串口波特率 */ - /* HY */ - uint8_t hardwareID[6]; /* 硬件ID */ - uint8_t communicationID[4]; /* 通信ID */ - uint8_t protocolType; /* 协议类型; 0x01表示:汇源协议(波特率9600) 0x02表示:南瑞协议(波特率115200)*/ + // /* HY */ + // uint8_t hardwareID[6]; /* 硬件ID */ + // uint8_t communicationID[4]; /* 通信ID */ + // uint8_t protocolType; /* 协议类型; 0x01表示:汇源协议(波特率9600) 0x02表示:南瑞协议(波特率115200)*/ - uint8_t CommunicationProtocolType; /* 0x00:SL - 0x01:HY*/ - uint8_t onlyPower; /* 是否只充当电源板:0x00:不是 - 0x01:是*/ + // uint8_t CommunicationProtocolType; /* 0x00:SL + // 0x01:HY*/ + // uint8_t onlyPower; /* 是否只充当电源板:0x00:不是 + // 0x01:是*/ - float constantVoltageV; /* 电压高于ConstantVoltageV且电流大于FloatI + 0.1)进行恒压充电 */ - float floatI; /* 电压高于ConstantVoltageV且电流低于FloatI进行浮充充电 */ - float startSolarOpenCircuitV; /* 太阳能板开路电压高于该电压开始充电 */ - float stopSolarOpenCircuitV; /* 太阳能板开路电压高于该电压 停止充电 */ - float constantVoltageChargeV; /* 恒压充电时的输出电压 */ - float FloatChargeV; /* 浮充电压 */ - float HighSideMosTemperature_stop; /* 当上桥温度达到该值时,停止输出 */ - float HighSideMosTemperature_end; /* 当上桥温度上升到该值时,降低功率运行 */ - float HighSideMosTemperature_start; /* 当上桥温度降低到该值时,按照正常情况输出 */ + // float constantVoltageV; /* 电压高于ConstantVoltageV且电流大于FloatI + 0.1)进行恒压充电 */ + // float floatI; /* 电压高于ConstantVoltageV且电流低于FloatI进行浮充充电 */ + // float startSolarOpenCircuitV; /* 太阳能板开路电压高于该电压开始充电 */ + // float stopSolarOpenCircuitV; /* 太阳能板开路电压高于该电压 停止充电 */ + // float constantVoltageChargeV; /* 恒压充电时的输出电压 */ + // float FloatChargeV; /* 浮充电压 */ + // float HighSideMosTemperature_stop; /* 当上桥温度达到该值时,停止输出 */ + // float HighSideMosTemperature_end; /* 当上桥温度上升到该值时,降低功率运行 */ + // float HighSideMosTemperature_start; /* 当上桥温度降低到该值时,按照正常情况输出 */ - // uint16_t checkSolarOpenCircuitVTime; /* 启动任务中太阳能板开路电压检测时间 */ - // uint16_t sensorEnableBroadcastTime; /* 传感器运行再次注册的间隔 */ - uint16_t outputAgainFlagTime; /* 出现短路保护后延长该段时间再次检测是否短路,仍然短路则关闭输出 */ - uint16_t excessiveLoadFlagTime; /* 出现过载后,在该段时间中再次出现过载,则关闭输出 */ - uint16_t eLAgainTime; /* 出现过载过载保护后,该段时间后,再次尝试输出 */ + // // uint16_t checkSolarOpenCircuitVTime; /* 启动任务中太阳能板开路电压检测时间 */ + // // uint16_t sensorEnableBroadcastTime; /* 传感器运行再次注册的间隔 */ + // uint16_t outputAgainFlagTime; /* 出现短路保护后延长该段时间再次检测是否短路,仍然短路则关闭输出 */ + // uint16_t excessiveLoadFlagTime; /* 出现过载后,在该段时间中再次出现过载,则关闭输出 */ + // uint16_t eLAgainTime; /* 出现过载过载保护后,该段时间后,再次尝试输出 */ - uint16_t crc; /* 校验 */ + uint8_t uniqueDeviceID[7]; /* 设备唯一ID */ + uint32_t gw485_Baud; /* 串口波特率 */ + uint32_t bat485_Baud; /* 串口波特率,为0代表bms不支持通信 */ + uint8_t powerBoxType; /* 是否只充当电源板:0x00:不是;0x01:是*/ + float constantVoltageV; /* 恒压充电阈值电压(V) */ + float floatI; /* 浮充充电阈值电流(A) */ + float startSolarOpenCircuitV; /* 启动充电太阳能板开路电压(V) */ + float stopSolarOutputCircuitV; /* 停止充电太阳能板输出电压(V) */ + uint16_t checkCanStartTime; /* 检测能否启动间隔时间(S) */ + uint16_t shortCircuitJudgmentDelay; /* 短路判断延时(S) */ + uint16_t inputPowerLowJudgmentDelay; /* 前端输入功率不足判断延时(S) */ + uint16_t inputPowerLowAgainOutputDelay; /* 前端输入功率不足再次输出延时(S) */ + uint16_t firstStageProtectionDelay; /* 第一段保护延时(10uS) */ + float firstStageProtectionCurr; /* 第一段保护电流(A) */ + uint16_t secondStageProtectionDelay; /* 第二段保护延时(100uS) */ + float secondStageProtectionCurr; /* 第二段保护电流(A) */ + uint32_t thirdStageProtectionDelay; /* 第三段保护延时(100uS) */ + float thirdStageProtectionCurr; /* 第三段保护电流(A) */ + uint16_t inputPowerLowDetectionDelay; /* 前端输入功率不足检测延时(100uS) */ + float inputPowerLowDetectionVolt; /* 前端输入功率不足检测电压(V) */ + float maxOpenSolarOutputCircuitV; /* 最大太阳能板输出电压(V) */ + float maxChargCurr; /* 最大充电电流(A) */ + float minCheckLoopImpedanceChargCurr; /* 检测回路阻抗时的最小充电电流(A) */ + float fullPowerOutputTemperature; /* 满功率输出温度(℃) */ + float reducePowerOutputTemperature; /* 降功率输出温度(℃) */ + float stopPowerOutputTemperature; /* 停止输出温度(℃) */ + float constantVoltageChargeV; /* 恒压充电时的输出电压(V) */ + float FloatChargeV; /* 浮充充电时的输出电压(V) */ + uint16_t collectOpenCircuitVoltageTime; /* 充电时采集开路电压的间隔时间 */ + + uint16_t crc; /* 校验 */ }config_info; #define CONFIG_INFO_SIZE (sizeof(config_info)) @@ -102,9 +132,10 @@ typedef struct _config_info{ void read_config_info(config_info *output_config_info); void saveConfigInfo(config_info *config_info); void config_info_start(void); +void readFlashContent(config_info *configInfo); -void saveLoopImpedance(float *loopImpedance); -void readLoopImpedance(float *loopImpedance); +void saveLoopImpedance(); +BOOL readLoopImpedance(); void savetotalElectricityConsumption(float *totalElectricityConsumption); void readtotalElectricityConsumption(float *totalElectricityConsumption); void savetotalChargCapacity(float *totalChargCapacity); diff --git a/APP/businessLogic/Inc/interruptSend.h b/APP/businessLogic/Inc/interruptSend.h index 9888995..8afe4e1 100644 --- a/APP/businessLogic/Inc/interruptSend.h +++ b/APP/businessLogic/Inc/interruptSend.h @@ -19,4 +19,7 @@ void send_init(void); void check_sendState(void); void uart_interruptSend(device_handle device, uint8_t buff[], uint8_t len); +uint8_t *getInsertData(void); +void uart_insertDataSend(device_handle device, uint8_t len); + #endif \ No newline at end of file diff --git a/APP/businessLogic/Inc/parameter.h b/APP/businessLogic/Inc/parameter.h index 5419ed0..26bf846 100644 --- a/APP/businessLogic/Inc/parameter.h +++ b/APP/businessLogic/Inc/parameter.h @@ -10,62 +10,44 @@ /* 主要有配置文件读取出来的数据 */ typedef struct _config_parameter{ - float constantVoltageV; /* 电压高于ConstantVoltageV且电流大于(FloatI + 0.1)进行恒压充电 - 电压低于该(ConstantVoltageV - 0.2) 进行恒流充电 (V) */ - float floatI; /* 电压高于该ConstantVoltageV且电流低于FloatI进行浮充充电 (A) */ - float startSolarOpenCircuitV; /* 太阳能板开路电压高于该电压开始充电 (V) */ - float stopSolarOpenCircuitV; /* 太阳能板开路电压高于该电压停止充电 (V) */ - float constantVoltageChargeV; /* 恒压充电时的输出电压 (V) */ - float FloatV; /* 浮充充电时的输出电压 (V) */ - float loopImpedance; /* 回路阻抗大小 (mΩ) */ - float HighSideMosTemperature_stop; /* 当上桥温度达到该值时,停止输出 (°C) */ - float HighSideMosTemperature_end; /* 当上桥温度上升到该值时,降低功率运行 (°C) */ - float HighSideMosTemperature_start; /* 当上桥温度降低到该值时,按照正常情况输出 (°C) */ + uint8_t uniqueDeviceID[7]; /* 设备唯一ID */ - float firstStageProtectionCurr; /* 第一段保护的电流(单位A) */ - uint16_t firstStageProtectionValue; /* 第一段保护的电流采集的ADC的值 */ - uint16_t firstStageProtectionDelay; /* 第一段保护的延时时间(单位10uS) */ - float secondStageProtectionCurr; /* 第二段保护的电流(单位A) */ - uint32_t secondStageProtectionDelay; /* 第二段保护的延时时间(单位100uS) */ - float thirdStageProtectionCurr; /* 第三段保护的电流(单位A) */ - uint32_t thirdStageProtectionDelay; /* 第三段保护的延时时间(单位100uS) */ - float checkLoopImpedanceChargCurr; /* 检测回路阻抗时的充电电流要大于该值(单位A) */ - float lowInputLoadDetectionVolt; /* 输入功率较低延时电压(单位V) */ - uint16_t lowInputLoadDetectionDelay; /* 输入功率较低延时(单位100uS) */ - float maxChargCurr; /* 最大充电电流(A) */ - float maxOpenSolarOpenCircuitV; /* 最大充电电压(V) */ - - - // uint16_t sensorEnableBroadcastTime; /* 传感器运行再次注册的间隔 (S) */ - // uint16_t checkSolarOpenCircuitVTime; /* 启动任务中太阳能板开路电压检测间隔时间 (S) */ - uint16_t outputAgainFlagTime; /* 出现短路保护后延长该段时间再次检测是否短路,仍然短路则关闭输出 (S) */ - uint16_t excessiveLoadFlagTime; /* 出现过载后,在该间隔时间中多次(2次)出现过载,则关闭输出 (S) */ - uint16_t eLAgainTime; /* 出现过载过载保护后,在该间隔段时间后,再次尝试输出 (S) */ - // uint16_t softShortTime; /* 软件短路保护延时 时间(100uS) */ - - uint32_t collectOpenCircuitVoltageTime; /* 充电时开路电压采集时间间隔(S) */ - + uint32_t gw485_Baud; /* 串口波特率 */ + uint32_t bat485_Baud; /* 串口波特率,为0代表bms不支持通信 */ + uint8_t powerBoxType; /* 是否只充当电源板:0x00:不是;0x01:是*/ + float constantVoltageV; /* 恒压充电阈值电压(V) */ + float floatI; /* 浮充充电阈值电流(A) */ + float startSolarOpenCircuitV; /* 启动充电太阳能板开路电压(V) */ + float stopSolarOutputCircuitV; /* 停止充电太阳能板输出电压(V) */ + uint16_t checkCanStartTime; /* 检测能否启动间隔时间(S) */ + uint16_t shortCircuitJudgmentDelay; /* 短路判断延时(S) */ + uint16_t inputPowerLowJudgmentDelay; /* 前端输入功率不足判断延时(S) */ + uint16_t inputPowerLowAgainOutputDelay; /* 前端输入功率不足再次输出延时(S) */ + uint16_t firstStageProtectionDelay; /* 第一段保护延时(10uS) */ + float firstStageProtectionCurr; /* 第一段保护电流(A) */ + uint16_t firstStageProtectionValue; /* 第一段保护ADC值 */ + uint16_t secondStageProtectionDelay; /* 第二段保护延时(100uS) */ + float secondStageProtectionCurr; /* 第二段保护电流(A) */ + uint16_t thirdStageProtectionDelay; /* 第三段保护延时(100uS) */ + float thirdStageProtectionCurr; /* 第三段保护电流(A) */ + uint16_t inputPowerLowDetectionDelay; /* 前端输入功率不足检测延时(100uS) */ + float inputPowerLowDetectionVolt; /* 前端输入功率不足检测电压(V) */ + float maxOpenSolarOutputCircuitV; /* 最大太阳能板输出电压(V) */ + float maxChargCurr; /* 最大充电电流(A) */ + float minCheckLoopImpedanceChargCurr; /* 检测回路阻抗时的最小充电电流(A) */ + float fullPowerOutputTemperature; /* 满功率输出温度(℃) */ + float reducePowerOutputTemperature; /* 降功率输出温度(℃) */ + float stopPowerOutputTemperature; /* 停止输出温度(℃) */ + float constantVoltageChargeV; /* 恒压充电时的输出电压(V) */ + float FloatChargeV; /* 浮充充电时的输出电压(V) */ + uint16_t collectOpenCircuitVoltageTime; /* 充电时采集开路电压的间隔时间 */ /* SL */ uint16_t Access_Node_Type; /* 接入节点类型 */ uint16_t Communication_Methods; /* 通信方式 */ - uint16_t Registration_Status; /* 注册状态 */ - uint8_t address[7]; /* 地址 */ uint8_t startFlagSL[2]; /* 起始标志 */ uint8_t endFlagSL; /* 结束标志 */ - /* HY */ - uint8_t hardwareID[6]; /* 硬件ID */ - uint8_t communicationID[4]; /* 通信ID */ - uint8_t protocolType; /* 协议类型; 0x01表示:汇源协议(波特率9600) 0x02表示:南瑞协议(波特率115200)*/ - uint8_t startFlagHY; /* 起始码 */ - uint8_t endFlagHY; /* 结束码 */ - - uint8_t onlyPower; /* 是否只充当电源板:0x00:不是 - 0x01:是*/ - - uint32_t gw485_Baud; /* 串口波特率 */ - uint32_t bat485_Baud; /* 串口波特率,为0代表bms不支持通信 */ } config_parameter; extern config_parameter g_cfgParameter; typedef struct _otherParameter{ @@ -84,8 +66,11 @@ typedef struct _otherParameter{ int MPPT_Mode; /* 工作模式 */ - uint8_t versionInformation[13]; /* 软件版本信息 */ + uint8_t versionInformation[13]; /* 软件版本信息 */ + float loopImpedance; /* 回路阻抗大小 (Ω) */ + + uint16_t Registration_Status; /* 注册状态 */ }otherParameter; // #pragma pack(pop) @@ -133,8 +118,11 @@ float getChargBatteryCurrent(void); BOOL getChargMosState(void); void setChargMosState(BOOL state); BOOL getDischargMosState(void); -uint8_t *getVersionInformation(void); - +uint8_t *getVersionnInformation(void); +float getLoopImpedance(void); +BOOL setLoopImpedance(float loopImpedance); +uint16_t getRegistrationStatus(void); +void setRegistrationStatus(uint16_t status); #endif \ No newline at end of file diff --git a/APP/businessLogic/Src/Init.c b/APP/businessLogic/Src/Init.c index e93066c..6555020 100644 --- a/APP/businessLogic/Src/Init.c +++ b/APP/businessLogic/Src/Init.c @@ -23,7 +23,9 @@ void Init(void) config_info_start(); ADC_Capture_Init(); - proportionalInt(g_cfgParameter.onlyPower); + proportionalInt(g_cfgParameter.powerBoxType); + + g_cfgParameter.firstStageProtectionValue = setfirstStageProtectionValue(g_cfgParameter.firstStageProtectionCurr); FM_GPIO_Init(); tim_Init(); @@ -41,7 +43,6 @@ void Init(void) send_init(); // POW_FF_PCON_Open(); // POW_OUT_PCON_Open(); - HAL_Delay(100); setPowerOutput(TRUE); diff --git a/APP/businessLogic/Src/abnormalManage.c b/APP/businessLogic/Src/abnormalManage.c index 8ecfbb0..23c7ca8 100644 --- a/APP/businessLogic/Src/abnormalManage.c +++ b/APP/businessLogic/Src/abnormalManage.c @@ -259,8 +259,13 @@ BOOL getExcessiveLoadFlag(void) */ void setPowerOutput(BOOL state) { +// static volatile float temp_OUT_VOLT_IN; +// static volatile float temp_PV_VOLT_OUT; +// temp_PV_VOLT_OUT = get_PV_VOLT_OUT(); +// temp_OUT_VOLT_IN = get_OUT_VOLT_IN(); if (state == TRUE) { - if (get_OUT_VOLT_IN() < (get_PV_VOLT_OUT() - 0.1f)) { + if (get_OUT_VOLT_IN() < (get_PV_VOLT_OUT() - 0.1f)) { +// if (temp_OUT_VOLT_IN < (temp_PV_VOLT_OUT - 0.5f)) { POW_FF_PCON_Open(); POW_OUT_PCON_Open(); } @@ -348,14 +353,14 @@ void lowInputLoadDetection(void) { static int num = 0; - if (excessiveLoadInterruptFlag == TRUE && getOutputVoltage() < g_cfgParameter.lowInputLoadDetectionVolt) { + if (excessiveLoadInterruptFlag == TRUE && getOutputVoltage() < g_cfgParameter.inputPowerLowDetectionVolt) { num++; } else { num = 0; excessiveLoadInterruptFlag = FALSE; } - if (excessiveLoadInterruptFlag == TRUE && num == g_cfgParameter.lowInputLoadDetectionDelay) { + if (excessiveLoadInterruptFlag == TRUE && num == g_cfgParameter.inputPowerLowDetectionDelay) { setOverLoad(); } } diff --git a/APP/businessLogic/Src/bl_chargControl.c b/APP/businessLogic/Src/bl_chargControl.c index 23e5710..6c178db 100644 --- a/APP/businessLogic/Src/bl_chargControl.c +++ b/APP/businessLogic/Src/bl_chargControl.c @@ -360,7 +360,7 @@ void mppt_readJust(void) return; } - if (getMosTemperState() == mosTemperEnd) { + if (getMosTemperState() == mosTemperReduce) { SolarInCircuitV = 16; } @@ -487,7 +487,7 @@ void startChargWork(void) */ BOOL stopChargConditions(void) { - if (getSolarInCircuitVoltage() < g_cfgParameter.stopSolarOpenCircuitV + if (getSolarInCircuitVoltage() < g_cfgParameter.stopSolarOutputCircuitV && getChargCurrent() < 1) { return TRUE; } @@ -600,7 +600,7 @@ void judgeYNBattery(void) */ void noBatteryChargControl(void) { - mppt_constantVoltageNoBatteryO(g_cfgParameter.FloatV); + mppt_constantVoltageNoBatteryO(g_cfgParameter.FloatChargeV); } /** @@ -633,7 +633,7 @@ void constantVoltageCharge(void) */ void floatCharge(void) { - mppt_constantVoltageO(g_cfgParameter.FloatV); + mppt_constantVoltageO(g_cfgParameter.FloatChargeV); } /** diff --git a/APP/businessLogic/Src/bl_usart.c b/APP/businessLogic/Src/bl_usart.c index 2f4f750..7476793 100644 --- a/APP/businessLogic/Src/bl_usart.c +++ b/APP/businessLogic/Src/bl_usart.c @@ -5,7 +5,11 @@ #include "configParameter.h" #include "string.h" #include "pDebug.h" +#include "bl_chargControl.h" +#include "interruptSend.h" +#include "inFlash.h" +/* 状态机 */ typedef enum { wait = 0, /* 串口状态机初始状态 */ startFlagSL, /* 接收到SL帧头 */ @@ -19,7 +23,9 @@ typedef enum { writeRegStartNumberSL, /* 接收到SL写入寄存器个数 */ regLengthSL, /* 接收到SL寄存器长度 */ regStatusSL, /* 接收到SL寄存器状态 */ - + cfgFramesNumSL, /* 接收到SL配置文件帧数 */ + cfgLengthSL, /* 接收到SL配置文件长度 */ + readCfgLengthSL, /* 接收到SL读取配置文件长度 */ } uartStateMachine; @@ -34,10 +40,74 @@ typedef enum SL_Function_Code_Read_Profile = 0xD1, /* 配置文件读取 */ }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; @@ -46,6 +116,7 @@ static uartStateMachine state = wait; static uint16_t frameLength = 0; static void stateMachine(device_handle device); +static BOOL checkCrcSl(void); /* 状态机函数 */ static BOOL analysisWait(void); @@ -60,6 +131,71 @@ 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); + + +/* 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); + /* 解析出来指令对应函数 */ @@ -73,6 +209,16 @@ static void SL_MsgProcFunc_Read_Profile(device_handle device, void *pMsg, uint32 + + + + + + + + + + /** * @brief modbus的crc校验 * @param *arr_buff 需要校验的数据 @@ -98,6 +244,35 @@ uint16_t checkModebusCrc(uint8_t *arr_buff, uint8_t len) 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 @@ -154,23 +329,48 @@ void stateMachine(device_handle device) else if (state == regStatusSL) { analysisRegStatusSL(); } + + else if (state == cfgFramesNumSL) { + analysisCfgFramesNumSL(); + } + + else if (state == cfgLengthSL) { + analysiscfgLengthSL(); + } + + else if (state == readCfgLengthSL) { + analysisReadCfgLengthSL(); + } } void gw485DataAnalysis(device_handle device) { + /* 每次函数最多执行5ms */ + static uint32_t tickstart = 0U; + tickstart = HAL_GetTick(); + /* 1S未解析出来一帧数据,将数据清零 */ gw485RxTime++; - if (gw485RxTime == 10) { + if (gw485RxTime >= 100) { gw485RxTime = 0; gw485RxBufferIndex = 0; state = wait; } - - while (uart_dev_char_present(device) == 1) { - gw485RxBuffer[gw485RxBufferIndex++] = uart_dev_in_char(device); - stateMachine(device); + + /* 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); + } stateMachine(device); } @@ -212,13 +412,13 @@ BOOL analysisStartFlagSL(void) /* 解析SL协议设备地址 */ if (gw485RxBufferIndex >= 9) { - if (gw485RxBuffer[2] == g_cfgParameter.address[0] - && gw485RxBuffer[3] == g_cfgParameter.address[1] - && gw485RxBuffer[4] == g_cfgParameter.address[2] - && gw485RxBuffer[5] == g_cfgParameter.address[3] - && gw485RxBuffer[6] == g_cfgParameter.address[4] - && gw485RxBuffer[7] == g_cfgParameter.address[5] - && gw485RxBuffer[8] == g_cfgParameter.address[6]) { + 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; } @@ -341,8 +541,6 @@ BOOL analysisFunctionCodeSL(void) state = crcCheckBitSL; return TRUE; } - log_info("tempCrc:%d", tempCrc); - log_info("checkModebusCrc:%d", checkModebusCrc(gw485RxBuffer, frameLength - 3)); } @@ -357,6 +555,26 @@ BOOL analysisFunctionCodeSL(void) 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; + } + } if (gw485RxBufferIndex < maxLen) { return FALSE; @@ -374,14 +592,14 @@ BOOL analysisFunctionCodeSL(void) */ BOOL analysisReadRegStartAddressSL(void) { - static uint16_t maxLen = 12; + static uint16_t maxLen = 14; /* 解析读取寄存器长度 */ if (gw485RxBufferIndex >= 14) { uint32_t tempAddrNumber = 0; tempAddrNumber = (gw485RxBuffer[12] << 8) | gw485RxBuffer[13]; - if (tempAddrNumber >= 1 && tempAddrNumber <= maxReadRegAddrNumMacro) { + if (tempAddrNumber >= 1 && tempAddrNumber <= maxReadRegAddrNumMacro) { state = readRegStartNumberSL; frameLength = 17; return TRUE; @@ -404,26 +622,28 @@ BOOL analysisReadRegStartAddressSL(void) */ BOOL analysisReadRegStartNumberSL(void) { - static uint16_t maxLen = 16; + // static uint16_t maxLen = 16; - /* crc校验 */ - if (gw485RxBufferIndex >= 16) { - uint32_t tempCrc = 0; - tempCrc = (gw485RxBuffer[14] << 8) | gw485RxBuffer[15]; + // /* crc校验 */ + // if (gw485RxBufferIndex >= 16) { + // uint32_t tempCrc = 0; + // tempCrc = (gw485RxBuffer[14] << 8) | gw485RxBuffer[15]; - if (tempCrc == checkModebusCrc(gw485RxBuffer, 14)) { - state = crcCheckBitSL; - return TRUE; - } - } + // if (tempCrc == checkModebusCrc(gw485RxBuffer, 14)) { + // state = crcCheckBitSL; + // return TRUE; + // } + // } - if (gw485RxBufferIndex < maxLen) { - return FALSE; - } - state = wait; - gw485RxBufferIndex--; - memcpy(gw485RxBuffer, gw485RxBuffer + 1, gw485RxBufferIndex); - return FALSE; + // if (gw485RxBufferIndex < maxLen) { + // return FALSE; + // } + // state = wait; + // gw485RxBufferIndex--; + // memcpy(gw485RxBuffer, gw485RxBuffer + 1, gw485RxBufferIndex); + // return FALSE; + + return checkCrcSl(); } /** @@ -526,25 +746,40 @@ BOOL analysisWriteRegStartAddressSL(void) */ BOOL analysisWriteRegStartNumberSL(void) { - static uint16_t maxLen = 16; - /* crc校验 */ - if (gw485RxBufferIndex >= 16) { - uint32_t tempCrc = 0; - tempCrc = (gw485RxBuffer[frameLength - 3] << 8) | gw485RxBuffer[frameLength - 2]; + // static uint16_t maxLen; + // maxLen = frameLength - 1; - if (tempCrc == checkModebusCrc(gw485RxBuffer, frameLength - 3)) { - state = crcCheckBitSL; - return TRUE; - } - } + // /* 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 (gw485RxBufferIndex < maxLen) { - return FALSE; - } - state = wait; - gw485RxBufferIndex--; - memcpy(gw485RxBuffer, gw485RxBuffer + 1, gw485RxBufferIndex); - return FALSE; + // 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(); } /** @@ -583,17 +818,52 @@ BOOL analysisRegLengthSL(void) * @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]; +{ + // 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; + // 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) { @@ -605,6 +875,939 @@ BOOL analysisRegStatusSL(void) 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 读取太阳能开路电压 + * @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 赛联协议读取寄存器 @@ -615,7 +1818,67 @@ BOOL analysisRegStatusSL(void) */ void SL_MsgProcFunc_Read_Register(device_handle device, void *pMsg, uint32_t MsgLen) { - debug_printf("SL_MsgProcFunc_Read_Register\n"); + // 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 = (Register_Number_16 >> 8); + *(replay_pack + 1) = (Register_Number_16); + + /* 回复数据内容 */ + replay_pack += 2; + for (uint8_t var = 0; var < Register_Number_16 * 2; var++) { + if (0 == (var & 0x01)) { + *(replay_pack + var) = (reply_Data_Content[var / 2] >> 8); + } else { + *(replay_pack + var) = (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); } /** @@ -627,7 +1890,30 @@ void SL_MsgProcFunc_Read_Register(device_handle device, void *pMsg, uint32_t Msg */ void SL_MsgProcFunc_Write_Register(device_handle device, void *pMsg, uint32_t MsgLen) { - debug_printf("SL_MsgProcFunc_Write_Register\n"); + // 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]); + } + } + } } /** @@ -643,7 +1929,7 @@ void SL_MsgProcFunc_Broadcast_Scan(device_handle device, void *pMsg, uint32_t Ms } /** - * @brief 赛联协议写入寄存器 + * @brief 赛联协议注册回复帧 * @param device 串口设备 * pMsg 数据内容 * MsgLen 数据长度 @@ -664,6 +1950,182 @@ void SL_MsgProcFunc_Registration_request(device_handle device, void *pMsg, uint3 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; } /** @@ -676,4 +2138,61 @@ void SL_MsgProcFunc_Distribution_Profile(device_handle device, void *pMsg, uint3 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); } \ No newline at end of file diff --git a/APP/businessLogic/Src/inFlash.c b/APP/businessLogic/Src/inFlash.c index afc72c0..865f268 100644 --- a/APP/businessLogic/Src/inFlash.c +++ b/APP/businessLogic/Src/inFlash.c @@ -59,22 +59,21 @@ void saveConfigInfo(config_info *configInfo) * @retval None * */ -static void readFlashContent(config_info *configInfo) +void readFlashContent(config_info *configInfo) { read_config_info(configInfo); /* 配置文件正确就返回 */ - // static volatile uint16_t tempCrc1, tempCrc2; - // static volatile config_info *tempConfigInfo1; - // tempConfigInfo1 = configInfo; - // tempCrc1 = configInfo->crc; - // tempCrc2 = checkModebusCrc((uint8_t *)configInfo, CONFIG_INFO_SIZE - 2); - // if (tempCrc1 == tempCrc2) { - // return; - // } +// static volatile uint16_t tempCrc1, tempCrc2; +// tempCrc1 = configInfo->crc; +// tempCrc2 = checkModebusCrc((uint8_t *)configInfo, CONFIG_INFO_SIZE - 2); +// if (tempCrc1 == tempCrc2) { +// return; +// } if (configInfo->crc == checkModebusCrc((uint8_t *)configInfo, CONFIG_INFO_SIZE - 2)) { return; } + // /* 更深处的配置文件正确就返回 */ // read_backups_config_info(config_info); // if (config_info->crc == configCheckFunc((uint8_t *)config_info, CONFIG_INFO_SIZE - 2)) { @@ -83,48 +82,65 @@ static void readFlashContent(config_info *configInfo) // } /* 配置文件错误使用默认配置 */ - configInfo->address[0] = 0x11; - configInfo->address[1] = 0x11; - configInfo->address[2] = 0x11; - configInfo->address[3] = 0x11; - configInfo->address[4] = 0x11; - configInfo->address[5] = 0x11; - configInfo->address[6] = 0x11; - // config_info->Access_Node_Type = 0x01; - // config_info->Communication_Methods = 0x02; + configInfo->uniqueDeviceID[0] = 0x11; + configInfo->uniqueDeviceID[1] = 0x11; + configInfo->uniqueDeviceID[2] = 0x11; + configInfo->uniqueDeviceID[3] = 0x11; + configInfo->uniqueDeviceID[4] = 0x11; + configInfo->uniqueDeviceID[5] = 0x11; + configInfo->uniqueDeviceID[6] = 0x11; + configInfo->gw485_Baud = 115200; configInfo->bat485_Baud = 115200; - - configInfo->hardwareID[0] = 0x48; - configInfo->hardwareID[1] = 0x59; - configInfo->hardwareID[2] = 0x30; - configInfo->hardwareID[3] = 0x30; - configInfo->hardwareID[4] = 0x30; - configInfo->hardwareID[5] = 0x31; - configInfo->communicationID[0] = 0x00; - configInfo->communicationID[1] = 0x00; - configInfo->communicationID[2] = 0x00; - configInfo->communicationID[3] = 0x01; - configInfo->protocolType = 0x01; - configInfo->CommunicationProtocolType = 0x01; - configInfo->onlyPower = 0x01; + configInfo->powerBoxType = 0x01; configInfo->constantVoltageV = 14; configInfo->floatI = 0.1f; configInfo->startSolarOpenCircuitV = 17; - configInfo->stopSolarOpenCircuitV = 15; + configInfo->stopSolarOutputCircuitV = 15; + + configInfo->checkCanStartTime = 5; + configInfo->shortCircuitJudgmentDelay = 10; + configInfo->inputPowerLowJudgmentDelay = 30; + configInfo->inputPowerLowAgainOutputDelay = 1800; + + configInfo->firstStageProtectionDelay = 2; + configInfo->firstStageProtectionCurr = 50; + configInfo->secondStageProtectionDelay = 50000; + configInfo->secondStageProtectionCurr = 35; + configInfo->thirdStageProtectionDelay = 600000; + configInfo->thirdStageProtectionCurr = 30; + + configInfo->inputPowerLowDetectionDelay = 10; + configInfo->inputPowerLowDetectionVolt = 10.0f; + + configInfo->maxOpenSolarOutputCircuitV = 25; + configInfo->maxChargCurr = 35; + + configInfo->minCheckLoopImpedanceChargCurr = 5; + + configInfo->stopPowerOutputTemperature = 100; + configInfo->reducePowerOutputTemperature = 90; + configInfo->fullPowerOutputTemperature = 50; + configInfo->constantVoltageChargeV = 14.4f; configInfo->FloatChargeV = 14.2f; - configInfo->HighSideMosTemperature_stop = 100; - configInfo->HighSideMosTemperature_end = 90; - configInfo->HighSideMosTemperature_start = 50; + configInfo->collectOpenCircuitVoltageTime = 1800; + + // configInfo->firstStageProtectionCurr = firstStageProtectionCurrMacro; + // configInfo->firstStageProtectionDelay = firstStageProtectionDelayMacro; + // configInfo->firstStageProtectionValue = firstStageProtectionValueMacro; + // configInfo->secondStageProtectionCurr = secondStageProtectionCurrMacro; + // configInfo->secondStageProtectionDelay = secondStageProtectionDelayMacro; + // configInfo->thirdStageProtectionCurr = thirdStageProtectionCurrMacro; + // configInfo->thirdStageProtectionDelay = thirdStageProtectionDelayMacro; + // configInfo->checkLoopImpedanceChargCurr = checkLoopImpedanceChargCurrMacro; + // configInfo->lowInputLoadDetectionVolt = lowInputLoadDetectionVoltMacro; + // configInfo->lowInputLoadDetectionDelay = lowInputLoadDetectionDelayMacro; + // configInfo->maxChargCurr = maxChargCurrMacro; + // configInfo->maxOpenSolarOpenCircuitV = maxOpenSolarOpenCircuitVMacro; - // configInfo->checkSolarOpenCircuitVTime = 10; - // configInfo->sensorEnableBroadcastTime = 20; - configInfo->outputAgainFlagTime = 10; - configInfo->excessiveLoadFlagTime = 60; - configInfo->eLAgainTime = 1800; } /** @@ -140,74 +156,65 @@ void config_info_start(void) config_info temp_configInfo; readFlashContent(&temp_configInfo); - g_cfgParameter.constantVoltageV = temp_configInfo.constantVoltageV; - g_cfgParameter.floatI = temp_configInfo.floatI; - g_cfgParameter.startSolarOpenCircuitV = temp_configInfo.startSolarOpenCircuitV; - g_cfgParameter.stopSolarOpenCircuitV = temp_configInfo.stopSolarOpenCircuitV; - g_cfgParameter.constantVoltageChargeV = temp_configInfo.constantVoltageChargeV; - g_cfgParameter.FloatV = temp_configInfo.FloatChargeV; - g_cfgParameter.HighSideMosTemperature_stop = temp_configInfo.HighSideMosTemperature_stop; - g_cfgParameter.HighSideMosTemperature_end = temp_configInfo.HighSideMosTemperature_end; - g_cfgParameter.HighSideMosTemperature_start = temp_configInfo.HighSideMosTemperature_start; - // g_cfgParameter.sensorEnableBroadcastTime = temp_configInfo.sensorEnableBroadcastTime; -// g_cfgParameter.checkSolarOpenCircuitVTime = temp_configInfo.checkSolarOpenCircuitVTime; - g_cfgParameter.outputAgainFlagTime = temp_configInfo.outputAgainFlagTime; - g_cfgParameter.excessiveLoadFlagTime = temp_configInfo.excessiveLoadFlagTime; - g_cfgParameter.eLAgainTime = temp_configInfo.eLAgainTime; - g_cfgParameter.collectOpenCircuitVoltageTime= 3600; - g_cfgParameter.address[0] = temp_configInfo.address[0]; - g_cfgParameter.address[1] = temp_configInfo.address[1]; - g_cfgParameter.address[2] = temp_configInfo.address[2]; - g_cfgParameter.address[3] = temp_configInfo.address[3]; - g_cfgParameter.address[4] = temp_configInfo.address[4]; - g_cfgParameter.address[5] = temp_configInfo.address[5]; - g_cfgParameter.address[6] = temp_configInfo.address[6]; - // g_cfgParameter.Access_Node_Type = temp_configInfo.Access_Node_Type; - // g_cfgParameter.Communication_Methods = temp_configInfo.Communication_Methods; - g_cfgParameter.hardwareID[0] = temp_configInfo.hardwareID[0]; - g_cfgParameter.hardwareID[1] = temp_configInfo.hardwareID[1]; - g_cfgParameter.hardwareID[2] = temp_configInfo.hardwareID[2]; - g_cfgParameter.hardwareID[3] = temp_configInfo.hardwareID[3]; - g_cfgParameter.hardwareID[4] = temp_configInfo.hardwareID[4]; - g_cfgParameter.hardwareID[5] = temp_configInfo.hardwareID[5]; - g_cfgParameter.communicationID[0] = temp_configInfo.communicationID[0]; - g_cfgParameter.communicationID[1] = temp_configInfo.communicationID[1]; - g_cfgParameter.communicationID[2] = temp_configInfo.communicationID[2]; - g_cfgParameter.communicationID[3] = temp_configInfo.communicationID[3]; - g_cfgParameter.protocolType = temp_configInfo.protocolType; - // g_cfgParameter.CommunicationProtocolType = temp_configInfo.CommunicationProtocolType; - g_cfgParameter.onlyPower = temp_configInfo.onlyPower; - g_cfgParameter.startFlagSL[0] = 'S'; g_cfgParameter.startFlagSL[1] = 'L'; g_cfgParameter.endFlagSL = 0x16; - g_cfgParameter.startFlagHY = 0x68; - g_cfgParameter.endFlagHY = 0x16; - // if (g_cfgParameter.CommunicationProtocolType == 0x00) { - // g_cfgParameter.gw485_Baud = temp_configInfo.gw485_Baud; - // g_cfgParameter.bat485_Baud = temp_configInfo.bat485_Baud; - // } else if (g_cfgParameter.CommunicationProtocolType == 0x01) { - // g_cfgParameter.bat485_Baud = temp_configInfo.bat485_Baud; - // if (g_cfgParameter.protocolType == 0x01) { - // g_cfgParameter.gw485_Baud = 9600; - // } else if (g_cfgParameter.protocolType == 0x02) { - // g_cfgParameter.gw485_Baud = 115200; - // } - // } - g_cfgParameter.gw485_Baud = 115200; - g_cfgParameter.bat485_Baud = 115200; + g_cfgParameter.Access_Node_Type = POWERBOX; + g_cfgParameter.Communication_Methods = RS485; + + g_cfgParameter.gw485_Baud = temp_configInfo.gw485_Baud; + g_cfgParameter.bat485_Baud = temp_configInfo.bat485_Baud; + + g_cfgParameter.uniqueDeviceID[0] = temp_configInfo.uniqueDeviceID[0]; + g_cfgParameter.uniqueDeviceID[1] = temp_configInfo.uniqueDeviceID[1]; + g_cfgParameter.uniqueDeviceID[2] = temp_configInfo.uniqueDeviceID[2]; + g_cfgParameter.uniqueDeviceID[3] = temp_configInfo.uniqueDeviceID[3]; + g_cfgParameter.uniqueDeviceID[4] = temp_configInfo.uniqueDeviceID[4]; + g_cfgParameter.uniqueDeviceID[5] = temp_configInfo.uniqueDeviceID[5]; + g_cfgParameter.uniqueDeviceID[6] = temp_configInfo.uniqueDeviceID[6]; + + g_cfgParameter.powerBoxType = temp_configInfo.powerBoxType; + + g_cfgParameter.constantVoltageV = temp_configInfo.constantVoltageV; + g_cfgParameter.floatI = temp_configInfo.floatI; + + g_cfgParameter.startSolarOpenCircuitV = temp_configInfo.startSolarOpenCircuitV; + g_cfgParameter.stopSolarOutputCircuitV = temp_configInfo.stopSolarOutputCircuitV; + + g_cfgParameter.checkCanStartTime = temp_configInfo.checkCanStartTime; + g_cfgParameter.shortCircuitJudgmentDelay = temp_configInfo.shortCircuitJudgmentDelay; + g_cfgParameter.inputPowerLowJudgmentDelay = temp_configInfo.inputPowerLowJudgmentDelay; + g_cfgParameter.inputPowerLowAgainOutputDelay= temp_configInfo.inputPowerLowAgainOutputDelay; + + g_cfgParameter.firstStageProtectionCurr = temp_configInfo.firstStageProtectionCurr; + g_cfgParameter.firstStageProtectionDelay = temp_configInfo.firstStageProtectionDelay; + g_cfgParameter.secondStageProtectionCurr = temp_configInfo.secondStageProtectionCurr; + g_cfgParameter.secondStageProtectionDelay = temp_configInfo.secondStageProtectionDelay; + g_cfgParameter.thirdStageProtectionCurr = temp_configInfo.thirdStageProtectionCurr; + g_cfgParameter.thirdStageProtectionDelay = temp_configInfo.thirdStageProtectionDelay; + + g_cfgParameter.inputPowerLowDetectionDelay = temp_configInfo.inputPowerLowDetectionDelay; + g_cfgParameter.inputPowerLowDetectionVolt = temp_configInfo.inputPowerLowDetectionVolt; + + g_cfgParameter.maxOpenSolarOutputCircuitV = temp_configInfo.maxOpenSolarOutputCircuitV; + g_cfgParameter.maxChargCurr = temp_configInfo.maxChargCurr; + g_cfgParameter.minCheckLoopImpedanceChargCurr = temp_configInfo.minCheckLoopImpedanceChargCurr; + g_cfgParameter.stopPowerOutputTemperature = temp_configInfo.stopPowerOutputTemperature; + g_cfgParameter.reducePowerOutputTemperature = temp_configInfo.reducePowerOutputTemperature; + g_cfgParameter.fullPowerOutputTemperature = temp_configInfo.fullPowerOutputTemperature; + + g_cfgParameter.constantVoltageChargeV = temp_configInfo.constantVoltageChargeV; + g_cfgParameter.FloatChargeV = temp_configInfo.FloatChargeV; + g_cfgParameter.collectOpenCircuitVoltageTime= temp_configInfo.collectOpenCircuitVoltageTime; + + /* 读取的回路阻抗无效则回路阻抗设置为0 */ + if (readLoopImpedance() == FALSE) { + setLoopImpedance(0); + saveLoopImpedance(); + } float fTemp; - readLoopImpedance(&fTemp); - /* 读取的回路阻抗偏差过大则不使用 */ - if (fTemp > (float)0.005 && fTemp < (float)1) { - g_cfgParameter.loopImpedance = fTemp; - } - else { - g_cfgParameter.loopImpedance = 0; - saveLoopImpedance(&g_cfgParameter.loopImpedance); - } readtotalElectricityConsumption(&fTemp); totalElectricityConsumptionInt(fTemp); readtotalChargCapacity(&fTemp); @@ -216,39 +223,30 @@ void config_info_start(void) timeInfo time; readTime(&time); setLastTime(time); - - g_cfgParameter.firstStageProtectionCurr = firstStageProtectionCurrMacro; - g_cfgParameter.firstStageProtectionDelay = firstStageProtectionDelayMacro; - g_cfgParameter.firstStageProtectionValue = firstStageProtectionValueMacro; - g_cfgParameter.secondStageProtectionCurr = secondStageProtectionCurrMacro; - g_cfgParameter.secondStageProtectionDelay = secondStageProtectionDelayMacro; - g_cfgParameter.thirdStageProtectionCurr = thirdStageProtectionCurrMacro; - g_cfgParameter.thirdStageProtectionDelay = thirdStageProtectionDelayMacro; - g_cfgParameter.checkLoopImpedanceChargCurr = checkLoopImpedanceChargCurrMacro; - g_cfgParameter.lowInputLoadDetectionVolt = lowInputLoadDetectionVoltMacro; - g_cfgParameter.lowInputLoadDetectionDelay = lowInputLoadDetectionDelayMacro; - g_cfgParameter.maxChargCurr = maxChargCurrMacro; - g_cfgParameter.maxOpenSolarOpenCircuitV = maxOpenSolarOpenCircuitVMacro; - } + /** * @brief 保存回路阻抗在flash中 * @param */ -void saveLoopImpedance(float *loopImpedance) +void saveLoopImpedance(void) { - write_Flash((uint8_t *)loopImpedance, LoopImpedance_SAVE_addr, sizeof(float)); + float loopImpedance; + loopImpedance = getLoopImpedance(); + write_Flash((uint8_t *)&loopImpedance, LoopImpedance_SAVE_addr, sizeof(float)); } /** * @brief 读取flash中的回路阻抗 * @param */ -void readLoopImpedance(float *loopImpedance) +BOOL readLoopImpedance(void) { - read_Flash((uint8_t *)loopImpedance, LoopImpedance_SAVE_addr, sizeof(float)); + float loopImpedance; + read_Flash((uint8_t *)&loopImpedance, LoopImpedance_SAVE_addr, sizeof(float)); + return setLoopImpedance(loopImpedance); } /** diff --git a/APP/businessLogic/Src/interruptSend.c b/APP/businessLogic/Src/interruptSend.c index 17fc49c..284d764 100644 --- a/APP/businessLogic/Src/interruptSend.c +++ b/APP/businessLogic/Src/interruptSend.c @@ -2,7 +2,7 @@ #include "interruptSend.h" -#define RS485_MAX_PACK_DATA_LEN 60 +#define RS485_MAX_PACK_DATA_LEN 256 static uint8_t dataLocation1[RS485_MAX_PACK_DATA_LEN]; static uint8_t dataLocation2[RS485_MAX_PACK_DATA_LEN]; @@ -55,7 +55,7 @@ typedef struct _uart_send_info { /* 恢复默认的对齐设置 */ #pragma pack(pop) -static uart_send_info uart_send = {0}; +uart_send_info uart_send = {0}; /** * @brief 串口中断发送的初始化,通过空闲中断来判断总线空闲状态 @@ -162,6 +162,12 @@ void setBatState(void) */ void setSendOverStateGw(void) { + /* 配置文件传输完成,复位 */ + if (uart_send.sendDataGw->data[9] = 0xD0 + && uart_send.sendDataGw->data[12] == 0xAA) { + NVIC_SystemReset(); + } + uart_send.sendOverStateGw = TRUE; uart_send.sendStateGw = FALSE; uart_send.sendDataGw->dataState = FALSE; @@ -192,7 +198,7 @@ void setSendOverStateBat(void) uart_send.sendStateBat = FALSE; uart_send.sendDataBat->dataState = FALSE; uart_send.sendDataBat = NULL; - uart_send.insertState++; + uart_send.insertState++; /* 插入指针指向为空时 */ if (uart_send.data1.dataState == FALSE) { @@ -315,3 +321,46 @@ void uart_interruptSend(device_handle device, uint8_t buff[], uint8_t len) } } + +/** + * @brief 得到中断发送插入数据指针 + * @param + * @retval + * + */ +uint8_t *getInsertData(void) +{ + return uart_send.insertData->data; +} + + +/** + * @brief 将数据发送指针的内容发送 + * @param + * @retval + * + */ +void uart_insertDataSend(device_handle device, uint8_t len) +{ + uart_send.insertData->Counter = 0; + uart_send.insertData->dataLen = len; + uart_send.insertData->device = device; + + uart_send.insertData->dataState = TRUE; + uart_send.insertState--; + + /* 可插入数据大于0时,将插入指针指向空的储存位置,否则指向NULL */ + if (uart_send.insertState > 0) { + if (uart_send.data1.dataState == FALSE) { + uart_send.insertData = &uart_send.data1; + } + else if (uart_send.data2.dataState == FALSE) { + uart_send.insertData = &uart_send.data2; + } + else if (uart_send.data3.dataState == FALSE) { + uart_send.insertData = &uart_send.data3; + } + } else { + uart_send.insertData = NULL; + } +} \ No newline at end of file diff --git a/APP/businessLogic/Src/parameter.c b/APP/businessLogic/Src/parameter.c index ecd49a8..871a5e1 100644 --- a/APP/businessLogic/Src/parameter.c +++ b/APP/businessLogic/Src/parameter.c @@ -10,7 +10,7 @@ static otherParameter g_otherParameter = {0}; static BOOL batteryState = FALSE; /* 有无电池(估计) */ static float dutyRatio = 0; /* 占空比 */ -static uint8_t mosTemperState = mosTemperStart; /* mos管温度状态 */ +static uint8_t mosTemperState = mosTemperFull; /* mos管温度状态 */ static BOOL checkImpedanceState = FALSE; /* 启动后是否进行了回路阻抗检测 */ static timeInfo lastTime = {0}; /* 上次读取充放电量参数的时间 */ @@ -98,7 +98,7 @@ uint8_t getMosTemperState(void) */ void setMosTemperState(uint8_t state) { - if (state == mosTemperStart || state == mosTemperEnd || state == mosTemperStop) { + if (state == mosTemperFull || state == mosTemperReduce || state == mosTemperStop) { mosTemperState = state; } } @@ -166,7 +166,7 @@ float getBatteryVoltage(void) void setBatteryVoltage(void) { g_otherParameter.Battery_Voltage = g_otherParameter.Output_Voltage - - getChargBatteryCurrent() * g_cfgParameter.loopImpedance; + - getChargBatteryCurrent() * getLoopImpedance(); } /** @@ -456,7 +456,7 @@ void setChargMosState(BOOL state) */ BOOL getDischargMosState(void) { - if (g_cfgParameter.onlyPower) { + if (g_cfgParameter.powerBoxType) { return readOnlyPowerOutputState(); } else { return readOutputState(); @@ -468,8 +468,55 @@ BOOL getDischargMosState(void) * @param * @retval softVer 软件版本号 */ -uint8_t *getVersionInformation(void) +uint8_t *getVersionnInformation(void) { return softVer; } +/** + * @brief 得到回路阻抗大小 + * @param + * @retval 回路阻抗大小 + */ +float getLoopImpedance(void) +{ + return g_otherParameter.loopImpedance; +} + +/** + * @brief 设置回路阻抗大小 + * @param loopImpedance 回路阻抗大小 + * @retval + */ +BOOL setLoopImpedance(float loopImpedance) +{ + /* 读取的回路阻抗偏差过大则不使用 */ + if (loopImpedance < 0 || loopImpedance > 0.3f) { + return FALSE; + } + + g_otherParameter.loopImpedance = loopImpedance; + return TRUE; +} + +/** + * @brief 得到注册状态 + * @param + * @retval 注册状态 + */ +uint16_t getRegistrationStatus(void) +{ + return g_otherParameter.Registration_Status; +} + +/** + * @brief 设置注册状态 + * @param 注册状态 + * @retval + */ +void setRegistrationStatus(uint16_t status) +{ + if (status == UNREGISTER || status == REGISTER_FAIL || status == REGISTER_SUCCESS) { + g_otherParameter.Registration_Status = status; + } +} \ No newline at end of file diff --git a/APP/businessLogic/Src/task.c b/APP/businessLogic/Src/task.c index e356ac0..95bb555 100644 --- a/APP/businessLogic/Src/task.c +++ b/APP/businessLogic/Src/task.c @@ -27,7 +27,7 @@ static STR_TimeSliceOffset m_runled; static void Task_Runled(void); /* 喂狗 */ -#define wdi_reloadVal 1000 /* 任务执行间隔 */ +#define wdi_reloadVal 3000 /* 任务执行间隔 */ #define wdi_offset 0 /* 任务执行偏移量 */ static STR_TimeSliceOffset m_wdi; static void Task_wdi(void); @@ -126,7 +126,7 @@ void Task_softShortCircuit(void); /* 串口任务 */ -#define uart_reloadVal 100 /* 任务执行间隔 */ +#define uart_reloadVal 10 /* 任务执行间隔 */ #define uart_offset 0 /* 任务执行偏移量 */ STR_TimeSliceOffset m_uart; void Task_uart(void); @@ -188,17 +188,22 @@ void Task_wdi(void) { feedDog(); - // debug_printf("chargCurrent:%f \n", getChargCurrent()); - // debug_printf("outputVoltage:%f \n", getOutputVoltage()); - // debug_printf("BatteryVoltage:%f \n", getBatteryVoltage()); - // debug_printf("dischargCurrent:%f \n", getDischargCurrent()); - // debug_printf("solarInCircuitVoltage:%f \n", getSolarInCircuitVoltage()); - // debug_printf("HighSideMosTemperature:%f \n", getHighSideMosTemperature()); - // debug_printf("InputVoltage:%f \n", getInputVoltage()); - // debug_printf("DischargMosState:%d \n", getDischargMosState()); - // debug_printf("MPPT_Mode:%d \n", getMPPT_Mode()); - // debug_printf("loopImpedance:%f \n", g_cfgParameter.loopImpedance); - // debug_printf("DutyRatio:%f \n", getDutyRatio()); +// debug_printf("chargCurrent:%f \n", getChargCurrent()); +// debug_printf("outputVoltage:%f \n", getOutputVoltage()); +// debug_printf("BatteryVoltage:%f \n", getBatteryVoltage()); +// debug_printf("dischargCurrent:%f \n", getDischargCurrent()); +// debug_printf("solarInCircuitVoltage:%f \n", getSolarInCircuitVoltage()); +// debug_printf("HighSideMosTemperature:%f \n", getHighSideMosTemperature()); +// debug_printf("InputVoltage:%f \n", getInputVoltage()); +// debug_printf("DischargMosState:%d \n", getDischargMosState()); +// debug_printf("MPPT_Mode:%d \n", getMPPT_Mode()); +// debug_printf("loopImpedance:%f \n", getLoopImpedance()); +// debug_printf("DutyRatio:%f \n", getDutyRatio()); +// debug_printf("OUT_VOLT_IN:%f \n", get_OUT_VOLT_IN()); +// debug_printf("HAL_GetTick:%d \n", HAL_GetTick()); + + + // char buf[100]; // sprintf(buf, "chargCurrent:%f \n", getChargCurrent()); @@ -261,7 +266,6 @@ void Task_wdi(void) saveTime(&time); NVIC_SystemReset(); } - } /** @@ -287,8 +291,8 @@ void Task_refreshJudgeData(void) } /* 有电池,太阳能输出功率大,电池电压低于14V,同时回路阻抗未测试或需要重新测试 */ - if ((getCheckImpedanceState() == FALSE || g_cfgParameter.loopImpedance == 0.0f) - && (getBatteryState() == TRUE) && (getChargCurrent() > g_cfgParameter.checkLoopImpedanceChargCurr) + if ((getCheckImpedanceState() == FALSE || getLoopImpedance() == 0.0f) + && (getBatteryState() == TRUE) && (getChargCurrent() > g_cfgParameter.maxChargCurr) && (getOutputVoltage() > 9) && (getSolarInCircuitVoltage() > 14) && (getBatteryVoltage() < 14)) { TimeSliceOffset_Register(&m_impedanceCalculation, Task_impedanceCalculation @@ -296,20 +300,20 @@ void Task_refreshJudgeData(void) } /* 温度检测 */ - if ((getMosTemperState() != mosTemperStart) - && (getHighSideMosTemperature() < g_cfgParameter.HighSideMosTemperature_start)) { + if ((getMosTemperState() != mosTemperFull) + && (getHighSideMosTemperature() < g_cfgParameter.fullPowerOutputTemperature)) { /* 状态处于停止运行则打开充电开关 */ if (getMosTemperState() == mosTemperStop) { beginChargWork(); } - setMosTemperState(mosTemperStart); + setMosTemperState(mosTemperFull); } - else if ((getMosTemperState() == mosTemperStart) - && getHighSideMosTemperature() > g_cfgParameter.HighSideMosTemperature_end) { - setMosTemperState(mosTemperEnd); + else if ((getMosTemperState() == mosTemperFull) + && getHighSideMosTemperature() > g_cfgParameter.reducePowerOutputTemperature) { + setMosTemperState(mosTemperReduce); } - else if ((getMosTemperState() == mosTemperEnd) - && getHighSideMosTemperature() > g_cfgParameter.HighSideMosTemperature_stop) { + else if ((getMosTemperState() == mosTemperReduce) + && getHighSideMosTemperature() > g_cfgParameter.stopPowerOutputTemperature) { setMosTemperState(mosTemperStop); /* 停止充电 */ stopChargWork(); @@ -329,7 +333,7 @@ void Task_startControl(void) { /* 是否达到启动条件 */ if (getSolarInCircuitVoltage() > g_cfgParameter.startSolarOpenCircuitV - && getSolarInCircuitVoltage() < g_cfgParameter.maxOpenSolarOpenCircuitV) { + && getSolarInCircuitVoltage() < g_cfgParameter.maxOpenSolarOutputCircuitV) { TimeSliceOffset_Unregister(&m_startControl); m_startControl.runFlag = 0; @@ -444,12 +448,16 @@ void Task_impedanceCalculation(void) float tempLoopImpedance = 0; tempLoopImpedance = (voltOne - voltTwo) / (currOne - currTwo); + // if (tempLoopImpedance < 1.0f && tempLoopImpedance > 0.05f) { + // g_cfgParameter.loopImpedance = tempLoopImpedance; + // saveLoopImpedance(&g_cfgParameter.loopImpedance); + // setCheckImpedanceState(); + // } /* 判断回路阻抗是否合理 */ - if (tempLoopImpedance < 1.0f && tempLoopImpedance > 0.05f) { - g_cfgParameter.loopImpedance = tempLoopImpedance; - saveLoopImpedance(&g_cfgParameter.loopImpedance); + if (setLoopImpedance(tempLoopImpedance) == TRUE) { + saveLoopImpedance(); setCheckImpedanceState(); - } + } setMPPT_Mode(MPPT); setChargControlFlag(TRUE); @@ -603,7 +611,7 @@ void Task_shortCircuitProtection(void) num++; /* 设定输出短路保护时间 */ - if (num == g_cfgParameter.outputAgainFlagTime) { + if (num == g_cfgParameter.shortCircuitJudgmentDelay) { num = 0; zeroShortCircuit(); TimeSliceOffset_Unregister(&m_shortCircuitProtection); @@ -679,7 +687,7 @@ void Task_excessiveLoad(void) } /* 仅过载一次,达到时间后关闭该任务 */ - if (num == g_cfgParameter.excessiveLoadFlagTime) { + if (num == g_cfgParameter.inputPowerLowJudgmentDelay) { num = 0; setExcessiveLoadFlag(FALSE); TimeSliceOffset_Unregister(&m_excessiveLoad); @@ -693,7 +701,7 @@ void Task_excessiveLoad(void) } /* 达到时间就重新尝试输出 */ - if (numLong == g_cfgParameter.eLAgainTime) { + if (numLong == g_cfgParameter.inputPowerLowAgainOutputDelay) { numLong = 0; TimeSliceOffset_Unregister(&m_excessiveLoad); m_excessiveLoad.runFlag = 0; @@ -762,7 +770,7 @@ void Task_softShortCircuit(void) setPowerOutput(TRUE); } - if (num >= g_cfgParameter.outputAgainFlagTime) { + if (num >= g_cfgParameter.shortCircuitJudgmentDelay) { num = 0; if (getShortCircuit() == 1) { setShortCircuitFlag(FALSE); diff --git a/APP/functionalModule/Inc/capture.h b/APP/functionalModule/Inc/capture.h index c965103..0064146 100644 --- a/APP/functionalModule/Inc/capture.h +++ b/APP/functionalModule/Inc/capture.h @@ -23,6 +23,7 @@ typedef struct _adcCapture void ADC_Capture_Init(void); void proportionalInt(int mode); +uint16_t setfirstStageProtectionValue(float curr); float get_CHG_CURR(void); float get_PV_VOLT_OUT(void); diff --git a/APP/functionalModule/Src/FM_GPIO.c b/APP/functionalModule/Src/FM_GPIO.c index 620b8d8..9cc485f 100644 --- a/APP/functionalModule/Src/FM_GPIO.c +++ b/APP/functionalModule/Src/FM_GPIO.c @@ -178,7 +178,8 @@ BOOL readOverCurrState(void) */ BOOL readOnlyPowerOutputState(void) { - static volatile GPIO_PinState gpioTemp1, gpioTemp2, gpioTemp3; + // static volatile GPIO_PinState gpioTemp1, gpioTemp2, gpioTemp3; + GPIO_PinState gpioTemp1, gpioTemp2, gpioTemp3; gpioTemp1 = HAL_GPIO_ReadPin(POW_FF_CON_GPIO_Port, POW_FF_CON_Pin); gpioTemp2 = HAL_GPIO_ReadPin(POW_OUT_CON_GPIO_Port, POW_OUT_CON_Pin); diff --git a/APP/functionalModule/Src/capture.c b/APP/functionalModule/Src/capture.c index dda22a1..6881307 100644 --- a/APP/functionalModule/Src/capture.c +++ b/APP/functionalModule/Src/capture.c @@ -213,7 +213,8 @@ void proportionalInt(int mode) /* 输出外部电压比例 */ P_OUT_VOLT_IN = ((47.0 + 4.7) / 4.7) * Proportion; } - + + // /* 光伏充电输出电流比例,放大倍数*电阻 */ // P_CHG_CURR = (1.0 / (50 * (1 / (1 / 0.01 + 1 / 0.002)))) * Proportion; // /* 充电控制盒输出电压比例,分压系数 */ @@ -226,6 +227,18 @@ void proportionalInt(int mode) // P_PV_VOLT_IN1 = ((47 + 4.7) / 4.7) * Proportion; } +/** + * @brief 设置第一段保护ADC采样的值 + * @param + * @retval None + */ +uint16_t setfirstStageProtectionValue(float curr) +{ + return (uint16_t)(curr / P_DSG_CURR); +} + + + #define N 4 /** * @brief 中位值平均滤波 @@ -424,7 +437,8 @@ float get_OUT_VOLT_IN(void) { float V; uint16_t V_ADC; - static uint16_t V_ADCTemp = (uint16_t)(0.55f / 3.0f * 4095); + static uint16_t V_ADCTemp = (uint16_t)(0.52f / 3.0f * 4095); + // static uint16_t V_ADCTemp = (uint16_t)(0.17f / 3.0f * 4095); V_ADC = ADC2_Capture(OUT_VOLT_IN_CHANNEL); @@ -432,7 +446,10 @@ float get_OUT_VOLT_IN(void) if (HAL_GPIO_ReadPin(POW_FF_CON_GPIO_Port, POW_FF_CON_Pin)) { V = (float)(V_ADC) * P_OUT_VOLT_IN; } else { - V = (float)(V_ADC - V_ADCTemp) * P_OUT_VOLT_IN; + if (V_ADC > V_ADCTemp) { + V = (float)(V_ADC - V_ADCTemp) * P_OUT_VOLT_IN; + } + V = (float)(V_ADC) * P_OUT_VOLT_IN; } #ifdef enable_Printf_VI diff --git a/tools/chargControlTypes.h b/tools/chargControlTypes.h index 7b2688e..1c98f49 100644 --- a/tools/chargControlTypes.h +++ b/tools/chargControlTypes.h @@ -13,12 +13,11 @@ typedef enum _chargMode{ }chargMode; typedef enum { - mosTemperStart = 0, /* 满功率充电mos状态 */ - mosTemperEnd = 1, /* 降功率充电mos状态 */ + mosTemperFull = 0, /* 满功率充电mos状态 */ + mosTemperReduce = 1, /* 降功率充电mos状态 */ mosTemperStop = 2, /* 停止充电mos状态 */ }mosTState; - /* 注册状态 */ typedef enum { UNREGISTER = 0, /* 未注册 */ diff --git a/tools/pDebug.h b/tools/pDebug.h index cb6cf96..eac07d1 100644 --- a/tools/pDebug.h +++ b/tools/pDebug.h @@ -11,8 +11,8 @@ // #define NDEBUG #define log_info_enable 1 -#define log_warn_enable 0 -#define log_error_enable 0 +#define log_warn_enable 1 +#define log_error_enable 1 /* Comment out this define to include log messages */ // #define NLOG