添加控制flash和gpio的控制等

This commit is contained in:
起床就犯困 2024-12-06 21:23:28 +08:00
parent 0288f9a9a6
commit 973601bb89
29 changed files with 1896 additions and 36 deletions

View File

@ -4,6 +4,12 @@
"parameter.h": "c",
"comm.h": "c",
"bl_chargcontrol.h": "c",
"comm_types.h": "c"
"comm_types.h": "c",
"hd_gpio.h": "c",
"inflash.h": "c",
"fm_tim.h": "c",
"timesliceoffset.h": "c",
"fm_gpio.h": "c",
"pdebug.h": "c"
}
}

View File

@ -0,0 +1,10 @@
#ifndef APP_TASK_H_
#define APP_TASK_H_
#include "timeSliceOffset.h"
#endif

View File

@ -8,7 +8,7 @@ void chargControl(void)
getCVData();
judgeYNBattery();
g_otherParameter.MPPT_Mode = chargControlMode();
chargControlMode();
if (g_otherParameter.MPPT_Mode == noWork) {
return;

View File

@ -1,12 +1,12 @@
#include "start.h"
#include "inFlash.h"
void start(void)
{
config_info_start();
TimeSliceOffset_Start();
}

View File

@ -0,0 +1,9 @@
#include "task.h"

View File

@ -2,10 +2,11 @@
#define BL_CHARG_CONTROL_H_
#include "chargControlEnum.h"
#include "FM_TIM.h"
void getCVData(void);
void judgeYNBattery(void);
int chargControlMode(void);
void chargControlMode(void);
void BatteryChargControl(void);
void noBatteryChargControl(void);

View File

@ -0,0 +1,110 @@
#ifndef BL_IN_FLASH_H_
#define BL_IN_FLASH_H_
#include "flash.h"
#include "stm32g431xx.h"
#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不支持通信 */
/* 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 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)
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; /* 串口波特率 */
/* 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*/
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 crc; /* 校验 */
}config_info;
#define CONFIG_INFO_SIZE (sizeof(config_info))
#pragma pack(pop)
#define CONFIG_SAVE_addr (0)
#define CONFIG_SAVE_ADDR_BEGIN (CONFIG_INFO_SIZE)
#define CONFIG_SAVE_ADDR_END (CONFIG_INFO_SIZE + CONFIG_INFO_SIZE)
#define LoopImpedance_SAVE_addr (CONFIG_INFO_SIZE + CONFIG_INFO_SIZE + 10)
#define totalElectricityConsumption_SAVE_addr (CONFIG_INFO_SIZE + CONFIG_INFO_SIZE + 20)
#define totalChargCapacity_SAVE_addr (CONFIG_INFO_SIZE + CONFIG_INFO_SIZE + 30)
void save_config_info(config_info *save_config_info);
void read_config_info(config_info *output_config_info);
void config_info_start(void);
// void read_and_process_config_data(void);
void saveLoopImpedance(float *loopImpedance);
void readLoopImpedance(float *loopImpedance);
void savetotalElectricityConsumption(float *totalElectricityConsumption);
void readtotalElectricityConsumption(float *totalElectricityConsumption);
void savetotalChargCapacity(float *totalChargCapacity);
void readtotalChargCapacity(float *totalChargCapacity);
#endif

View File

@ -79,10 +79,10 @@ typedef struct _otherParameter{
float dutyRatio; /* 占空比 */
}otherParameter;
extern otherParameter g_otherParameter;
#endif

View File

@ -4,10 +4,10 @@
#include "comm_types.h"
static void stopChargWork(void);
static int stopChargConditions(void);
static int floatChargConditions(void);
static int mpptChargConditions(void);
static int constantVChargConditions(void);
static BOOL stopChargConditions(void);
static BOOL floatChargConditions(void);
static BOOL mpptChargConditions(void);
static BOOL constantVChargConditions(void);
static void mpptCharge(void);
static void constantVoltageCharge(void);
static void floatCharge(void);
@ -79,26 +79,26 @@ BOOL constantVChargConditions(void)
/**
* @brief
* @param
* @retval
* @retval
*
*/
int chargControlMode(void)
void chargControlMode(void)
{
if (stopChargConditions()) {
stopChargWork();
return noWork;
g_otherParameter.MPPT_Mode = noWork;
}
if (floatChargConditions()) {
return floatCharg;
g_otherParameter.MPPT_Mode = floatCharg;
}
if (mpptChargConditions()) {
return MPPT;
g_otherParameter.MPPT_Mode = MPPT;
}
if (constantVChargConditions()) {
return constantVoltage;
g_otherParameter.MPPT_Mode = constantVoltage;
}
}
@ -179,19 +179,20 @@ void BatteryChargControl(void)
{
switch(g_otherParameter.MPPT_Mode) {
case CONSTANTCURRENT:
case MPPT:
mpptCharge();
break;
case CONSTANTVOLTAGE:
case constantVoltage:
constantVoltageCharge();
break;
case FLOAT:
case floatCharg:
floatCharge();
break;
default:
g_otherParameter.MPPT_Mode = noWork;
stopChargWork();
break;
}

View File

@ -0,0 +1,605 @@
#include "inFlash.h"
#include "parameter.h"
#include "pDebug.h"
// static uint8_t config_buff[200];
// static uint8_t config_buff_pos = 0;
/**
* @brief , modebus
* @param
* @retval
*/
static uint16_t configCheckFunc(uint8_t *arr_buff, uint8_t len)
{
uint16_t crc = 0xFFFF;
uint16_t i, j;
for (j = 0; j < len; ++j) {
crc = crc ^ (*arr_buff++);
for (i = 0; i < 8; ++i) {
if ((crc&0x0001) > 0) {
crc = crc >> 1;
crc = crc ^ 0xa001;
}
else {
crc = crc >> 1;
}
}
}
return crc;
}
/**
* @brief
* @param save_config_info
* @retval None
*/
void save_config_info(config_info *save_config_info)
{
write_Flash((uint8_t *)save_config_info, CONFIG_SAVE_ADDR_BEGIN, CONFIG_INFO_SIZE);
}
/**
* @brief
* @param save_config_info
* @retval None
*/
static void save_backups_config_info(config_info *save_config_info)
{
write_Flash((uint8_t *)save_config_info, CONFIG_SAVE_addr, CONFIG_INFO_SIZE);
}
/**
* @brief
* @param read_config_info output_config_info中
* @retval None
*/
void read_config_info(config_info *output_config_info)
{
read_Flash((uint8_t *)output_config_info, CONFIG_SAVE_ADDR_BEGIN, CONFIG_INFO_SIZE);
}
/**
* @brief
* @param read_config_info output_config_info中
* @retval None
*/
static void read_backups_config_info(config_info *output_config_info)
{
read_Flash((uint8_t *)output_config_info, CONFIG_SAVE_addr, CONFIG_INFO_SIZE);
}
/**
* @brief flash中是否有配置文件或者文件是否有损坏,flash中都损坏则使用默认文件
* @param config_info
* @retval None
*
*/
static void readFlashContent(config_info *config_info)
{
read_config_info(config_info);
/* 配置文件正确就返回 */
if (config_info->crc == configCheckFunc((uint8_t *)config_info, CONFIG_INFO_SIZE - 2)) {
return;
}
/* 更深处的配置文件正确就返回 */
read_backups_config_info(config_info);
if (config_info->crc == configCheckFunc((uint8_t *)config_info, CONFIG_INFO_SIZE - 2)) {
save_config_info(config_info);
return;
}
/* 配置文件错误使用默认配置 */
config_info->address[0] = 0x11;
config_info->address[1] = 0x11;
config_info->address[2] = 0x11;
config_info->address[3] = 0x11;
config_info->address[4] = 0x11;
config_info->address[5] = 0x11;
config_info->address[6] = 0x11;
config_info->Access_Node_Type = 0x01;
config_info->Communication_Methods = 0x02;
config_info->gw485_Baud = 9600;
config_info->bat485_Baud = 115200;
config_info->hardwareID[0] = 0x48;
config_info->hardwareID[1] = 0x59;
config_info->hardwareID[2] = 0x30;
config_info->hardwareID[3] = 0x30;
config_info->hardwareID[4] = 0x30;
config_info->hardwareID[5] = 0x31;
config_info->communicationID[0] = 0x00;
config_info->communicationID[1] = 0x00;
config_info->communicationID[2] = 0x00;
config_info->communicationID[3] = 0x01;
config_info->protocolType = 0x01;
// config_info->CommunicationProtocolType = 0x00;
config_info->onlyPower = 0x01;
config_info->constantVoltageV = 14;
config_info->floatI = 0.02;
config_info->startSolarOpenCircuitV = 17;
config_info->stopSolarOpenCircuitV = 15;
config_info->constantVoltageChargeV = 14.4;
config_info->FloatChargeV = 14;
config_info->HighSideMosTemperature_stop = 100;
config_info->HighSideMosTemperature_end = 90;
config_info->HighSideMosTemperature_start = 50;
config_info->checkSolarOpenCircuitVTime = 10;
config_info->sensorEnableBroadcastTime = 20;
config_info->outputAgainFlagTime = 10;
config_info->excessiveLoadFlagTime = 60;
config_info->eLAgainTime = 1800;
}
/**
* @brief
* @param None
* @retval None
*
*/
void config_info_start(void)
{
Flash_Init();
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 = 9600;
g_cfgParameter.gw485_Baud = 115200;
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(&g_otherParameter.totalElectricityConsumption);
readtotalChargCapacity(&g_otherParameter.totalChargCapacity);
}
/**
* @brief flash中
* @param None
* @retval None
*
*/
// #define enlargeScale 100
// BOOL read_and_process_config_data(uint8_t *config_buff[])
// {
// recv_config_info *pack = (recv_config_info *)*config_buff;
// config_info save_configInfo;
// while (config_buff_pos >= RECV_CONFIG_INFO) {
// /* 判断起始标志是否正确 */
// if (pack->start_Flag[0] != g_cfgParameter.startFlagSL[0]
// || pack->start_Flag[1] != g_cfgParameter.startFlagSL[1]) {
// // debug(" start_Flag : 0x%x, 0x%x \n", pack->start_Flag[0], pack->start_Flag[1]);
// goto err;
// }
// /* 判断接入节点类型是否正确 */
// save_configInfo.Access_Node_Type = (uint16_t)pack->Access_Node_Type[0] << 8
// | (uint16_t)pack->Access_Node_Type[1];
// // debug(" Access_Node_Type : 0x%x \n", save_configInfo.Access_Node_Type);
// if (save_configInfo.Access_Node_Type != POWERBOX) {
// goto err;
// }
// /* 判断通信方式是否正确 */
// save_configInfo.Communication_Methods = (uint16_t)pack->Communication_Methods[0] << 8
// | (uint16_t)pack->Communication_Methods[1];
// // debug(" Communication_Methods : 0x%x \n", save_configInfo.Communication_Methods);
// // if (temp_u16 != RS485 || temp_u16 != RJ45) {
// if (save_configInfo.Communication_Methods != RS485) {
// goto err;
// }
// /* 判断波特率是否正确 */
// save_configInfo.gw485_Baud = (uint32_t)pack->gw485_Baud[0] << 24
// | (uint32_t)pack->gw485_Baud[1] << 16
// | (uint32_t)pack->gw485_Baud[2] << 8
// | (uint32_t)pack->gw485_Baud[3];
// // debug(" gw485_Baud : 0x%x, %d \n", save_configInfo.gw485_Baud, save_configInfo.gw485_Baud);
// if (save_configInfo.gw485_Baud != 9600 && save_configInfo.gw485_Baud != 115200) {
// // if (save_configInfo.gw485_Baud != 0x2580 || save_configInfo.gw485_Baud != 115200) {
// // debug(" error : %d\n", save_configInfo.gw485_Baud);
// goto err;
// }
// save_configInfo.bat485_Baud = (uint32_t)pack->bat485_Baud[0] << 24
// | (uint32_t)pack->bat485_Baud[1] << 16
// | (uint32_t)pack->bat485_Baud[2] << 8
// | (uint32_t)pack->bat485_Baud[3];
// // debug(" bat485_Baud : 0x%x, %d \n", save_configInfo.bat485_Baud, save_configInfo.bat485_Baud);
// if (save_configInfo.bat485_Baud != 9600 && save_configInfo.bat485_Baud!= 115200 && save_configInfo.bat485_Baud!= 0) {
// goto err;
// }
// /* 判断协议类型是否正确 */
// if (pack->protocolType != 0x01 && pack->protocolType != 0x02) {
// goto err;
// }
// // debug(" protocolType : 0x%x \n", pack->protocolType);
/* 判断通信协议类型是否正确 */
/*
if (pack->CommunicationProtocolType != 0x00 && pack->CommunicationProtocolType != 0x01) {
goto err;
}
// debug(" CommunicationProtocolType : 0x%x \n", pack->CommunicationProtocolType);
*/
// /* 判断电源盒类型是否正确 */
// if (pack->onlyPower != 0x00 && pack->onlyPower != 0x01) {
// goto err;
// }
// // debug(" onlyPower : 0x%x \n", pack->onlyPower);
// /* 判断恒压充电阈值是否正确 */
// save_configInfo.constantVoltageV =
// (float)(pack->ConstantVoltageV[0] << 8 | pack->ConstantVoltageV[1]) / enlargeScale;
// // debug(" constantVoltageV : %f \n", save_configInfo.constantVoltageV);
// if (save_configInfo.constantVoltageV > (float)14.4 || save_configInfo.constantVoltageV < (float)13.5) {
// goto err;
// }
// /* 判断浮充充电阈值是否正确 */
// save_configInfo.floatI = (float)(pack->FloatI[0] << 8 | pack->FloatI[1]) / enlargeScale;
// // debug(" floatI : %f \n", save_configInfo.floatI);
// if (save_configInfo.floatI > (float)0.2 || save_configInfo.floatI < (float)0) {
// goto err;
// }
// /* 判断太阳能板开路启动电压是否正确 */
// save_configInfo.startSolarOpenCircuitV =
// (float)(pack->startSolarOpenCircuitV[0] << 8 | pack->startSolarOpenCircuitV[1]) / enlargeScale;
// // debug(" startSolarOpenCircuitV : %f \n", save_configInfo.startSolarOpenCircuitV);
// if (save_configInfo.startSolarOpenCircuitV > 24 || save_configInfo.startSolarOpenCircuitV < 14) {
// goto err;
// }
// /* 判断太阳能板关闭电压是否正确 */
// save_configInfo.stopSolarOpenCircuitV =
// (float)(pack->stopSolarOpenCircuitV[0] << 8 | pack->stopSolarOpenCircuitV[1]) / enlargeScale;
// // debug(" stopSolarOpenCircuitV : %f \n", save_configInfo.stopSolarOpenCircuitV);
// if (save_configInfo.stopSolarOpenCircuitV > 17 || save_configInfo.stopSolarOpenCircuitV < 13) {
// goto err;
// }
// /* 判断恒压充电时的输出电压是否正确 */
// save_configInfo.constantVoltageChargeV =
// (float)(pack->constantVoltageChargeV[0] << 8 | pack->constantVoltageChargeV[1]) / enlargeScale;
// // debug(" constantVoltageChargeV : %f \n", save_configInfo.constantVoltageChargeV);
// if (save_configInfo.constantVoltageChargeV > (float)14.6 || save_configInfo.constantVoltageChargeV < (float)14) {
// goto err;
// }
// /* 判断浮充充电时的输出电压是否正确 */
// save_configInfo.FloatChargeV =
// (float)(pack->FloatChargeV[0] << 8 | pack->FloatChargeV[1]) / enlargeScale;
// // debug(" FloatChargeV : %f \n", save_configInfo.FloatChargeV);
// if (save_configInfo.FloatChargeV > (float)14.4 || save_configInfo.FloatChargeV < (float)13.8) {
// goto err;
// }
// /* 判断mos管停止工作温度是否正确 */
// save_configInfo.HighSideMosTemperature_stop =
// (float)(pack->HighSideMosTemperature_stop[0] << 8 | pack->HighSideMosTemperature_stop[1]) / enlargeScale;
// // debug(" HighSideMosTemperature_stop : %f \n", save_configInfo.HighSideMosTemperature_stop);
// if (save_configInfo.HighSideMosTemperature_stop < 60) {
// goto err;
// }
// /* 判断mos管降低工作功率工作温度是否正确 */
// save_configInfo.HighSideMosTemperature_end =
// (float)(pack->HighSideMosTemperature_end[0] << 8 | pack->HighSideMosTemperature_end[1]) / enlargeScale;
// // debug(" HighSideMosTemperature_end : %f \n", save_configInfo.HighSideMosTemperature_end));
// if (save_configInfo.HighSideMosTemperature_end < 50) {
// goto err;
// }
// /* 判断mos管完全恢复工作温度是否正确 */
// save_configInfo.HighSideMosTemperature_start =
// (float)(pack->HighSideMosTemperature_start[0] << 8 | pack->HighSideMosTemperature_start[1]) / enlargeScale;
// // debug(" HighSideMosTemperature_start : %d \n", save_configInfo.HighSideMosTemperature_start);
// if (save_configInfo.HighSideMosTemperature_start < 40) {
// goto err;
// }
// /* 判断启动任务中太阳能板开路电压检测间隔时间是否正确 */
// save_configInfo.checkSolarOpenCircuitVTime =
// pack->checkSolarOpenCircuitVTime[0] << 8 | pack->checkSolarOpenCircuitVTime[1];
// // debug(" checkSolarOpenCircuitVTime : %d \n", save_configInfo.checkSolarOpenCircuitVTime);
// if (save_configInfo.checkSolarOpenCircuitVTime > 1800 || save_configInfo.checkSolarOpenCircuitVTime < 5) {
// goto err;
// }
// /* 判断传感器运行再次注册的间隔是否正确 */
// save_configInfo.sensorEnableBroadcastTime =
// pack->sensorEnableBroadcastTime[0] << 8 | pack->sensorEnableBroadcastTime[1];
// // debug(" sensorEnableBroadcastTime : %d \n", save_configInfo.sensorEnableBroadcastTime);
// if (save_configInfo.sensorEnableBroadcastTime > 60 || save_configInfo.sensorEnableBroadcastTime < 10) {
// goto err;
// }
// /* 判断出现短路保护后延长该段时间再次检测是否短路,仍然短路则关闭输出的间隔是否正确 */
// save_configInfo.outputAgainFlagTime =
// pack->outputAgainFlagTime[0] << 8 | pack->outputAgainFlagTime[1];
// // debug(" outputAgainFlagTime : %d \n", save_configInfo.outputAgainFlagTime);
// if (save_configInfo.sensorEnableBroadcastTime > 30 || save_configInfo.sensorEnableBroadcastTime < 5) {
// goto err;
// }
// /* 判断出现过载后在该间隔时间中多次2次出现过载则关闭输出的间隔是否正确 */
// save_configInfo.excessiveLoadFlagTime =
// pack->excessiveLoadFlagTime[0] << 8 | pack->excessiveLoadFlagTime[1];
// // debug(" excessiveLoadFlagTime : %d \n", save_configInfo.excessiveLoadFlagTime);
// if (save_configInfo.excessiveLoadFlagTime > 90 || save_configInfo.excessiveLoadFlagTime < 30) {
// goto err;
// }
// /* 判断出现过载过载保护后,在该间隔段时间后,再次尝试输出的间隔是否正确 */
// save_configInfo.eLAgainTime = pack->eLAgainTime[0] << 8 | pack->eLAgainTime[1];
// // debug(" eLAgainTime : %d \n", save_configInfo.eLAgainTime);
// if (save_configInfo.eLAgainTime > 3000 || save_configInfo.eLAgainTime < 1000) {
// goto err;
// }
// /* crc校验 */
// save_configInfo.crc = pack->crc[0] << 8 | pack->crc[1];
// // debug(" crc : %x%x \n", pack->crc[0], pack->crc[1]);
// if (save_configInfo.crc != configCheckFunc(config_buff, RECV_CONFIG_INFO - 3)) {
// // debug(" configCheckFunc : %x \n", configCheckFunc(config_buff, RECV_CONFIG_INFO));
// goto err;
// }
// /* 结束标志 */
// // debug(" end_Flag : %x \n", pack->end_Flag);
// if (pack->end_Flag != 0x16) {
// goto err;
// }
// // debug("address : 0x %x %x %x %x %x %x %x\n", pack->address[0]
// // , pack->address[1], pack->address[2], pack->address[3]
// // , pack->address[4], pack->address[5], pack->address[6]);
// config_info temp_configInfo;
// read_config_info(&temp_configInfo);
// if (pack->address[0] != 0xFF
// || pack->address[1] != 0xFF
// || pack->address[2] != 0xFF
// || pack->address[3] != 0xFF
// || pack->address[4] != 0xFF
// || pack->address[5] != 0xFF
// || pack->address[6] != 0xFF) {
// save_configInfo.address[0] = pack->address[0];
// save_configInfo.address[1] = pack->address[1];
// save_configInfo.address[2] = pack->address[2];
// save_configInfo.address[3] = pack->address[3];
// save_configInfo.address[4] = pack->address[4];
// save_configInfo.address[5] = pack->address[5];
// save_configInfo.address[6] = pack->address[6];
// // debug("address : 0x %x %x %x %x %x %x %x\n", save_configInfo.address[0]
// // , save_configInfo.address[1], save_configInfo.address[2], save_configInfo.address[3]
// // , save_configInfo.address[4], save_configInfo.address[5], save_configInfo.address[6]);
// } else {
// save_configInfo.address[0] = temp_configInfo.address[0];
// save_configInfo.address[1] = temp_configInfo.address[1];
// save_configInfo.address[2] = temp_configInfo.address[2];
// save_configInfo.address[3] = temp_configInfo.address[3];
// save_configInfo.address[4] = temp_configInfo.address[4];
// save_configInfo.address[5] = temp_configInfo.address[5];
// save_configInfo.address[6] = temp_configInfo.address[6];
// }
// if (pack->hardwareID[0] != 0xFF
// || pack->hardwareID[1] != 0xFF
// || pack->hardwareID[2] != 0xFF
// || pack->hardwareID[3] != 0xFF
// || pack->hardwareID[4] != 0xFF
// || pack->hardwareID[5] != 0xFF) {
// save_configInfo.hardwareID[0] = pack->hardwareID[0];
// save_configInfo.hardwareID[1] = pack->hardwareID[1];
// save_configInfo.hardwareID[2] = pack->hardwareID[2];
// save_configInfo.hardwareID[3] = pack->hardwareID[3];
// save_configInfo.hardwareID[4] = pack->hardwareID[4];
// save_configInfo.hardwareID[5] = pack->hardwareID[5];
// } else {
// save_configInfo.hardwareID[0] = temp_configInfo.hardwareID[0];
// save_configInfo.hardwareID[1] = temp_configInfo.hardwareID[1];
// save_configInfo.hardwareID[2] = temp_configInfo.hardwareID[2];
// save_configInfo.hardwareID[3] = temp_configInfo.hardwareID[3];
// save_configInfo.hardwareID[4] = temp_configInfo.hardwareID[4];
// save_configInfo.hardwareID[5] = temp_configInfo.hardwareID[5];
// }
// if (pack->communicationID[0] != 0xFF
// || pack->communicationID[1] != 0xFF
// || pack->communicationID[2] != 0xFF
// || pack->communicationID[3] != 0xFF) {
// save_configInfo.communicationID[0] = pack->communicationID[0];
// save_configInfo.communicationID[1] = pack->communicationID[1];
// save_configInfo.communicationID[2] = pack->communicationID[2];
// save_configInfo.communicationID[3] = pack->communicationID[3];
// } else {
// save_configInfo.communicationID[0] = temp_configInfo.communicationID[0];
// save_configInfo.communicationID[1] = temp_configInfo.communicationID[1];
// save_configInfo.communicationID[2] = temp_configInfo.communicationID[2];
// save_configInfo.communicationID[3] = temp_configInfo.communicationID[3];
// }
// save_configInfo.protocolType = pack->protocolType;
// save_configInfo.CommunicationProtocolType = pack->CommunicationProtocolType;
// save_configInfo.onlyPower = pack->onlyPower;
// save_configInfo.crc = configCheckFunc((uint8_t *)&save_configInfo, CONFIG_INFO_SIZE - 2);
// save_backups_config_info(&save_configInfo);
// save_config_info(&save_configInfo);
// memset(config_buff, 0, sizeof(config_buff));
// // /* 返回更改配置文件成功 */
// // SL_Mppt_SOther_pack SUpdateProfile_pack = {0};
// // SUpdateProfile_pack.start_Flag[0] = g_otherParameter.startFlagSL[0];
// // SUpdateProfile_pack.start_Flag[1] = g_otherParameter.startFlagSL[1];
// // SUpdateProfile_pack.address[0] = save_configInfo.address[0];
// // SUpdateProfile_pack.address[1] = save_configInfo.address[1];
// // SUpdateProfile_pack.address[2] = save_configInfo.address[2];
// // SUpdateProfile_pack.address[3] = save_configInfo.address[3];
// // SUpdateProfile_pack.address[4] = save_configInfo.address[4];
// // SUpdateProfile_pack.address[5] = save_configInfo.address[5];
// // SUpdateProfile_pack.address[6] = save_configInfo.address[6];
// // SUpdateProfile_pack.function_Code = SL_Function_Code_Update_Profile;
// // SUpdateProfile_pack.state = 0x01;
// // uint16_t crc = CheckFuncSL((uint8_t *)&SUpdateProfile_pack, SL_MPPT_SOTHER_PACK_SIZE - 3);
// // SUpdateProfile_pack.check_Bit_H = crc >> 8;
// // SUpdateProfile_pack.check_Bit_L = crc;
// // SUpdateProfile_pack.end_Flag = g_otherParameter.endFlagSL;
// // while (1) {
// // if (!Check_485_bus_busy(g_gw485_uart4_handle)) {
// // uart_dev_write(g_gw485_uart4_handle, (uint8_t *)&SUpdateProfile_pack, SL_MPPT_SOTHER_PACK_SIZE);
// // USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);
// // break;
// // }
// // Delay_Ms(randomDelay());
// // }
// /* 复位 */
// NVIC_SystemReset();
// return;
// err:
// config_buff_pos--;
// memcpy(config_buff, config_buff + 1, sizeof(config_buff) - 1);
// }
// }
/**
* @brief flash中
* @param
*/
void saveLoopImpedance(float *loopImpedance)
{
write_Flash((uint8_t *)loopImpedance, LoopImpedance_SAVE_addr, sizeof(float));
}
/**
* @brief flash中的回路阻抗
* @param
*/
void readLoopImpedance(float *loopImpedance)
{
read_Flash((uint8_t *)loopImpedance, LoopImpedance_SAVE_addr, sizeof(float));
}
/**
* @brief flash中
* @param
*/
void savetotalElectricityConsumption(float *totalElectricityConsumption)
{
write_Flash((uint8_t *)totalElectricityConsumption, totalElectricityConsumption_SAVE_addr, sizeof(float));
}
/**
* @brief flash中的放电量
* @param
*/
void readtotalElectricityConsumption(float *totalElectricityConsumption)
{
read_Flash((uint8_t *)totalElectricityConsumption, totalElectricityConsumption_SAVE_addr, sizeof(float));
}
/**
* @brief flash中
* @param
*/
void savetotalChargCapacity(float *totalChargCapacity)
{
write_Flash((uint8_t *)totalChargCapacity, totalChargCapacity_SAVE_addr, sizeof(float));
}
/**
* @brief flash中的充电量
* @param
*/
void readtotalChargCapacity(float *totalChargCapacity)
{
read_Flash((uint8_t *)totalChargCapacity, totalChargCapacity_SAVE_addr, sizeof(float));
}

View File

@ -0,0 +1,26 @@
#ifndef FM_GPIO_H_
#define FM_GPIO_H_
#include "HD_GPIO.h"
void FM_GPIO_Init(void);
void POW_FF_PCON_Open(void);
void POW_FF_PCON_Close(void);
void POW_OUT_PCON_Open(void);
void POW_OUT_PCON_Close(void);
void RUN_LEN_Open(void);
void RUN_LEN_Close(void);
void FFMOS_CON_Open(void);
void FFMOS_CON_Close(void);
void EN_PWMOUT_Eable(void);
void EN_PWMOUT_Diseable(void);
// extern void WORK_VOLT_Interrupt(void);
// extern void DSG_PROT_Interrupt(void);
#endif

View File

@ -0,0 +1,13 @@
#ifndef FM_PWM_CONTORL_H_
#define FM_PWM_CONTORL_H_
#include "HD_TIM.h"
void pwm_Init(void);
void set_pwmDutyRatio(float DutyRatio);
void set_pwmPulse(uint32_t Pulse);
extern void chargControl(void);
#endif

View File

@ -0,0 +1,13 @@
#ifndef FM_FLASH_H_
#define FM_FLASH_H_
#include "main.h"
#include "w25qxx.h"
void Flash_Init(void);
void read_Flash(uint8_t* pBuffer,uint32_t ReadAddr,uint16_t NumByteToRead);
void write_Flash(uint8_t* pBuffer,uint32_t WriteAddr,uint16_t NumByteToWrite);
#endif

View File

@ -0,0 +1,127 @@
#include "FM_GPIO.h"
void FM_GPIO_Init(void)
{
HD_GPIO_Init();
}
/**
* @brief mos管
* @param None
* @retval None
*/
void POW_FF_PCON_Open(void)
{
HAL_GPIO_WritePin(POW_FF_CON_GPIO_Port, POW_FF_CON_Pin, GPIO_PIN_SET);
}
/**
* @brief mos管
* @param None
* @retval None
*/
void POW_FF_PCON_Close(void)
{
HAL_GPIO_WritePin(POW_FF_CON_GPIO_Port, POW_FF_CON_Pin, GPIO_PIN_RESET);
}
/**
* @brief mos管
* @param None
* @retval None
*/
void POW_OUT_PCON_Open(void)
{
HAL_GPIO_WritePin(POW_OUT_CON_GPIO_Port, POW_OUT_CON_Pin, GPIO_PIN_SET);
}
/**
* @brief mos管
* @param None
* @retval None
*/
void POW_OUT_PCON_Close(void)
{
HAL_GPIO_WritePin(POW_OUT_CON_GPIO_Port, POW_OUT_CON_Pin, GPIO_PIN_RESET);
}
/**
* @brief LED灯
* @param None
* @retval None
*/
void RUN_LEN_Open(void)
{
HAL_GPIO_WritePin(RUN_LED_GPIO_Port, RUN_LED_Pin, GPIO_PIN_SET);
}
/**
* @brief LED灯
* @param None
* @retval None
*/
void RUN_LEN_Close(void)
{
HAL_GPIO_WritePin(RUN_LED_GPIO_Port, RUN_LED_Pin, GPIO_PIN_RESET);
}
/**
* @brief mppt电感后的输出mos管
* @param None
* @retval None
*/
void FFMOS_CON_Open(void)
{
HAL_GPIO_WritePin(FFMOS_CON_GPIO_Port, FFMOS_CON_Pin, GPIO_PIN_RESET);
}
/**
* @brief mppt电感后的输出mos管
* @param None
* @retval None
*/
void FFMOS_CON_Close(void)
{
HAL_GPIO_WritePin(FFMOS_CON_GPIO_Port, FFMOS_CON_Pin, GPIO_PIN_SET);
}
/**
* @brief mos管使能pwm输出
* @param None
* @retval None
*/
void EN_PWMOUT_Eable(void)
{
HAL_GPIO_WritePin(EN_PWMOUT_GPIO_Port, EN_PWMOUT_Pin, GPIO_PIN_RESET);
}
/**
* @brief mos管关闭pwm输出
* @param None
* @retval None
*/
void EN_PWMOUT_Diseable(void)
{
HAL_GPIO_WritePin(EN_PWMOUT_GPIO_Port, EN_PWMOUT_Pin, GPIO_PIN_SET);
}
/**
* @brief GPIO外部中断的回调函数
* @param GPIO_Pin
* @retval None
*/
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
if (GPIO_Pin == WORK_VOLT_Pin) {
// WORK_VOLT_Interrupt();
}
else if (GPIO_Pin == DSG_PROT_Pin) {
// DSG_PROT_Interrupt();
}
}

View File

@ -0,0 +1,77 @@
#include "FM_TIM.h"
#include "timeSliceOffset.h"
static int PWM_RESOLUTION;
void pwm_Init(void)
{
HD_PWM_Init();
PWM_RESOLUTION = HAL_RCC_GetHCLKFreq() / 100000;
}
void pwm_Stop(void)
{
set_pwmPulse(0);
HAL_TIM_OC_MspDeInit(&htim3);
}
/**
* @brief
* @param Pulse
* @retval None
*/
void set_pwmPulse(uint32_t Pulse)
{
if (Pulse > PWM_RESOLUTION) {
return;
}
__HAL_TIM_SetCompare(&htim3, TIM_CHANNEL_4, Pulse);
}
/**
* @brief
* @param DutyRatio
* @retval None
*/
void set_pwmDutyRatio(float DutyRatio)
{
if (DutyRatio > (float)0.9 || DutyRatio < (float)0.05) {
return;
}
uint32_t Pulse = (int)(DutyRatio * PWM_RESOLUTION);
set_pwmPulse(Pulse);
}
/**
* @brief Period elapsed callback in non blocking mode
* @note This function is called when TIM1 interrupt took place, inside
* HAL_TIM_IRQHandler(). It makes a direct call to HAL_IncTick() to increment
* a global variable "uwTick" used as application time base.
* @param htim : TIM handle
* @retval None
*/
/**
* @brief
* @param htim
* @retval None
*/
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
/* USER CODE BEGIN Callback 0 */
/* USER CODE END Callback 0 */
if (htim->Instance == TIM1) {
HAL_IncTick();
}
/* USER CODE BEGIN Callback 1 */
if (htim->Instance == TIM7) {
TimeSliceOffset_Produce();
chargControl();
}
/* USER CODE END Callback 1 */
}

View File

@ -0,0 +1,43 @@
#include "flash.h"
/**
* @brief flash初始化
* @param
*/
void Flash_Init(void)
{
__HAL_RCC_GPIOA_CLK_ENABLE();
HAL_GPIO_WritePin(FLASH_CS_GPIO_Port, FLASH_CS_Pin, GPIO_PIN_RESET);
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = FLASH_CS_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
W25QXX_Init();
}
/**
* @brief flash中的数据
* @param pBuffer
* @param ReadAddr
* @param NumByteToRead
*/
void read_Flash(uint8_t* pBuffer,uint32_t ReadAddr,uint16_t NumByteToRead)
{
W25QXX_Read(pBuffer, ReadAddr, NumByteToRead);
}
/**
* @brief flash中
* @param pBuffer
* @param ReadAddr
* @param NumByteToRead
*/
void write_Flash(uint8_t* pBuffer,uint32_t WriteAddr,uint16_t NumByteToWrite)
{
W25QXX_Write(pBuffer, WriteAddr, NumByteToWrite);
}

View File

@ -0,0 +1,12 @@
#ifndef HD_GPIO_H_
#define HD_GPIO_H_
#include "main.h"
#include "gpio.h"
#include "stm32g431xx.h"
#include "comm_types.h"
void HD_GPIO_Init(void);
#endif

View File

@ -0,0 +1,13 @@
#ifndef HD_TIM_H_
#define HD_TIM_H_
#include "main.h"
#include "tim.h"
#include "stm32g431xx.h"
void HD_PWM_Init(void);
void HD_controlTim_Init(void);
#endif

View File

@ -0,0 +1,67 @@
#ifndef __W25QXX_H
#define __W25QXX_H
#include <main.h>
#define W25QXX_SPI_Handle (&hspi1)
//W25X系列/Q系列芯片列表
//W25Q80 ID 0XEF13
//W25Q16 ID 0XEF14
//W25Q32 ID 0XEF15
//W25Q64 ID 0XEF16
//W25Q128 ID 0XEF17
#define W25Q80 0XEF13
#define W25Q16 0XEF14
#define W25Q32 0XEF15
#define W25Q64 0XEF16
#define W25Q128 0XEF17
#define W25QXX_CS_L() HAL_GPIO_WritePin(FLASH_CS_GPIO_Port, FLASH_CS_Pin, GPIO_PIN_RESET)
#define W25QXX_CS_H() HAL_GPIO_WritePin(FLASH_CS_GPIO_Port, FLASH_CS_Pin, GPIO_PIN_SET)
extern uint16_t W25QXX_TYPE;
extern uint32_t W25QXX_SIZE;
extern uint8_t W25QXX_UID[8];
//
//指令表
#define W25X_WriteEnable 0x06
#define W25X_WriteDisable 0x04
#define W25X_ReadStatusReg 0x05
#define W25X_WriteStatusReg 0x01
#define W25X_ReadData 0x03
#define W25X_FastReadData 0x0B
#define W25X_FastReadDual 0x3B
#define W25X_PageProgram 0x02
#define W25X_BlockErase 0xD8
#define W25X_SectorErase 0x20
#define W25X_ChipErase 0xC7
#define W25X_PowerDown 0xB9
#define W25X_ReleasePowerDown 0xAB
#define W25X_DeviceID 0xAB
#define W25X_ManufactDeviceID 0x90
#define W25X_JedecDeviceID 0x9F
int W25QXX_Init(void);
void W25QXX_ReadUniqueID(uint8_t UID[8]);
uint16_t W25QXX_ReadID(void); //读取FLASH ID
uint8_t W25QXX_ReadSR(void); //读取状态寄存器
void W25QXX_Write_SR(uint8_t sr); //写状态寄存器
void W25QXX_Write_Enable(void); //写使能
void W25QXX_Write_Disable(void); //写保护
void W25QXX_Write_NoCheck(uint8_t* pBuffer,uint32_t WriteAddr,uint16_t NumByteToWrite);
void W25QXX_Read(uint8_t* pBuffer,uint32_t ReadAddr,uint16_t NumByteToRead); //读取flash
void W25QXX_Write(uint8_t* pBuffer,uint32_t WriteAddr,uint16_t NumByteToWrite);//写入flash
void W25QXX_Erase_Chip(void); //整片擦除
void W25QXX_Erase_Sector(uint32_t Dst_Addr); //扇区擦除
void W25QXX_Wait_Busy(void); //等待空闲
void W25QXX_PowerDown(void); //进入掉电模式
void W25QXX_WAKEUP(void); //唤醒
uint32_t W25QXX_ReadCapacity(void);
#endif

View File

@ -0,0 +1,58 @@
#include "HD_GPIO.h"
void HD_GPIO_Init(void)
{
// MX_GPIO_Init();
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOF_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
/*Configure GPIO pin Output Level */
// HAL_GPIO_WritePin(FLASH_CS_GPIO_Port, FLASH_CS_Pin, GPIO_PIN_RESET);
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOB, WDI_INPUT_Pin|RUN_LED_Pin|POW_FF_CON_Pin|POW_OUT_CON_Pin, GPIO_PIN_RESET);
/*Configure GPIO pin Output Level */
HAL_GPIO_WritePin(GPIOA, EN_PWMOUT_Pin|FFMOS_CON_Pin, GPIO_PIN_SET);
/*Configure GPIO pin : DSG_PROT_Pin */
GPIO_InitStruct.Pin = DSG_PROT_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(DSG_PROT_GPIO_Port, &GPIO_InitStruct);
/*Configure GPIO pins : FLASH_CS_Pin EN_PWMOUT_Pin FFMOS_CON_Pin */
// GPIO_InitStruct.Pin = FLASH_CS_Pin|EN_PWMOUT_Pin|FFMOS_CON_Pin;
// GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
// GPIO_InitStruct.Pull = GPIO_NOPULL;
// GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
// HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.Pin = EN_PWMOUT_Pin|FFMOS_CON_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/*Configure GPIO pins : WDI_INPUT_Pin RUN_LED_Pin POW_FF_CON_Pin POW_OUT_CON_Pin */
GPIO_InitStruct.Pin = WDI_INPUT_Pin|RUN_LED_Pin|POW_FF_CON_Pin|POW_OUT_CON_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/*Configure GPIO pin : WORK_VOLT_INT_Pin */
GPIO_InitStruct.Pin = WORK_VOLT_INT_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING;
GPIO_InitStruct.Pull = GPIO_PULLUP;
HAL_GPIO_Init(WORK_VOLT_INT_GPIO_Port, &GPIO_InitStruct);
/* EXTI interrupt init*/
HAL_NVIC_SetPriority(EXTI15_10_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(EXTI15_10_IRQn);
}

View File

@ -0,0 +1,11 @@
#include "HD_TIM.h"
void HD_PWM_Init(void)
{
MX_TIM3_Init();
}
void HD_controlTim_Init(void)
{
MX_TIM7_Init();
}

View File

@ -0,0 +1,334 @@
/**
* @file w25qxx.c
*
* @brief Create by AnKun on 2020/6/18
*
*/
#include "w25qxx.h"
#include "spi.h"
uint16_t W25QXX_TYPE = 0;
uint32_t W25QXX_SIZE = 0;
uint8_t W25QXX_UID[8];
static void delay_us(uint32_t us)
{
uint32_t delay = (HAL_RCC_GetHCLKFreq() / 4000000 * us);
while (delay--)
{
;
}
}
//SPI读写一个字节
//TxData:要写入的字节
//返回值:读取到的字节
static uint8_t W25QXX_SPI_ReadWriteByte(uint8_t TxData)
{
uint8_t RxData = 0X00;
if(HAL_SPI_TransmitReceive(W25QXX_SPI_Handle, &TxData, &RxData, 1, 10) != HAL_OK)
{
RxData = 0XFF;
}
return RxData;
}
//4Kbytes为一个Sector
//16个扇区为1个Block
//W25Q128
//容量为16M字节,共有128个Block,4096个Sector
//初始化SPI FLASH的IO口
int W25QXX_Init(void)
{
MX_SPI1_Init();
W25QXX_CS_L(); /* 拉低选中 */
W25QXX_SPI_ReadWriteByte(0XFF);
W25QXX_CS_H(); /* 拉高取消 */
W25QXX_TYPE = W25QXX_ReadID(); // 读取FLASH ID.
W25QXX_SIZE = W25QXX_ReadCapacity(); // 读取容量
W25QXX_ReadUniqueID(W25QXX_UID); // 读取唯一ID
if((W25QXX_TYPE & 0XEF00) != 0XEF00)
{
return -1;
}
return 0;
}
//读取W25QXX的状态寄存器
//BIT7 6 5 4 3 2 1 0
//SPR RV TB BP2 BP1 BP0 WEL BUSY
//SPR:默认0,状态寄存器保护位,配合WP使用
//TB,BP2,BP1,BP0:FLASH区域写保护设置
//WEL:写使能锁定
//BUSY:忙标记位(1,忙;0,空闲)
//默认:0x00
uint8_t W25QXX_ReadSR(void)
{
uint8_t byte = 0;
W25QXX_CS_L(); //使能器件
W25QXX_SPI_ReadWriteByte(W25X_ReadStatusReg); //发送读取状态寄存器命令
byte = W25QXX_SPI_ReadWriteByte(0Xff); //读取一个字节
W25QXX_CS_H(); //取消片选
return byte;
}
//写W25QXX状态寄存器
//只有SPR,TB,BP2,BP1,BP0(bit 7,5,4,3,2)可以写!!!
void W25QXX_Write_SR(uint8_t sr)
{
W25QXX_CS_L(); //使能器件
W25QXX_SPI_ReadWriteByte(W25X_WriteStatusReg); //发送写取状态寄存器命令
W25QXX_SPI_ReadWriteByte(sr); //写入一个字节
W25QXX_CS_H(); //取消片选
}
//W25QXX写使能
//将WEL置位
void W25QXX_Write_Enable(void)
{
W25QXX_CS_L(); //使能器件
W25QXX_SPI_ReadWriteByte(W25X_WriteEnable); //发送写使能
W25QXX_CS_H(); //取消片选
}
//W25QXX写禁止
//将WEL清零
void W25QXX_Write_Disable(void)
{
W25QXX_CS_L(); //使能器件
W25QXX_SPI_ReadWriteByte(W25X_WriteDisable); //发送写禁止指令
W25QXX_CS_H(); //取消片选
}
//读取芯片ID
//返回值如下:
//0XEF13,表示芯片型号为W25Q80
//0XEF14,表示芯片型号为W25Q16
//0XEF15,表示芯片型号为W25Q32
//0XEF16,表示芯片型号为W25Q64
//0XEF17,表示芯片型号为W25Q128
uint16_t W25QXX_ReadID(void)
{
uint16_t Temp = 0;
W25QXX_CS_L();
W25QXX_SPI_ReadWriteByte(0x90); //发送读取ID命令
W25QXX_SPI_ReadWriteByte(0x00);
W25QXX_SPI_ReadWriteByte(0x00);
W25QXX_SPI_ReadWriteByte(0x00);
Temp |= W25QXX_SPI_ReadWriteByte(0xFF) << 8;
Temp |= W25QXX_SPI_ReadWriteByte(0xFF);
W25QXX_CS_H();
return Temp;
}
uint32_t W25QXX_ReadCapacity(void)
{
int i = 0;
uint8_t arr[4] = {0,0,0,0};
W25QXX_CS_L();
W25QXX_SPI_ReadWriteByte(0x5A);
W25QXX_SPI_ReadWriteByte(0x00);
W25QXX_SPI_ReadWriteByte(0x00);
W25QXX_SPI_ReadWriteByte(0x84);
W25QXX_SPI_ReadWriteByte(0x00);
for(i = 0; i < sizeof(arr); i++)
{
arr[i] = W25QXX_SPI_ReadWriteByte(0xFF);
}
W25QXX_CS_H();
return ((((*(uint32_t *)arr)) + 1) >> 3);
}
void W25QXX_ReadUniqueID(uint8_t UID[8])
{
int i = 0;
W25QXX_CS_L();
W25QXX_SPI_ReadWriteByte(0x4B);
W25QXX_SPI_ReadWriteByte(0x00);
W25QXX_SPI_ReadWriteByte(0x00);
W25QXX_SPI_ReadWriteByte(0x00);
W25QXX_SPI_ReadWriteByte(0x00);
for(i = 0; i < 8; i++)
{
UID[i] = W25QXX_SPI_ReadWriteByte(0xFF);
}
W25QXX_CS_H();
}
//读取SPI FLASH
//在指定地址开始读取指定长度的数据
//pBuffer:数据存储区
//ReadAddr:开始读取的地址(24bit)
//NumByteToRead:要读取的字节数(最大65535)
void W25QXX_Read(uint8_t *pBuffer, uint32_t ReadAddr, uint16_t NumByteToRead)
{
uint16_t i;
W25QXX_CS_L(); //使能器件
W25QXX_SPI_ReadWriteByte(W25X_ReadData); //发送读取命令
W25QXX_SPI_ReadWriteByte((uint8_t)((ReadAddr) >> 16)); //发送24bit地址
W25QXX_SPI_ReadWriteByte((uint8_t)((ReadAddr) >> 8));
W25QXX_SPI_ReadWriteByte((uint8_t)ReadAddr);
for (i = 0; i < NumByteToRead; i++)
{
pBuffer[i] = W25QXX_SPI_ReadWriteByte(0XFF); //循环读数
}
W25QXX_CS_H();
}
//SPI在一页(0~65535)内写入少于256个字节的数据
//在指定地址开始写入最大256字节的数据
//pBuffer:数据存储区
//WriteAddr:开始写入的地址(24bit)
//NumByteToWrite:要写入的字节数(最大256),该数不应该超过该页的剩余字节数!!!
void W25QXX_Write_Page(uint8_t *pBuffer, uint32_t WriteAddr, uint16_t NumByteToWrite)
{
uint16_t i;
W25QXX_Write_Enable(); //SET WEL
W25QXX_CS_L(); //使能器件
W25QXX_SPI_ReadWriteByte(W25X_PageProgram); //发送写页命令
W25QXX_SPI_ReadWriteByte((uint8_t)((WriteAddr) >> 16)); //发送24bit地址
W25QXX_SPI_ReadWriteByte((uint8_t)((WriteAddr) >> 8));
W25QXX_SPI_ReadWriteByte((uint8_t)WriteAddr);
for (i = 0; i < NumByteToWrite; i++)
W25QXX_SPI_ReadWriteByte(pBuffer[i]); //循环写数
W25QXX_CS_H(); //取消片选
W25QXX_Wait_Busy(); //等待写入结束
}
//无检验写SPI FLASH
//必须确保所写的地址范围内的数据全部为0XFF,否则在非0XFF处写入的数据将失败!
//具有自动换页功能
//在指定地址开始写入指定长度的数据,但是要确保地址不越界!
//pBuffer:数据存储区
//WriteAddr:开始写入的地址(24bit)
//NumByteToWrite:要写入的字节数(最大65535)
//CHECK OK
void W25QXX_Write_NoCheck(uint8_t *pBuffer, uint32_t WriteAddr, uint16_t NumByteToWrite)
{
uint16_t pageremain;
pageremain = 256 - WriteAddr % 256; //单页剩余的字节数
if (NumByteToWrite <= pageremain)
pageremain = NumByteToWrite; //不大于256个字节
while (1)
{
W25QXX_Write_Page(pBuffer, WriteAddr, pageremain);
if (NumByteToWrite == pageremain)
break; //写入结束了
else //NumByteToWrite>pageremain
{
pBuffer += pageremain;
WriteAddr += pageremain;
NumByteToWrite -= pageremain; //减去已经写入了的字节数
if (NumByteToWrite > 256)
pageremain = 256; //一次可以写入256个字节
else
pageremain = NumByteToWrite; //不够256个字节了
}
};
}
//写SPI FLASH
//在指定地址开始写入指定长度的数据
//该函数带擦除操作!
//pBuffer:数据存储区
//WriteAddr:开始写入的地址(24bit)
//NumByteToWrite:要写入的字节数(最大65535)
uint8_t W25QXX_BUFFER[4096];
void W25QXX_Write(uint8_t *pBuffer, uint32_t WriteAddr, uint16_t NumByteToWrite)
{
uint32_t secpos;
uint16_t secoff;
uint16_t secremain;
uint16_t i;
uint8_t *W25QXX_BUF;
W25QXX_BUF = W25QXX_BUFFER;
secpos = WriteAddr / 4096; //扇区地址
secoff = WriteAddr % 4096; //在扇区内的偏移
secremain = 4096 - secoff; //扇区剩余空间大小
if (NumByteToWrite <= secremain)
secremain = NumByteToWrite; //不大于4096个字节
while (1)
{
W25QXX_Read(W25QXX_BUF, secpos * 4096, 4096); //读出整个扇区的内容
for (i = 0; i < secremain; i++) //校验数据
{
if (W25QXX_BUF[secoff + i] != 0XFF)
break; //需要擦除
}
if (i < secremain) //需要擦除
{
W25QXX_Erase_Sector(secpos); //擦除这个扇区
for (i = 0; i < secremain; i++) //复制
{
W25QXX_BUF[i + secoff] = pBuffer[i];
}
W25QXX_Write_NoCheck(W25QXX_BUF, secpos * 4096, 4096); //写入整个扇区
}
else
W25QXX_Write_NoCheck(pBuffer, WriteAddr, secremain); //写已经擦除了的,直接写入扇区剩余区间.
if (NumByteToWrite == secremain)
break; //写入结束了
else //写入未结束
{
secpos++; //扇区地址增1
secoff = 0; //偏移位置为0
pBuffer += secremain; //指针偏移
WriteAddr += secremain; //写地址偏移
NumByteToWrite -= secremain; //字节数递减
if (NumByteToWrite > 4096)
secremain = 4096; //下一个扇区还是写不完
else
secremain = NumByteToWrite; //下一个扇区可以写完了
}
};
}
//擦除整个芯片
//等待时间超长...
void W25QXX_Erase_Chip(void)
{
W25QXX_Write_Enable(); //SET WEL
W25QXX_Wait_Busy();
W25QXX_CS_L(); //使能器件
W25QXX_SPI_ReadWriteByte(W25X_ChipErase); //发送片擦除命令
W25QXX_CS_H(); //取消片选
W25QXX_Wait_Busy(); //等待芯片擦除结束
}
//擦除一个扇区
//Dst_Addr:扇区地址 根据实际容量设置
//擦除一个山区的最少时间:150ms
void W25QXX_Erase_Sector(uint32_t Dst_Addr)
{
//监视falsh擦除情况,测试用
Dst_Addr *= 4096;
W25QXX_Write_Enable(); //SET WEL
W25QXX_Wait_Busy();
W25QXX_CS_L(); //使能器件
W25QXX_SPI_ReadWriteByte(W25X_SectorErase); //发送扇区擦除指令
W25QXX_SPI_ReadWriteByte((uint8_t)((Dst_Addr) >> 16)); //发送24bit地址
W25QXX_SPI_ReadWriteByte((uint8_t)((Dst_Addr) >> 8));
W25QXX_SPI_ReadWriteByte((uint8_t)Dst_Addr);
W25QXX_CS_H(); //取消片选
W25QXX_Wait_Busy(); //等待擦除完成
}
//等待空闲
void W25QXX_Wait_Busy(void)
{
while ((W25QXX_ReadSR() & 0x01) == 0x01); // 等待BUSY位清空
}
//进入掉电模式
void W25QXX_PowerDown(void)
{
W25QXX_CS_L(); //使能器件
W25QXX_SPI_ReadWriteByte(W25X_PowerDown); //发送掉电命令
W25QXX_CS_H(); //取消片选
delay_us(3); //等待TPD
}
//唤醒
void W25QXX_WAKEUP(void)
{
W25QXX_CS_L(); //使能器件
W25QXX_SPI_ReadWriteByte(W25X_ReleasePowerDown); // send W25X_PowerDown command 0xAB
W25QXX_CS_H(); //取消片选
delay_us(3); //等待TRES1
}

View File

@ -173,18 +173,18 @@ void SystemClock_Config(void)
* @param htim : TIM handle
* @retval None
*/
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
/* USER CODE BEGIN Callback 0 */
// void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
// {
// /* USER CODE BEGIN Callback 0 */
/* USER CODE END Callback 0 */
if (htim->Instance == TIM1) {
HAL_IncTick();
}
/* USER CODE BEGIN Callback 1 */
// /* USER CODE END Callback 0 */
// if (htim->Instance == TIM1) {
// HAL_IncTick();
// }
// /* USER CODE BEGIN Callback 1 */
/* USER CODE END Callback 1 */
}
// /* USER CODE END Callback 1 */
// }
/**
* @brief This function is executed in case of error occurrence.

View File

@ -365,6 +365,7 @@
<state>$PROJ_DIR$\..\APP\hardwareDriver\Inc</state>
<state>$PROJ_DIR$\..\tools\RingQueue</state>
<state>$PROJ_DIR$\..\tools</state>
<state>$PROJ_DIR$\..\tools\TimeSliceOffset</state>
</option>
<option>
<name>CCStdIncCheck</name>
@ -1102,6 +1103,63 @@
<data />
</settings>
</configuration>
<group>
<name>APP</name>
<group>
<name>application</name>
<file>
<name>$PROJ_DIR$\..\APP\application\Src\chargControl.c</name>
</file>
<file>
<name>$PROJ_DIR$\..\APP\application\Src\comm.c</name>
</file>
<file>
<name>$PROJ_DIR$\..\APP\application\Src\start.c</name>
</file>
<file>
<name>$PROJ_DIR$\..\APP\application\Src\task.c</name>
</file>
</group>
<group>
<name>businessLogic</name>
<file>
<name>$PROJ_DIR$\..\APP\businessLogic\Src\bl_chargControl.c</name>
</file>
<file>
<name>$PROJ_DIR$\..\APP\businessLogic\Src\bl_comm.c</name>
</file>
<file>
<name>$PROJ_DIR$\..\APP\businessLogic\Src\inFlash.c</name>
</file>
<file>
<name>$PROJ_DIR$\..\APP\businessLogic\Src\parameter.c</name>
</file>
</group>
<group>
<name>functionalModule</name>
<file>
<name>$PROJ_DIR$\..\APP\functionalModule\Src\flash.c</name>
</file>
<file>
<name>$PROJ_DIR$\..\APP\functionalModule\Src\FM_GPIO.c</name>
</file>
<file>
<name>$PROJ_DIR$\..\APP\functionalModule\Src\FM_TIM.c</name>
</file>
</group>
<group>
<name>hardwareDriver</name>
<file>
<name>$PROJ_DIR$\..\APP\hardwareDriver\Src\HD_GPIO.c</name>
</file>
<file>
<name>$PROJ_DIR$\..\APP\hardwareDriver\Src\HD_TIM.c</name>
</file>
<file>
<name>$PROJ_DIR$\..\APP\hardwareDriver\Src\w25qxx.c</name>
</file>
</group>
</group>
<group>
<name>Application</name>
<group>
@ -1237,4 +1295,13 @@
</group>
</group>
</group>
<group>
<name>tools</name>
<file>
<name>$PROJ_DIR$\..\tools\RingQueue\ring_queue.c</name>
</file>
<file>
<name>$PROJ_DIR$\..\tools\TimeSliceOffset\timeSliceOffset.c</name>
</file>
</group>
</project>

View File

@ -1426,6 +1426,63 @@
</data>
</settings>
</configuration>
<group>
<name>APP</name>
<group>
<name>application</name>
<file>
<name>$PROJ_DIR$\..\APP\application\Src\chargControl.c</name>
</file>
<file>
<name>$PROJ_DIR$\..\APP\application\Src\comm.c</name>
</file>
<file>
<name>$PROJ_DIR$\..\APP\application\Src\start.c</name>
</file>
<file>
<name>$PROJ_DIR$\..\APP\application\Src\task.c</name>
</file>
</group>
<group>
<name>businessLogic</name>
<file>
<name>$PROJ_DIR$\..\APP\businessLogic\Src\bl_chargControl.c</name>
</file>
<file>
<name>$PROJ_DIR$\..\APP\businessLogic\Src\bl_comm.c</name>
</file>
<file>
<name>$PROJ_DIR$\..\APP\businessLogic\Src\inFlash.c</name>
</file>
<file>
<name>$PROJ_DIR$\..\APP\businessLogic\Src\parameter.c</name>
</file>
</group>
<group>
<name>functionalModule</name>
<file>
<name>$PROJ_DIR$\..\APP\functionalModule\Src\flash.c</name>
</file>
<file>
<name>$PROJ_DIR$\..\APP\functionalModule\Src\FM_GPIO.c</name>
</file>
<file>
<name>$PROJ_DIR$\..\APP\functionalModule\Src\FM_TIM.c</name>
</file>
</group>
<group>
<name>hardwareDriver</name>
<file>
<name>$PROJ_DIR$\..\APP\hardwareDriver\Src\HD_GPIO.c</name>
</file>
<file>
<name>$PROJ_DIR$\..\APP\hardwareDriver\Src\HD_TIM.c</name>
</file>
<file>
<name>$PROJ_DIR$\..\APP\hardwareDriver\Src\w25qxx.c</name>
</file>
</group>
</group>
<group>
<name>Application</name>
<group>
@ -1561,4 +1618,13 @@
</group>
</group>
</group>
<group>
<name>tools</name>
<file>
<name>$PROJ_DIR$\..\tools\RingQueue\ring_queue.c</name>
</file>
<file>
<name>$PROJ_DIR$\..\tools\TimeSliceOffset\timeSliceOffset.c</name>
</file>
</group>
</project>

View File

@ -0,0 +1,149 @@
/*
* timeSliceOffset.c
*
* Created on: 2024622
* Author: psx
*/
#include "TimeSliceOffset.h"
static STR_TimeSliceOffset* pTimeSliceList = NULL; /**< 时间片链表入口(仅入口,最终直接指向设备实体,所需无需申请空间。链表是单向线性链表) */
/**
* @brief
* @param[in] pTSlice
* @param[in] taskFunc
* @param[in] reloadVal *tick基准即为任务执行间隔
* @param[in] offset
* @return
* - 0
* - 1
* - -1 pTSlice为空指针
* @par
* - reloadVal设置为零即非定时任务offset偏移量无效
* @par :
* @code
*
* TimeSliceOffset_Register(&m_timeSlice_1, Task_1, 0, 0); //0即非定时任务(每次轮询都会执行)
* TimeSliceOffset_Register(&m_timeSlice_2, Task_2, 10, 0); //10*1ms即10ms运行一次
* TimeSliceOffset_Register(&m_timeSlice_3, Task_3, 10, 5); //10*1ms即10ms运行一次与Task_2错开5ms这样就不会集中到同一个10ms的时间点上
*
* @endcode
*/
int TimeSliceOffset_Register(STR_TimeSliceOffset* pTSlice, \
void (*taskFunc)(void), \
unsigned short reloadVal, \
unsigned short offset)
{
if(NULL == pTSlice)return -1; /* 返回错误:无效对象 */
pTSlice->reloadVal = reloadVal;
pTSlice->count = reloadVal + offset; /* 添加偏移量,使得同一数值的时间片错开 */
pTSlice->taskFunc = taskFunc;
if(0 == reloadVal) /* 非定时任务 */
{
pTSlice->runFlag = 1; /* 非定时任务可运行标志默认为一 */
}
else /* 定时任务 */
{
pTSlice->runFlag = 0; /* 定时任务可运行标志默认为零 */
}
/*遍历链表,防止添加重复*/
for(STR_TimeSliceOffset* pTemp = pTimeSliceList; pTemp != NULL; pTemp = pTemp->pNext)
{
if(pTemp == pTSlice)
{
return 1; /* 返回成功:配置完成,但对象已存在,无需加入链表 */
}
}
/*加入链表*/
pTSlice->pNext = pTimeSliceList;
pTimeSliceList = pTSlice; /* 把对象加入到链表头部 */
return 0; /* 返回成功:注册成功 */
}
/**
* @brief
* @return
* - 0
* - 1
* - -1 pTSlice为空指针
* @endcode
*/
int TimeSliceOffset_Unregister(STR_TimeSliceOffset* pTSlice)
{
if (NULL == pTSlice) return -1; /* 返回错误:无效对象 */
/* 遍历链表 */
for (STR_TimeSliceOffset* pTemp = pTimeSliceList; pTemp != NULL; pTemp = pTemp->pNext) {
if (pTemp->pNext == pTSlice) {
pTemp->pNext = pTemp->pNext->pNext;
return 0; /* 返回成功:取消注册 */
} else if (pTemp == pTSlice) {
pTimeSliceList = pTemp->pNext;
// pTimeSliceList->pNext = pTemp->pNext->pNext;
return 0; /* 返回成功:取消注册 */
}
}
return 1; /* 返回成功:对象不存在于链表中 */
}
/**
* @brief (main的while循环)
* @param null
* @return null
* @par
* - null
*/
void TimeSliceOffset_Start(void)
{
while(1) /* 代替main的while循环 */
{
/*遍历时间片链表*/
for(STR_TimeSliceOffset* pTemp = pTimeSliceList; pTemp != NULL; pTemp = pTemp->pNext)
{
if(pTemp->runFlag) /* 可运行则调用任务函数 */
{
if(pTemp->reloadVal) /* 重载值不为0即定时任务 */
{
pTemp->runFlag = 0; /* 可运行标志清零,开启新一轮倒计时 */
}
pTemp->taskFunc();
}
}
// __WFI();
}
}
/**
* @brief (systick或定时器中断处理函数内)
* @param null
* @return null
* @par
* - null
*/
void TimeSliceOffset_Produce(void)
{
/*遍历时间片链表*/
for(STR_TimeSliceOffset* pTemp = pTimeSliceList; pTemp != NULL; pTemp = pTemp->pNext)
{
if(pTemp->reloadVal) /* 重载值不为0即定时任务 */
{
--pTemp->count; /* 计数器递减 */
if(0 == pTemp->count) /* 计数器递减到零 */
{
pTemp->runFlag = 1; /* 允许执行 */
pTemp->count = pTemp->reloadVal; /* 计数器重载 */
}
}
}
}

View File

@ -0,0 +1,42 @@
/*
* timeSliceOffset.h
*
* Created on: 2024622
* Author: psx
*/
#ifndef DRIVERS_TIMESLICEOFFSET_TIMESLICEOFFSET_H_
#define DRIVERS_TIMESLICEOFFSET_TIMESLICEOFFSET_H_
#include "pdebug.h"
/**时间片类*/
typedef struct _STR_TimeSliceOffset{
volatile unsigned char runFlag; /**< 可运行标志(1:可运行/0:不可运行) */
volatile unsigned short count; /**< 计数器 */
unsigned short reloadVal; /**< 重载值 */
void (*taskFunc)(void); /**< 任务函数的函数指针 */
struct _STR_TimeSliceOffset* pNext; /**< 指向下一个对象 */
}STR_TimeSliceOffset;
/********************************************函数声明********************************************/
/* 注册 */
int TimeSliceOffset_Register(STR_TimeSliceOffset* pTSlice, \
void (*taskFunc)(void), \
unsigned short reloadVal, \
unsigned short offset);
/* 取消注册 */
int TimeSliceOffset_Unregister(STR_TimeSliceOffset* pTSlice);
/* 启动时间片错位轮询(代替main的while循环) */
void TimeSliceOffset_Start(void);
/* 时间片生成(放到systick或定时器中断处理函数内) */
void TimeSliceOffset_Produce(void);
#endif /* DRIVERS_TIMESLICEOFFSET_TIMESLICEOFFSET_H_ */

View File

@ -7,7 +7,7 @@ typedef enum {
MPPT = 1, /* 最大功率充电 */
constantVoltage = 2, /* 恒压充电 */
floatCharg = 3 /* 浮充充电 */
}chargControlMode;
}_chargControlMode;
#endif

View File

@ -4,18 +4,18 @@
#include <stdio.h>
#include <string.h>
#include "uart_dev.h"
#include "pdebug.h"
// #include "uart_dev.h"
// #include "pdebug.h"
/* Comment out this define to include debug messages */
//#define NDEBUG
#define NDEBUG
#define log_info_enable 1
#define log_warn_enable 0
#define log_error_enable 0
/* Comment out this define to include log messages */
//#define NLOG
#define NLOG
#ifdef NDEBUG
#define debug(M, ...) do {}while(0)