chargeController/APP/businessLogic/Src/task.c

766 lines
23 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

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

#include "task.h"
#include "inFlash.h"
#include "parameter.h"
#include "FM_GPIO.h"
#include "chargControlTypes.h"
#include "bl_chargControl.h"
#include "hy_protocol.h"
#include "cfg_protocol.h"
#include "uart_dev.h"
#include "abnormalManage.h"
#include "interruptSend.h"
#include <stdio.h>
/* 控制运行指示灯和喂狗 */
#define runled_reloadVal 2000 /* 任务执行间隔 */
// static uint16_t runled_reloadVal = 1000; /* 任务执行间隔 */
#define runled_offset 0 /* 任务执行偏移量 */
static STR_TimeSliceOffset m_runled;
static void Task_Runled(void);
/* 喂狗 */
#define wdi_reloadVal 1000 /* 任务执行间隔 */
#define wdi_offset 0 /* 任务执行偏移量 */
static STR_TimeSliceOffset m_wdi;
static void Task_wdi(void);
/* 刷新寄存器中的数据 */
#define refreshJudgeData_reloadVal 1000 /* 任务执行间隔 */
#define refreshJudgeData_offset 0 /* 任务执行偏移量 */
static STR_TimeSliceOffset m_refreshJudgeData;
static void Task_refreshJudgeData(void);
/* 启动任务 */
#define startControl_reloadVal 1000 /* 任务执行间隔 */
#define startControl_offset 100 /* 任务执行偏移量 */
static STR_TimeSliceOffset m_startControl;
static void Task_startControl(void);
/* 软启动 */
#define softStart_reloadVal 1 /* 任务执行间隔 */
#define softStart_offset 0 /* 任务执行偏移量 */
static STR_TimeSliceOffset m_softStart;
static void Task_softStart(void);
/* 回路阻抗检测 */
#define impedanceCalculation_reloadVal 20 /* 任务执行间隔 */
#define impedanceCalculation_offset 0 /* 任务执行偏移量 */
static STR_TimeSliceOffset m_impedanceCalculation;
static void Task_impedanceCalculation(void);
/* 开路电压采集 */
#define collectOpenCircuitVoltage_reloadVal 1000 /* 任务执行间隔 */
#define collectOpenCircuitVoltage_offset 0 /* 任务执行偏移量 */
STR_TimeSliceOffset m_collectOpenCircuitVoltage;
void Task_collectOpenCircuitVoltage(void);
/* 限时开启HY协议配置模式 */
#define beginHYconfigMode_reloadVal 1000 /* 任务执行间隔 */
#define beginHYconfigMode_offset 0 /* 任务执行偏移量 */
static STR_TimeSliceOffset m_beginHYconfigMode;
static void Task_beginHYconfigMode(void);
/* 串口数据接收判断 */
#define usartJudge_reloadVal 100 /* 任务执行间隔 */
#define usartJudge_offset 0 /* 任务执行偏移量 */
static STR_TimeSliceOffset m_usartJudge;
static void Task_usartJudge(void);
/* 串口数据解析和处理 */
#define usartHandle_reloadVal 20 /* 任务执行间隔 */
#define usartHandle_offset 0 /* 任务执行偏移量 */
static STR_TimeSliceOffset m_usartHandle;
static void Task_usartHandle(void);
typedef void (*uartJudgeHandle)(device_handle device);
static uartJudgeHandle uart_judge_handle;
/* 配置文件数据解析和处理 */
#define usartCfg_reloadVal 200 /* 任务执行间隔 */
#define usartCfg_offset 0 /* 任务执行偏移量 */
static STR_TimeSliceOffset m_usartCfg;
static void Task_usartCfg(void);
/* 短路保护 */
#define shortCircuitProtection_reloadVal 1000 /* 任务执行间隔 */
#define shortCircuitProtection_offset 0 /* 任务执行偏移量 */
static STR_TimeSliceOffset m_shortCircuitProtection;
static void Task_shortCircuitProtection(void);
/* 过载保护 */
#define excessiveLoad_reloadVal 1000 /* 任务执行间隔 */
#define excessiveLoad_offset 0 /* 任务执行偏移量 */
STR_TimeSliceOffset m_excessiveLoad;
void Task_excessiveLoad(void);
/* 总线状态检测 */
#define busFree_reloadVal 5 /* 任务执行间隔 */
#define busFree_offset 0 /* 任务执行偏移量 */
STR_TimeSliceOffset m_busFree;
void Task_busFree(void);
// /* 中断发送 */
// #define interruptSend_reloadVal 1 /* 任务执行间隔 */
// #define interruptSend_offset 0 /* 任务执行偏移量 */
// STR_TimeSliceOffset m_interruptSend;
// void Task_interruptSend(void);
// /* 软件过载保护 */
// #define softExcessiveLoad_reloadVal 1000 /* 任务执行间隔 */
// #define softExcessiveLoad_offset 0 /* 任务执行偏移量 */
// STR_TimeSliceOffset m_softExcessiveLoad;
// void Task_softExcessiveLoad(void);
/* 软件短路保护 */
#define softShortCircuit_reloadVal 1000 /* 任务执行间隔 */
#define softShortCircuit_offset 0 /* 任务执行偏移量 */
STR_TimeSliceOffset m_softShortCircuit;
void Task_softShortCircuit(void);
/**
* @brief 启动时初始化各任务
* @param None
* @retval None
*
*/
void task_Init(void)
{
TimeSliceOffset_Register(&m_runled, Task_Runled, runled_reloadVal, runled_offset);
TimeSliceOffset_Register(&m_wdi, Task_wdi, wdi_reloadVal, wdi_offset);
TimeSliceOffset_Register(&m_startControl, Task_startControl, startControl_reloadVal, startControl_offset);
TimeSliceOffset_Register(&m_refreshJudgeData, Task_refreshJudgeData
, refreshJudgeData_reloadVal, refreshJudgeData_offset);
TimeSliceOffset_Register(&m_collectOpenCircuitVoltage, Task_collectOpenCircuitVoltage
, collectOpenCircuitVoltage_reloadVal, collectOpenCircuitVoltage_offset);
uartTaskInit();
TimeSliceOffset_Register(&m_usartJudge, Task_usartJudge, usartJudge_reloadVal, usartJudge_offset);
TimeSliceOffset_Register(&m_usartCfg, Task_usartCfg, usartCfg_reloadVal, usartCfg_offset);
TimeSliceOffset_Register(&m_busFree, Task_busFree, busFree_reloadVal, busFree_offset);
}
/**
* @brief 运行指示灯任务
* @param None
* @retval None
*
*/
void Task_Runled(void)
{
RUN_LED();
}
/**
* @brief 修改运行指示灯状态
* @param mode 充电时1Hz的频率闪烁
* 其余时间2Hz的频率闪烁
* @retval None
*
*/
void chargRunLed(uint8_t mode)
{
if (mode == runLedChargMode) {
m_runled.reloadVal = 500;
}
else if (mode == runLedOtherMode) {
m_runled.reloadVal = 2000;
}
}
/**
* @brief 喂狗任务
* @param None
* @retval None
*/
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());
// char buf[100];
// sprintf(buf, "chargCurrent:%f \n", getChargCurrent());
// uart_dev_write(g_gw485_uart2_handle, buf, strlen(buf));
// memset(buf, 0, sizeof(buf));
// sprintf(buf, "outputVoltage:%f \n", getOutputVoltage());
// uart_dev_write(g_gw485_uart2_handle, buf, strlen(buf));
// memset(buf, 0, sizeof(buf));
// sprintf(buf, "BatteryVoltage:%f \n", getBatteryVoltage());
// uart_dev_write(g_gw485_uart2_handle, buf, strlen(buf));
// memset(buf, 0, sizeof(buf));
// sprintf(buf, "dischargCurrent:%f \n", getDischargCurrent());
// uart_dev_write(g_gw485_uart2_handle, buf, strlen(buf));
// memset(buf, 0, sizeof(buf));
// sprintf(buf, "solarInCircuitVoltage:%f \n", getSolarInCircuitVoltage());
// uart_dev_write(g_gw485_uart2_handle, buf, strlen(buf));
// memset(buf, 0, sizeof(buf));
// sprintf(buf, "HighSideMosTemperature:%f \n", getHighSideMosTemperature());
// uart_dev_write(g_gw485_uart2_handle, buf, strlen(buf));
// memset(buf, 0, sizeof(buf));
// sprintf(buf, "InputVoltage:%f \n", getInputVoltage());
// uart_dev_write(g_gw485_uart2_handle, buf, strlen(buf));
// memset(buf, 0, sizeof(buf));
// sprintf(buf, "DischargMosState:%d \n", getDischargMosState());
// uart_dev_write(g_gw485_uart2_handle, buf, strlen(buf));
// memset(buf, 0, sizeof(buf));
// sprintf(buf, "MPPT_Mode:%d \n", getMPPT_Mode());
// uart_dev_write(g_gw485_uart2_handle, buf, strlen(buf));
// memset(buf, 0, sizeof(buf));
// sprintf(buf, "loopImpedance:%f \n", g_cfgParameter.loopImpedance);
// uart_dev_write(g_gw485_uart2_handle, buf, strlen(buf));
// memset(buf, 0, sizeof(buf));
// sprintf(buf, "DutyRatio:%f \n", getDutyRatio());
// uart_dev_write(g_gw485_uart2_handle, buf, strlen(buf));
// uart_interruptSend(g_gw485_uart2_handle, "hello world\n", sizeof("hello world\n"));
/* 每天复位一次复位前将电量信息写入flash中 */
static uint32_t temp = 60 * 60 * 24;
if (!(--temp)) {
temp = 0;
float tempF;
tempF = getTotalElectricityConsumption();
savetotalElectricityConsumption(&tempF);
tempF = getTotalChargCapacity();
savetotalChargCapacity(&tempF);
timeInfo time;
time = getLastTime();
saveTime(&time);
NVIC_SystemReset();
}
}
/**
* @brief 刷新并判断数据
* @param None
* @retval None
*
*/
void Task_refreshJudgeData(void)
{
/* 获取数据 */
setInputVoltage();
setHighSideMosTemperature();
/* 判断有无电池 */
if (getBatteryState() == FALSE && (getChargBatteryCurrent() > 1 || getChargBatteryCurrent() < -1)
&& getOutputVoltage() < 14.2f) {
setBatteryState(TRUE);
}
/* 有电池太阳能输出功率大电池电压低于14V同时回路阻抗未测试或需要重新测试 */
if ((getCheckImpedanceState() == FALSE || g_cfgParameter.loopImpedance == 0.0f)
&& (getBatteryState() == TRUE) && (getChargCurrent() > 3.0f)
&& (getOutputVoltage() > 9) && (getSolarInCircuitVoltage() > 14)
&& (getBatteryVoltage() < 14)) {
TimeSliceOffset_Register(&m_impedanceCalculation, Task_impedanceCalculation
, impedanceCalculation_reloadVal, impedanceCalculation_reloadVal);
}
/* 温度检测 */
if ((getMosTemperState() != mosTemperStart)
&& (getHighSideMosTemperature() < g_cfgParameter.HighSideMosTemperature_start)) {
/* 状态处于停止运行则打开充电开关 */
if (getMosTemperState() == mosTemperStop) {
beginChargWork();
}
setMosTemperState(mosTemperStart);
}
else if ((getMosTemperState() == mosTemperStart)
&& getHighSideMosTemperature() > g_cfgParameter.HighSideMosTemperature_end) {
setMosTemperState(mosTemperEnd);
}
else if ((getMosTemperState() == mosTemperEnd)
&& getHighSideMosTemperature() > g_cfgParameter.HighSideMosTemperature_stop) {
setMosTemperState(mosTemperStop);
/* 停止充电 */
stopChargWork();
}
}
/**
* @brief 停止充电或系统启动时后开启该任务,每隔一段时间检测开路电压
* 检测电池电压是否大于充电电压,大于则开启充电,否则关闭充电
* 能否达到充电标准,达到后检测电压判断系统中是否有电池同时启
* 动软启动任务
* @param None
* @retval None
*
*/
void Task_startControl(void)
{
/* 是否达到启动条件 */
if (getSolarInCircuitVoltage() > g_cfgParameter.startSolarOpenCircuitV) {
TimeSliceOffset_Unregister(&m_startControl);
m_startControl.runFlag = 0;
/* 判断有无电池 */
if (getOutputVoltage() > 11.0f) {
setBatteryState(TRUE);
} else {
setBatteryState(FALSE);
}
/* 启动软起动任务 */
TimeSliceOffset_Register(&m_softStart, Task_softStart, softStart_reloadVal, softStart_offset);
}
}
/**
* @brief 打开启动任务
* @param
* @retval
*/
void beginStartControlTask(void)
{
TimeSliceOffset_Register(&m_startControl, Task_startControl, startControl_reloadVal, startControl_offset);
m_startControl.runFlag = 1;
}
/**
* @brief 软启动
* @param
* @retval
*
*/
void Task_softStart(void)
{
static uint16_t num = 0;
static float dutyRatio = 0;
num++;
if (num < 5) {
set_pwmDutyRatio(0.1f);
EN_PWMOUT_Eable();
}
else if (num > 70 || dutyRatio > 0.75f) {
TimeSliceOffset_Unregister(&m_softStart);
m_softStart.runFlag = 0;
dutyRatio = 0;
num = 0;
setDutyRatio(0.75f);
if (getBatteryState() == TRUE) {
setMPPT_Mode(MPPT);
} else {
setMPPT_Mode(floatCharg);
}
setChargControlFlag(TRUE);
}
else {
setDutyRatio(getDutyRatio() + 0.01f);
}
}
/**
* @brief 启动软启动任务
* @param
* @retval
*/
void beginSoftStartTask(void)
{
TimeSliceOffset_Register(&m_softStart, Task_softStart, softStart_reloadVal, softStart_offset);
}
/**
* @brief 满足一定条件后启动该任务,测量回路阻抗
* @param
* @retval
*/
void Task_impedanceCalculation(void)
{
static uint8_t num = 0;
static float currOne = 0;
static float voltOne = 0;
static float currTwo = 0;
static float voltTwo = 0;
num++;
if (num == 1) {
setChargControlFlag(FALSE);
setDutyRatio(0.7);
set_pwmDutyRatio(getDutyRatio());
return;
}
if (num == 11) {
currOne = getChargCurrent() - getDischargCurrent();
voltOne = getOutputVoltage();
setDutyRatio(0.85);
set_pwmDutyRatio(getDutyRatio());
return;
}
if (num == 21) {
TimeSliceOffset_Unregister(&m_impedanceCalculation);
m_impedanceCalculation.runFlag = 0;
currTwo = getChargCurrent() - getDischargCurrent();
voltTwo = getOutputVoltage();
float tempLoopImpedance = 0;
tempLoopImpedance = (voltOne - voltTwo) / (currOne - currTwo);
/* 判断回路阻抗是否合理 */
if (tempLoopImpedance < 1.0f && tempLoopImpedance > 0.05f) {
g_cfgParameter.loopImpedance = tempLoopImpedance;
saveLoopImpedance(&g_cfgParameter.loopImpedance);
setCheckImpedanceState();
}
num = 0;
setMPPT_Mode(MPPT);
setChargControlFlag(TRUE);
return;
}
}
/**
* @brief 开路电压采集
* @retval
*/
void Task_collectOpenCircuitVoltage(void)
{
/* 用于无充电控制时获取开路电压 */
static uint32_t collectOpenCircuitVoltageNoNUM = 0;
/* 用于有充电控制时获取开路电压 */
static uint8_t collectOpenCircuitVoltageYesNUM = 0;
/* 用于有充电控制时当标志位 */
static BOOL collectOpenCircuitVoltageYesFlag = 0;
/* 未进行充电时3S采集一次开路电压 */
if (FALSE == getChargControlFlag()) {
if (2 <= collectOpenCircuitVoltageNoNUM++) {
setSolarOpenCircuitVoltage();
collectOpenCircuitVoltageNoNUM = 0;
}
collectOpenCircuitVoltageYesNUM = 0;
if (collectOpenCircuitVoltageYesFlag == TRUE) {
setSolarOpenCircuitVoltage();
beginChargWork();
collectOpenCircuitVoltageYesFlag = FALSE;
}
}
collectOpenCircuitVoltageYesNUM++;
/* 到达开路电压检测时间 */
if (collectOpenCircuitVoltageYesNUM == g_cfgParameter.collectOpenCircuitVoltageTime) {
/* 有电池才进行开路电压检测 */
if (getBatteryState()) {
collectOpenCircuitVoltageYesFlag = TRUE;
stopChargWork();
/* 设置延时为1000-500ms */
m_collectOpenCircuitVoltage.count = 500;
}
collectOpenCircuitVoltageYesNUM = 0;
}
/* 检测开路电压 */
if (collectOpenCircuitVoltageYesNUM == g_cfgParameter.collectOpenCircuitVoltageTime + 1) {
setSolarOpenCircuitVoltage();
beginChargWork();
collectOpenCircuitVoltageYesFlag = FALSE;
}
}
/**
* @brief 开启HY配置模式后配置完成后120S后自动退出
* @param
* @retval
*/
void Task_beginHYconfigMode(void)
{
static uint8_t num = 0;
num++;
if (num >= 120) {
TimeSliceOffset_Unregister(&m_beginHYconfigMode);
m_beginHYconfigMode.runFlag = 0;
num = 0;
setHYconfigModeState(FALSE);
}
}
/**
* @brief 开启HY配置模式后启动退出任务
* @param
* @retval
*/
void beginHYconfigMode(void)
{
setHYconfigModeState(TRUE);
TimeSliceOffset_Register(&m_beginHYconfigMode, Task_beginHYconfigMode
, beginHYconfigMode_reloadVal, beginHYconfigMode_offset);
}
/**
* @brief 初始化串口任务,确定使用的协议
* @param
* @retval
*/
void uartTaskInit(void)
{
// if (g_cfgParameter.CommunicationProtocolType == 0x00) {
// uart_judge_handle = read_and_process_uart_data;
// } else if (g_cfgParameter.CommunicationProtocolType == 0x01) {
// uart_judge_handle = HY_read_and_process_uart_data;
// }
uart_judge_handle = HY_read_and_process_uart_data;
}
/**
* @brief 检测有无通信数据传来
* @param
* @retval
*/
void Task_usartJudge(void)
{
/* 检测到对上通信串口有数据启动读取并解析任务 */
if (uart_dev_char_present(g_gw485_uart2_handle)) {
TimeSliceOffset_Register(&m_usartHandle, Task_usartHandle
, usartHandle_reloadVal, usartHandle_offset);
}
}
/**
* @brief 读取并解析对上通讯的数据
* @param
* @retval
*/
void Task_usartHandle(void)
{
TimeSliceOffset_Unregister(&m_usartHandle);
m_usartHandle.runFlag = 0;
uart_judge_handle(g_gw485_uart2_handle);
}
/**
* @brief 读取并解析配置文件的数据
* @param
* @retval
*/
void Task_usartCfg(void)
{
read_and_process_config_data();
}
/**
* @brief 短路保护任务,短路后启动该任务
* @param
* @retval
*/
void Task_shortCircuitProtection(void)
{
static uint8_t num = 0;
num++;
/* 设定输出短路保护时间 */
if (num == g_cfgParameter.outputAgainFlagTime) {
num = 0;
zeroShortCircuit();
TimeSliceOffset_Unregister(&m_shortCircuitProtection);
m_shortCircuitProtection.runFlag = 0;
/* 仍然过流,彻底关闭输出 */
if (readOverCurrState() == FALSE) {
setPowerOutput(FALSE);
}
/* 不过流,则状态位复位 */
else {
setShortCircuitFlag(FALSE);
}
}
}
/**
* @brief 启动短路保护任务
* @param
* @retval
*/
void startShortCircuitProtection(void)
{
TimeSliceOffset_Register(&m_shortCircuitProtection, Task_shortCircuitProtection
, shortCircuitProtection_reloadVal, shortCircuitProtection_offset);
}
/**
* @brief 关闭短路保护任务
* @param
* @retval
*/
void stopShortCircuitProtection(void)
{
TimeSliceOffset_Unregister(&m_shortCircuitProtection);
m_shortCircuitProtection.runFlag = 0;
}
/**
* @brief 过载保护任务,输入不够供给输出后启动该任务
* @param
* @retval
*/
void Task_excessiveLoad(void)
{
static uint8_t num = 0;
static uint16_t numLong = 0;
/* 短路保护了则退出过载保护 */
if (getShortCircuitFlag() == TRUE) {
num = 0;
numLong = 0;
zeroExcessiveLoad();
setExcessiveLoadFlag(FALSE);
TimeSliceOffset_Unregister(&m_excessiveLoad);
m_excessiveLoad.runFlag = 0;
}
/* 过载一次 */
if (getExcessiveLoad() == 1) {
num++;
}
/* 延迟一段时间打开输出接口 */
if (num == 1 && getExcessiveLoad() == 1) {
setPowerOutput(TRUE);
}
/* 多次过载则关闭输出(关闭输出中断中完成),尝试一段时间后再次输出 */
if (getExcessiveLoad() >= 2) {
// GPIO_WriteBit(POW_OUT_CON_GPIO, POW_OUT_CON_PIN, RESET);
num = 0;
}
/* 仅过载一次,达到时间后关闭该任务 */
if (num == g_cfgParameter.excessiveLoadFlagTime) {
num = 0;
setExcessiveLoadFlag(FALSE);
TimeSliceOffset_Unregister(&m_excessiveLoad);
m_excessiveLoad.runFlag = 0;
return;
}
/* 关闭输出后开始计时 */
if (readPOW_OUT_PCON_State() == FALSE) {
numLong++;
}
/* 达到时间就重新尝试输出 */
if (numLong == g_cfgParameter.eLAgainTime) {
numLong = 0;
TimeSliceOffset_Unregister(&m_excessiveLoad);
m_excessiveLoad.runFlag = 0;
setPowerOutput(TRUE);
setExcessiveLoadFlag(FALSE);
}
}
/**
* @brief 启动硬件过载保护任务
* @param
* @retval
*/
void startExcessiveLoadProtection(void)
{
TimeSliceOffset_Register(&m_excessiveLoad, Task_excessiveLoad
, excessiveLoad_reloadVal, excessiveLoad_offset);
}
/**
* @brief 检测总线是否空闲,并且判断有无数据需要发送
* @param
* @retval
*/
void Task_busFree(void)
{
setGwState();
setBatState();
check_sendState();
}
// /**
// * @brief 中断发送任务
// * @param
// * @retval
// */
// void Task_interruptSend(void)
// {
// // if(check_sendState() == TRUE) {
// // TimeSliceOffset_Unregister(&m_interruptSend);
// // m_interruptSend.runFlag = 0;
// // }
// }
// /**
// * @brief 启动中断发送任务
// * @param
// * @retval
// */
// void startInterruptSendTask(void)
// {
// TimeSliceOffset_Register(&m_interruptSend, Task_interruptSend
// , interruptSend_reloadVal, interruptSend_offset);
// }
/**
* @brief 软件短路保护任务,一段时间中连续出现短路,则关闭输出
* @param
* @retval
*/
void Task_softShortCircuit(void)
{
static uint8_t num = 0;
if (2 == num++) {
setPowerOutput(TRUE);
}
if (num >= g_cfgParameter.outputAgainFlagTime) {
num = 0;
if (getShortCircuit() == 1) {
setShortCircuitFlag(FALSE);
}
zeroShortCircuit();
TimeSliceOffset_Unregister(&m_softShortCircuit);
m_softShortCircuit.runFlag = 0;
}
}
/**
* @brief 启动软件短路保护任务
* @param
* @retval
*/
void startSoftShortCircuitProtection(void)
{
TimeSliceOffset_Register(&m_softShortCircuit, Task_softShortCircuit
, softShortCircuit_reloadVal, softShortCircuit_offset);
}