/*
 * task.c
 *
 *  Created on: 2024年6月24日
 *      Author: psx
 */
#include  <string.h>

#include "task.h"


#include "tim.h"
#include "pwm.h"
#include "adc.h"
#include "rs485.h"
#include "gpio.h"
#include "flash.h"


#include "sl_protocol.h"
#include "mppt_control.h"
#include "inflash.h"
#include <stdlib.h>
#include "collect_Conversion.h"
#include "parameter.h"
#include "hy_protocol.h"
#include "uart_send.h"

/**
 * @brief   初始化
 * @param
 * @retval
 *
 */
void Init()
{
    SPI_Flash_Init();
    currBuffInit();
    config_info_start();
    adcChangeProportionalInit();

    uart_dev_init();
    PWM_TIM_Configuration();
    ADC_all_Init();
    RUN_LED_Init();
    WDI_INPUT_Init();
    POW_OUT_CON_Init();
    POW_FF_CON_Init();
    DSG_PROT_Init();

//    for (int var = 0; var < 50; ++var) {
//        USART_Tbuffer[var] = var;
//    }
//    len = 51;
//    USART_Tbuffer[len] = '\n';
//    gw485_tx_enabla();
//    uartDMA_Init(g_gw485_uart4_handle, USART_Tbuffer, len);
//    USART_DMACmd(USART4, USART_DMAReq_Tx, ENABLE);
//    USART_ITConfig(USART4, USART_IT_TXE, ENABLE);
//    while(1){
////        USART_DMACmd(USART4, USART_DMAReq_Tx, ENABLE);
////        DMA_ClearFlag(DMA1_FLAG_TC1);   //清除DMA1通道4传输完成挂起标志
////        DMA_Cmd(DMA1_Channel1, ENABLE);
////        printf("WHILE\n");
//        Delay_Ms(5000);
////        uartDMA_Init(g_gw485_uart4_handle, USART_Tbuffer, len);
////        USART_DMACmd(USART4, USART_DMAReq_Tx, ENABLE);
//    };
//    send_init();

    /* 1ms */
    TIM3_Init(10);

    TimeSliceOffset_Register(&m_WdiRunled, Task_WdiRunled, WdiRunled_reloadVal, WdiRunled_offset);
    TimeSliceOffset_Register(&m_refreshRegister, Task_refreshRegister,
            refreshRegister_reloadVal, refreshRegister_offset);
    TimeSliceOffset_Register(&g_startMpptControl, Task_startMpptControl,
            startMpptControl_reloadVal, startMpptControl_offset);
    TimeSliceOffset_Register(&g_dataJudgment, Task_dataJudgment,
            dataJudgment_reloadVal, dataJudgment_offset);

    if (g_otherParameter.CommunicationProtocolType == 0x00) {
        uart_judge_handle = read_and_process_uart_data;
    } else if (g_otherParameter.CommunicationProtocolType == 0x01) {
        uart_judge_handle = HY_read_and_process_uart_data;
    }
    TimeSliceOffset_Register(&m_usartJudge, Task_usartJudge, usartJudge_reloadVal, usartJudge_offset);
    TimeSliceOffset_Register(&m_uartConfigFile, Task_uartConfigFile,
            uartConfigFile_reloadVal, uartConfigFile_offset);

    TIM2_Init(1);
    TimeSliceOffset_Start();    /* 启动时间片轮询 */
}

/**
 * @brief   运行指示灯和看门狗
 * @param
 * @retval
 *
 */
STR_TimeSliceOffset m_WdiRunled;
void Task_WdiRunled(void)
{

//    DMA_ClearFlag(DMA1_FLAG_TC1);   //清除DMA1通道4传输完成挂起标志
//    USART_DMACmd(USART4, USART_DMAReq_Tx, ENABLE);

    /* 控制LED的亮灭 */
    static uint8_t flag = RESET;
    flag = !flag;
    GPIO_WriteBit(RUN_LED_GPIO, RUN_LED_PIN, flag);

    /* 每天复位一次，复位前将电量信息写入flash中 */
    static uint32_t temp = wdi_RESET;
    if (!(--temp)) {
        temp = 0;
        savetotalElectricityConsumption(&g_otherParameter.totalElectricityConsumption);
        savetotalChargCapacity(&g_otherParameter.totalChargCapacity);
        NVIC_SystemReset();
    }

    /* tempT S后打开输出接口 */
    static uint8_t tempT = 15;
    if (tempT != 0) {
        tempT--;
        if (tempT == 0) {
            GPIO_WriteBit(POW_OUT_CON_GPIO, POW_OUT_CON_PIN, SET);
            GPIO_WriteBit(POW_FF_CON_GPIO, POW_FF_CON_PIN, SET);
            /* 延时1ms防止外部电容影响电平造成误判 */
            Delay_Ms(1);
            WORK_VOLT_INT_Init();
        }
    }

    /* 喂狗 */
    GPIO_WriteBit(WDI_INPUT_GPIO, WDI_INPUT_PIN, SET);
    GPIO_WriteBit(WDI_INPUT_GPIO, WDI_INPUT_PIN, RESET);

    srand(TIM_GetCounter(TIM4));
    g_otherParameter.randomNumber = 1 + rand() % 10;

//    if (USART_RbufferLen != 0) {
//        printf("%s\n", USART_Rbuffer);
//        memset(USART_Rbuffer, 0, sizeof(USART_Rbuffer));
//        USART_RbufferLen = 0;
//
//    }

//    printf(" vBattery : %d/100 \n", (int)(g_otherParameter.Battery_Voltage * 100));

    uart_dev_write(g_bat485_uart3_handle, " \n", sizeof(" \n"));

    char buffer[80];
    memset(buffer, 0, sizeof(buffer));
    sprintf(buffer, " duty_ratio : %d/1000 \n", (int)(g_controlParameter.dutyRatio * 1000));
    uart_dev_write(g_bat485_uart3_handle, buffer, sizeof(buffer));

    memset(buffer, 0, sizeof(buffer));
    sprintf(buffer, " Solar_In_Circuit_Voltage : %d/100 \n", (int)(g_otherParameter.Solar_In_Circuit_Voltage * 100));
    uart_dev_write(g_bat485_uart3_handle, buffer, sizeof(buffer));

    memset(buffer, 0, sizeof(buffer));
    sprintf(buffer, " vout : %d/100 \n", (int)(g_otherParameter.Output_Voltage * 100));
    uart_dev_write(g_bat485_uart3_handle, buffer, sizeof(buffer));

    memset(buffer, 0, sizeof(buffer));
    sprintf(buffer, " vBattery : %d/100 \n", (int)(g_otherParameter.Battery_Voltage * 100));
    uart_dev_write(g_bat485_uart3_handle, buffer, sizeof(buffer));

    memset(buffer, 0, sizeof(buffer));
    sprintf(buffer, " Iout : %d/100 \n", (int)(g_otherParameter.Charg_Current * 100));
    uart_dev_write(g_bat485_uart3_handle, buffer, sizeof(buffer));

    memset(buffer, 0, sizeof(buffer));
    sprintf(buffer, " Idisout : %d/100 \n", (int)(g_otherParameter.Discharg_Current * 100));
    uart_dev_write(g_bat485_uart3_handle, buffer, sizeof(buffer));

    memset(buffer, 0, sizeof(buffer));
    sprintf(buffer, " mosT : %d/10 \n",  (int)(g_otherParameter.HighSideMos_Temperature * 10));
    uart_dev_write(g_bat485_uart3_handle, buffer, sizeof(buffer));

    memset(buffer, 0, sizeof(buffer));
    sprintf(buffer, " impedance : %d/1000 \n",  (int)(g_controlParameter.loopImpedance * 1000));
    uart_dev_write(g_bat485_uart3_handle, buffer, sizeof(buffer));

    memset(buffer, 0, sizeof(buffer));
    sprintf(buffer, " g_impedanceStart : %d \n",  g_otherParameter.impedanceStart);
    uart_dev_write(g_bat485_uart3_handle, buffer, sizeof(buffer));

    memset(buffer, 0, sizeof(buffer));
    sprintf(buffer, " mosState : %d \n",  (int)(g_otherParameter.DischargMos_State));
    uart_dev_write(g_bat485_uart3_handle, buffer, sizeof(buffer));

    memset(buffer, 0, sizeof(buffer));
    sprintf(buffer, " batteryState : %d \n",  g_otherParameter.batteryState);
    uart_dev_write(g_bat485_uart3_handle, buffer, sizeof(buffer));

    memset(buffer, 0, sizeof(buffer));
    sprintf(buffer, " outputAgainFlag : %d \n",  g_otherParameter.outputAgainFlag);
    uart_dev_write(g_bat485_uart3_handle, buffer, sizeof(buffer));

    memset(buffer, 0, sizeof(buffer));
    sprintf(buffer, " excessiveLoadFlag : %d \n",  g_otherParameter.excessiveLoadFlag);
    uart_dev_write(g_bat485_uart3_handle, buffer, sizeof(buffer));

    memset(buffer, 0, sizeof(buffer));
    sprintf(buffer, " inPower : %d/10000 \n",  (int)(g_otherParameter.totalChargCapacity * 10000));
    uart_dev_write(g_bat485_uart3_handle, buffer, sizeof(buffer));

    memset(buffer, 0, sizeof(buffer));
    sprintf(buffer, " outPower : %d/10000 \n",  (int)(g_otherParameter.totalElectricityConsumption * 10000));
    uart_dev_write(g_bat485_uart3_handle, buffer, sizeof(buffer));

    memset(buffer, 0, sizeof(buffer));
    sprintf(buffer, " 0.没有工作; 1.恒流模式; 2.恒压模式; 3.浮充模式 : %d \n",  g_otherParameter.MPPT_Mode);
    uart_dev_write(g_bat485_uart3_handle, buffer, sizeof(buffer));

    uart_dev_write(g_bat485_uart3_handle, " \n", sizeof(" \n"));

}

/**
 * @brief   刷新寄存器中的数据
 * @param
 * @retval
 *
 */
STR_TimeSliceOffset m_refreshRegister;
void Task_refreshRegister(void)
{
    g_otherParameter.Output_Voltage = get_PV_VOLT_OUT();
    g_otherParameter.Input_Voltage = get_PV_VOLT_IN1();
    g_otherParameter.Solar_In_Circuit_Voltage = get_PV1_VOLT_IN();
    g_otherParameter.HighSideMos_Temperature = get_MOSFET_Temper();

    if (g_controlParameter.dutyRatio == 0 && g_otherParameter.batteryState == 0) {
        g_otherParameter.Solar_Open_Circuit_Voltage = get_PV1_VOLT_IN();
    }

    g_otherParameter.Charg_BatteryCurrent = g_otherParameter.Charg_Current
            - g_otherParameter.Discharg_Current;
    g_otherParameter.totalChargCapacity += totalChargCapacity / 3600000;
    totalChargCapacity = 0;
    g_otherParameter.totalElectricityConsumption += totalElectricityConsumption / 3600000;
    totalElectricityConsumption = 0;
//    saveTotalPower(&g_otherParameter.totalElectricityConsumption, &g_otherParameter.totalChargCapacity);

    g_otherParameter.SOC = 0;

    g_otherParameter.Battery_Voltage = g_otherParameter.Output_Voltage
            - g_otherParameter.Charg_BatteryCurrent * g_controlParameter.loopImpedance;

    if (g_otherParameter.onlyPower) {
        g_otherParameter.DischargMos_State = GPIO_ReadOutputDataBit(POW_OUT_CON_GPIO, POW_OUT_CON_PIN)
                                                && GPIO_ReadInputDataBit(DSG_PROT_GPIO, DSG_PROT_PIN);
    } else {
        g_otherParameter.DischargMos_State = GPIO_ReadOutputDataBit(POW_OUT_CON_GPIO, POW_OUT_CON_PIN);
    }
}

/**
 * @brief   满足一定条件后启动该任务，测量回路阻抗
 * @param
 * @retval
 *
 */
STR_TimeSliceOffset m_impedanceCalculation;
void Task_impedanceCalculation(void)
{
    static uint8_t num = 0;
    static float_t currOne = 0;
    static float_t voltOne = 0;
    static float_t currTwo = 0;
    static float_t voltTwo = 0;

    num++;

    if (num == 1) {
        TIM_Cmd(TIM3, DISABLE);
        TIM_SetCompare4(TIM4, 300);
        return;
    }

    if (num == 11) {
        currOne = get_CHG_CURR() - get_DSG_CURR();
        voltOne = get_PV_VOLT_OUT();
        TIM_SetCompare4(TIM4, 420);
        return;
    }

//    if (num == 11) {
//        currOne = get_CHG_CURR() - get_DSG_CURR();
//        voltOne = get_PV_VOLT_OUT();
//        TIM_SetCompare4(TIM4, 420);
//        return;
//    }

    if (num == 21) {
        TimeSliceOffset_Unregister(&m_impedanceCalculation);
        m_impedanceCalculation.runFlag = 0;

        currTwo = get_CHG_CURR() - get_DSG_CURR();
        voltTwo = get_PV_VOLT_OUT();
        float_t tempLoopImpedance = 0;
        tempLoopImpedance = (voltOne - voltTwo) / (currOne - currTwo);

        /* 判断回路阻抗是否合理 */
        if (tempLoopImpedance < 1.0 && tempLoopImpedance > 0.05) {
            g_controlParameter.loopImpedance = tempLoopImpedance;
            saveLoopImpedance(&g_controlParameter.loopImpedance);
        }

        g_otherParameter.impedanceStart = 0;
        num = 0;

        g_otherParameter.MPPT_Mode = CONSTANTCURRENT;
        TIM_Cmd(TIM3, ENABLE);
        return;
    }

}

/**
 * @brief   短路保护后启动该任务，一段时间后检测是否仍然短路，仍然短路则关闭输出
 * @param
 * @retval
 *
 */
STR_TimeSliceOffset g_outputAgain;
void Task_outputAgain(void)
{
    static uint8_t num = 0;
    num++;

     if (num == g_controlParameter.outputAgainFlagTime) {
         num = 0;
         g_otherParameter.outputAgainFlag = 0;
         TimeSliceOffset_Unregister(&g_outputAgain);
         g_outputAgain.runFlag = 0;
         if (!(GPIO_ReadInputDataBit(DSG_PROT_GPIO, DSG_PROT_PIN))) {
             GPIO_WriteBit(POW_OUT_CON_GPIO, POW_OUT_CON_PIN, RESET);
         }
     }
}

/**
 * @brief   过载保护
 * @param
 * @retval
 *
 */
STR_TimeSliceOffset g_excessiveLoad;
void Task_excessiveLoad(void)
{
    static uint8_t num = 0;
    static uint16_t numLong = 0;

    /* 短路保护了则退出过载保护 */
    if (g_otherParameter.outputAgainFlag == 1) {
        num = 0;
        numLong = 0;
        g_otherParameter.excessiveLoadFlag = 0;
        TimeSliceOffset_Unregister(&g_excessiveLoad);
        g_excessiveLoad.runFlag = 0;
    }

    /* 过载一次 */
    if (g_otherParameter.excessiveLoadFlag == 1) {
        num++;
    }

    /* 延迟一段时间打开输出接口 */
    if (num == 1 && g_otherParameter.excessiveLoadFlag == 1) {
        GPIO_WriteBit(POW_OUT_CON_GPIO, POW_OUT_CON_PIN, SET);
    }

    /* 多次过载则关闭输出 */
    if (g_otherParameter.excessiveLoadFlag >= 2) {
//        GPIO_WriteBit(POW_OUT_CON_GPIO, POW_OUT_CON_PIN, RESET);
        num = 0;
    }

    /* 仅过载一次，达到时间后关闭该任务 */
    if (num == g_controlParameter.excessiveLoadFlagTime) {
        num = 0;
        g_otherParameter.excessiveLoadFlag = 0;
        TimeSliceOffset_Unregister(&g_excessiveLoad);
        g_excessiveLoad.runFlag = 0;
        return;
    }

    /* 关闭输出后开始计时 */
    if (!(GPIO_ReadOutputDataBit(POW_OUT_CON_GPIO, POW_OUT_CON_PIN))) {
        numLong++;
    }

    /* 达到时间就重新尝试输出 */
    if (numLong == g_controlParameter.eLAgainTime) {
        numLong = 0;
        TimeSliceOffset_Unregister(&g_excessiveLoad);
        g_excessiveLoad.runFlag = 0;
        GPIO_WriteBit(POW_OUT_CON_GPIO, POW_OUT_CON_PIN, SET);
        g_otherParameter.excessiveLoadFlag = 0;
    }

    return;
}

/**
 * @brief   软启动
 * @param
 * @retval
 *
 */
STR_TimeSliceOffset m_softStart;
void Task_softStart(void)
{
    static uint16_t num = 0;
    static float_t dutyRatio = 0;
    num++;

    if (num < 5) {
        TIM_SetCompare4(TIM4, 100);
    }

    else if (num > 70 || dutyRatio > 0.75) {
        TimeSliceOffset_Unregister(&m_softStart);
        m_softStart.runFlag = 0;

        dutyRatio = 0;
        num = 0;
        g_controlParameter.dutyRatio = 0.75;
        Set_duty_ratio(&g_controlParameter.dutyRatio);

        if (g_otherParameter.batteryState == 1) {
            g_otherParameter.MPPT_Mode = CONSTANTCURRENT;
            goto start;
        } else {
            g_otherParameter.Charg_BatteryCurrent = g_otherParameter.Charg_Current
                    - g_otherParameter.Discharg_Current;
            //软起动后bms保护板开启电池充电
            if (g_otherParameter.Charg_BatteryCurrent > 0.1
                    || g_otherParameter.Charg_BatteryCurrent < -0.1) {
                g_otherParameter.MPPT_Mode = CONSTANTCURRENT;
            }

            g_otherParameter.MPPT_Mode = FLOAT;

            start:
                TIM_Cmd(TIM3, ENABLE);
                TimeSliceOffset_Register(&g_collectOpenCircuitVoltage, Task_collectOpenCircuitVoltage
                        , collectOpenCircuitVoltage_reloadVal, collectOpenCircuitVoltage_offset);
        }
    }
}

/**
 * @brief   停止充电后开启该任务，每隔一段时间检测开路电压能否达到充电标准，达到后检测电压判断系统中是否有电池同时启动软启动任务，
 * @param
 * @retval
 *
 */
STR_TimeSliceOffset g_startMpptControl;
void Task_startMpptControl(void)
{
    static uint8_t num = 0;
    if (g_controlParameter.checkSolarOpenCircuitVTime == ++num) {
        num = 0;
        g_otherParameter.Solar_Open_Circuit_Voltage = get_PV1_VOLT_IN();

        if (g_otherParameter.Solar_Open_Circuit_Voltage > g_controlParameter.startSolarOpenCircuitV) {
            TimeSliceOffset_Unregister(&g_startMpptControl);
            g_startMpptControl.runFlag = 0;
            if (g_otherParameter.Output_Voltage > 11) {
                g_otherParameter.batteryState = 1;
            } else {
                g_otherParameter.batteryState = 0;
            }
            TimeSliceOffset_Register(&m_softStart, Task_softStart, softStart_reloadVal, softStart_offset);
        }
    }
    return;
}

/**
 * @brief 根据寄存器数据完成一些判断：
 *                  是否开启回路阻抗计算
 *                  MOS管温度对于进入什么模式
 * @param
 * @retval
 *
 */
STR_TimeSliceOffset g_dataJudgment;
void Task_dataJudgment(void)
{
    /* 判断有无电池 */
    if (g_otherParameter.batteryState == 0 && (g_otherParameter.Charg_BatteryCurrent > 1 || g_otherParameter.Charg_BatteryCurrent < -1)
            && g_otherParameter.Output_Voltage < 14.2) {
        g_otherParameter.batteryState = 1;
    }

//    /* 流向电池的电流小于一定值或者电压过大或者过小判定无电池采用浮充输出 */
//    if ((g_otherParameter.Charg_BatteryCurrent < 0.05 && g_otherParameter.Charg_BatteryCurrent > -0.05)
//            || g_otherParameter.Battery_Voltage > 16 || g_otherParameter.Battery_Voltage < 8) {
//        g_otherParameter.MPPT_Mode = FLOAT;
//        g_otherParameter.batteryState = 0;
//        return;
//    }

    /* 有电池，太阳能输出功率大，同时回路阻抗未测试或需要重新测试 */
    if ((g_otherParameter.impedanceStart == 1 || g_controlParameter.loopImpedance == 0.0)
            && g_otherParameter.batteryState == 1 && (g_otherParameter.Charg_Current > 3.0)
            && g_otherParameter.Output_Voltage > 9 && g_otherParameter.Solar_In_Circuit_Voltage > 14) {
        TimeSliceOffset_Register(&m_impedanceCalculation, Task_impedanceCalculation
                , impedanceCalculation_reloadVal, impedanceCalculation_reloadVal);
    }

    /* 根据不同的温度切换到不同输出模式，全功率，降功率和停止输出 */
    if (g_otherParameter.overTemperature != 0
            && g_otherParameter.HighSideMos_Temperature < g_controlParameter.HighSideMosTemperature_start) {
        if (g_otherParameter.overTemperature == 3) {
            TimeSliceOffset_Register(&m_softStart, Task_softStart, softStart_reloadVal, softStart_offset);
        }
        g_otherParameter.overTemperature = 0;
        return;
    }

    if (g_otherParameter.overTemperature == 0
            && g_otherParameter.HighSideMos_Temperature < g_controlParameter.HighSideMosTemperature_stop
            && g_otherParameter.HighSideMos_Temperature > g_controlParameter.HighSideMosTemperature_end) {
        g_controlParameter.dutyRatio -= 0.05;
        Set_duty_ratio(&g_controlParameter.dutyRatio);
        g_otherParameter.overTemperature = 1;
    }

    if (g_otherParameter.overTemperature == 1
            && g_otherParameter.HighSideMos_Temperature < g_controlParameter.HighSideMosTemperature_stop
            && g_otherParameter.HighSideMos_Temperature > g_controlParameter.HighSideMosTemperature_end + 5) {
        g_controlParameter.dutyRatio -= 0.05;
        Set_duty_ratio(&g_controlParameter.dutyRatio);
        g_otherParameter.overTemperature = 2;
    }

    if (g_otherParameter.overTemperature == 2
            && g_otherParameter.HighSideMos_Temperature < g_controlParameter.HighSideMosTemperature_stop
            && g_otherParameter.HighSideMos_Temperature > g_controlParameter.HighSideMosTemperature_end + 10) {
        g_controlParameter.dutyRatio -= 0.05;
        Set_duty_ratio(&g_controlParameter.dutyRatio);
        g_otherParameter.overTemperature = 3;
    }

    if (g_otherParameter.overTemperature != 3
            && g_otherParameter.HighSideMos_Temperature > g_controlParameter.HighSideMosTemperature_stop) {
        g_otherParameter.overTemperature = 3;
        TIM_Cmd(TIM3, DISABLE);
        TIM_SetCompare4(TIM4, 0);
        g_controlParameter.dutyRatio = 0;
    }
}

/**
 * @brief 串口数据解析和处理
 *              Task_usartSL：sl协议
 *              Task_usartHY：hy协议
 * @param
 * @retval
 *
 */
uartJudgeHandle uart_judge_handle;
STR_TimeSliceOffset m_usartJudge;
void Task_usartJudge(void)
{
    /* 检测到有数据启动读取并解析任务 */
    if (uart_dev_char_present(g_gw485_uart4_handle)) {
        TimeSliceOffset_Register(&m_usartHandle, Task_usartHandle
                , usartHandle_reloadVal, usartHandle_offset);
    }
}
STR_TimeSliceOffset m_usartHandle;
void Task_usartHandle(void)
{
    TimeSliceOffset_Unregister(&m_usartHandle);
    m_usartHandle.runFlag = 0;
    uart_judge_handle(g_gw485_uart4_handle);
}


/**
 * @brief 接收到广播指令后,发送数据给网关，未接收到指令再次发送，最多三次，间隔时间3s
 * @param
 * @retval
 *
 */
uint8_t recvbroadcast_flag;              /* 是否需要再次发送标志 */
device_handle  g_recvBroadcastDevice;    /* 串口句柄 */
STR_TimeSliceOffset g_recvbroadcast;
void Task_recvbroadcast(void)
{
    static uint8_t run_number = 0;
    /* 超过三次，不再发送 */
    if (run_number++ == 3 || run_number > 3) {
        g_otherParameter.RegistrationRequestFlag = 0;
        run_number = 0;
        TimeSliceOffset_Unregister(&g_recvbroadcast);
        g_recvbroadcast.runFlag = 0;
        return;
    }
    SL_Mppt_RegistrationRequest_pack recvpack = {0};

    /* 起始标志 */
    recvpack.start_Flag[0] = g_otherParameter.startFlagSL[0];
    recvpack.start_Flag[1] = g_otherParameter.startFlagSL[1];

    /* ID */
    recvpack.address[0] = 0xFF;
    recvpack.address[1] = 0xFF;
    recvpack.address[2] = 0xFF;
    recvpack.address[3] = 0xFF;
    recvpack.address[4] = 0xFF;
    recvpack.address[5] = 0xFF;
    recvpack.address[6] = 0xFF;

    /* 功能码 */
    recvpack.function_Code = SL_Function_Code_Registration_request;

    /* 寄存器长度 */
//    recvpack.register_Length_H =  (g_otherParameter.RegisterNumberMax + 5) >> 8;
//    recvpack.register_Length_L =  g_otherParameter.RegisterNumberMax + 5;
    recvpack.register_Length_H =  g_otherParameter.RegisterNumberMax >> 8;
    recvpack.register_Length_L =  g_otherParameter.RegisterNumberMax;

    /* 注册状态 */
    recvpack.registration_Status_H = g_otherParameter.Registration_Status >> 8;
    recvpack.registration_Status_L = g_otherParameter.Registration_Status;

    /* 接入节点ID */
    recvpack.access_Node_ID[0] = g_otherParameter.address[0];
    recvpack.access_Node_ID[1] = g_otherParameter.address[1];
    recvpack.access_Node_ID[2] = g_otherParameter.address[2];
    recvpack.access_Node_ID[3] = g_otherParameter.address[3];
    recvpack.access_Node_ID[4] = g_otherParameter.address[4];
    recvpack.access_Node_ID[5] = g_otherParameter.address[5];
    recvpack.access_Node_ID[6] = g_otherParameter.address[6];

    /* 接入节点类型 */
    recvpack.access_Node_Type_H = g_otherParameter.Access_Node_Type >> 8;
    recvpack.access_Node_Type_L = g_otherParameter.Access_Node_Type;

    /* 校验位 */
//    uint8_t *rpack_buf = (uint8_t *)&recvpack;
    uint16_t crc = CheckFuncSL((uint8_t *)&recvpack, SL_MPPT_REGISTRATIONREQUEST_PACK_SIZE - 3);

    recvpack.check_Bit_H = crc >> 8;
    recvpack.check_Bit_L = crc;
    /* 结束标志 */
    recvpack.end_Flag = g_otherParameter.endFlagSL;
    /* 校验位 */
    for (uint8_t var = 0; var < 10; ++var) {
        Delay_Ms(randomDelay());
        if (!Check_485_bus_busy(g_recvBroadcastDevice)) {
            if (recvbroadcast_flag == 1) {
                recvbroadcast_flag = 0;
                run_number = 0;
                return;
            }
            uart_dev_write(g_recvBroadcastDevice, (uint8_t *)&recvpack, SL_MPPT_REGISTRATIONREQUEST_PACK_SIZE);

            if (g_recvBroadcastDevice == g_bat485_uart3_handle) {
                USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);
            } else {
                USART_ITConfig(USART4, USART_IT_RXNE, ENABLE);
            }

            break;
        }
    }
}

/**
 * @brief 注册后，一段时间后才能再次响应注册指令
 * @param
 * @retval
 *
 */
STR_TimeSliceOffset g_sensorEnableBroadcast;
void Task_sensorEnableBroadcast(void)
{
    static uint32_t enabBroadcastTimeFlag = 0;
    enabBroadcastTimeFlag++;
    g_otherParameter.runBroadcast = 0;

    if (enabBroadcastTimeFlag == g_controlParameter.sensorEnableBroadcastTime) {
        TimeSliceOffset_Unregister(&g_sensorEnableBroadcast);
        g_sensorEnableBroadcast.runFlag = 0;
        enabBroadcastTimeFlag = 0;
        g_otherParameter.runBroadcast = 1;
    }
    return;
}

/**
 * @brief 接收配置文件
 * @param
 * @retval
 *
 */
STR_TimeSliceOffset m_uartConfigFile;
void Task_uartConfigFile(void)
{
    read_and_process_config_data();
}

///**
// * @brief 过载延时
// * @param
// * @retval
// *
// */
//STR_TimeSliceOffset g_overloadDelay;
//void Task_overloadDelay(void)
//{
//    TimeSliceOffset_Unregister(&g_overloadDelay);
//    g_overloadDelay.runFlag = 0;
//    WORK_VOLT_INT_open();
//}

/**
 * @brief 系统启动后，通过该任务采集开路电压
 * @param
 * @retval
 *
 */
STR_TimeSliceOffset g_collectOpenCircuitVoltage;
uint8_t g_collectOpenCircuitVoltageFlag = 0;
void Task_collectOpenCircuitVoltage(void)
{
    /* 到达开路电压检测时间 */
    g_otherParameter.collectOpenCircuitVoltageNUM++;
    if (g_otherParameter.collectOpenCircuitVoltageNUM == g_controlParameter.collectOpenCircuitVoltageTime) {
        if (g_otherParameter.batteryState) {
            g_collectOpenCircuitVoltageFlag = 1;
            TIM_Cmd(TIM3, DISABLE);
            Delay_Ms(1);
            TIM_SetCompare4(TIM4, 0);
            g_controlParameter.dutyRatio = 0;
            /* 设置延时为1000-500ms */
            g_collectOpenCircuitVoltage.count = 500;
        }
    }

    /* 检测开路电压 */
    if (g_collectOpenCircuitVoltageFlag) {
        g_collectOpenCircuitVoltageFlag = 0;
        g_otherParameter.Solar_Open_Circuit_Voltage = get_PV1_VOLT_IN();
        TimeSliceOffset_Register(&m_softStart, Task_softStart, softStart_reloadVal, softStart_offset);
    }
}

/**
 * @brief HY通信协议下进入配置模式后，120S后自动退出
 * @param
 * @retval
 *
 */
STR_TimeSliceOffset g_configurationModeDelayedExit;
void Task_configurationModeDelayedExit(void)
{
    if (120 == ++g_otherParameter.HYconfigModeT) {
        g_otherParameter.HYconfigModeState = 0;
        g_otherParameter.HYconfigModeT = 0;
        TimeSliceOffset_Unregister(&g_configurationModeDelayedExit);
        g_configurationModeDelayedExit.runFlag = 0;
    }
}
