Files
GateWay/Project/GateWay/source/User/Src/main.c
T
YuanHongbin fe4b9fabf8 fix(flash,upgrade): 注册应答/Flash并发/参数校验修复+升级后擦参数分区+注释统一UTF-8
- 注册应答先发后写Flash,重复注册参数无变化时跳过写入;SX1276发送前等待上一帧TxDone,防止应答帧被下一帧截断
- SPI Flash操作增加互斥锁(ReadPara/WritePara/AddLog/SavLogNum),修复多线程并发写坏参数镜像
- WritePara自行擦除参数区全部扇区并加越界保护;移除通用写函数中的日志簿记副作用(双擦+LastLogEndAddr污染)
- 开机参数加载增加CRC校验与通讯单元表语义清洗;修复忽略ReadPara返回值导致坏镜像放行并被回写洗白的问题
- RS485Send函数指针每次开机重设,不再从Flash恢复旧固件代码地址
- Boot升级完成置APP_BOOT_UPGRADE_FLAG,App启动时仅擦外部参数分区(扇区0~1,历史日志保留)并恢复标志
- 参数SavFlag绑定PARA_LAYOUT_VER布局版本戳,布局变更自动回退默认参数
- res gxjt改为仅擦参数分区,不再触发全片扫描
- 全部源码注释统一UTF-8(无BOM),修复历史GBK/UTF-8混合编码及乱码字符
- 软件版本 1.2 -> 1.3
2026-09-03 19:00:24 +08:00

531 lines
19 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 "main.h"
#include "CatOneTask.h"
#include "EthTask.h"
#include "LoraTask.h"
#include "RS485Task.h"
#include "DebugCmd.h"
#include "Update.h"
#include "spiflash.h"
//雅下: 81-00-00-06-00-01
// 81-00-00-06-00-02
// 81-00-00-06-00-03
// 81-00-00-06-00-04
// 81-00-00-06-00-05
// 81-00-00-06-00-06
// 81-00-00-06-00-07
// 81-00-00-06-00-08
// 81-00-00-06-00-09
// 81-00-00-06-00-0A
//网关MAC编码由Boot程序固定在0x4000(协议规定: VerInfo(1)+PrjNum(3)+GwNum(2))
bool MainDispEn = true;
static rt_thread_t Lora_Thread = RT_NULL;
static rt_thread_t Cat1_Thread = RT_NULL;
static rt_thread_t Eth_Thread = RT_NULL;
static rt_thread_t RS485Ch1_Thread = RT_NULL;
static rt_thread_t RS485Ch2_Thread = RT_NULL;
static rt_thread_t Debug_Thread = RT_NULL;
GateWayPara_t GateWay;
#define ARRAY_DIM(a) (sizeof(a) / sizeof((a)[0]))
//static int Battery_Level_Percent_Table[11] = {3000, 3650, 3700, 3740, 3760, 3795, 3840, 3910, 3980, 4070, 4150};
static int Battery_Level_Percent_Table[11] = {6000, 7300, 7400, 7480, 7520, 7590, 7680, 7820, 7960, 8140, 8300};
int toPercentage(int voltage)
{
int i;
if(voltage < Battery_Level_Percent_Table[0])
return 0;
for(i = 0; i<ARRAY_DIM(Battery_Level_Percent_Table); i++){
if(voltage < Battery_Level_Percent_Table[i])
return i*10 - (10UL * (int)(Battery_Level_Percent_Table[i] - voltage)) /
(int)(Battery_Level_Percent_Table[i] - Battery_Level_Percent_Table[i-1]);;
}
return 100;
}
/*****************************************************************************************
* 函数名称: MainDBGOnOff
* 功能描述: 主调试信息开关函数
* 参 数: OnOff,开关
* 返 回 值: 无
*****************************************************************************************/
void MainDBGOnOff(bool OnOff)
{
MainDispEn = OnOff;
if(OnOff)
Debug_Printf("\r\nMain Display Enable!\r\n\r\n");
else
Debug_Printf("\r\nMain Display Disable!\r\n\r\n");
}
void GateWayInit(void)
{
LogHeader_t Header;
uint32_t FlashID = SpiFlashReadId();
Debug_Printf("FlashID: %08x\r\n", FlashID);
memset((uint8_t *)&GateWay.ConfigPara, 0x00, sizeof(GWConfigPara_t));
boot_para_t bootParam;
dev_boot_read_param(&bootParam);
rt_kprintf("AppFlag: 0x%08x\r\n", bootParam.AppFlag);
/*升级完成后Boot置AppFlag=APP_BOOT_UPGRADE_FLAG(每次升级均置位,不限首次)。
App启动时据此擦除参数分区(仅扇区0~1,非全片擦除)并恢复APP_START_FLAG
随后ReadPara读到0xFF→SavFlag无效→自动加载默认参数,传感器重新注册。
须在下方升级异常检测之前处理,避免AppFlag!=APP_START_FLAG误触发全片擦除*/
if(bootParam.AppFlag == APP_BOOT_UPGRADE_FLAG) {
rt_kprintf("Upgrade done, erasing parameter partition...\r\n");
for(uint32_t Sector = GATEWEY_PARA_SAV_SECTOR; Sector < LOG_INFO_START_SECTOR; Sector++) {
SpiFlashEraseSector(Sector * SPIFLASH_SECTORSIZE);
}
bootParam.AppFlag = APP_START_FLAG;
dev_boot_write_param(bootParam);
}
/*检测升级异常(UpdateFlag仍为APP_UPDATE_FLAG 或 非首次且AppFlag无效)时擦外置Flash*/
if(bootParam.UpdateFlag == APP_UPDATE_FLAG
|| (bootParam.FirstRunFlag == 0 && bootParam.AppFlag != APP_START_FLAG)) {
rt_kprintf("Boot upgrade detected, erasing external Flash...\r\n");
SpiFlashEraseChip();
bootParam.UpdateFlag = 0;
dev_boot_write_param(bootParam);
}
bool NeedSavePara = false;
int ret = ReadPara((uint8_t *)&GateWay.ConfigPara, sizeof(GWConfigPara_t));
/*ReadPara返回-1表示CRC校验失败(参数镜像损坏)。原实现只检查SavFlag:
SavFlag位于结构体最前部,"部分损坏"的镜像(前部有效后部乱码)恰好保留合法
SavFlag,坏数据会被整体装入RAM——正是culs显示后面设备参数乱码的根源。
CRC失败必须回退默认参数,让传感器走重新注册流程*/
if(ret != 0) {
rt_kprintf("Para CRC Error, reset to default!\r\n");
}
if(ret != 0 || GateWay.ConfigPara.SavFlag != LOG_SAV_FLAG) {
/*CRC正常但SavFlag无效:flash参数为空(全新设备/曾执行res gxjt/Boot整片擦除后)
打印区分于CRC错误路径,便于现场排障判断走的是默认参数还是正常恢复*/
if(ret == 0)
rt_kprintf("Para empty, load default!\r\n");
NeedSavePara = true;
memset((uint8_t *)&GateWay.ConfigPara, 0x00, sizeof(GWConfigPara_t));
GateWay.ConfigPara.SavFlag = LOG_SAV_FLAG;
/*通道/服务器等默认参数全部从Boot参数区(BootPara_t)获取, 由Boot直接配置*/
GateWay.ConfigPara.Much = (Channel_m)bootParam.Much;
GateWay.ConfigPara.Auch = (Channel_m)bootParam.Auch;
GateWay.ConfigPara.Duch = (Channel_m)bootParam.Duch;
GateWay.ConfigPara.CuchMask = bootParam.CuchMask;
GateWay.ConfigPara.LTENet.DestAddr[0] = bootParam.SvrAddr[0];
GateWay.ConfigPara.LTENet.DestAddr[1] = bootParam.SvrAddr[1];
GateWay.ConfigPara.LTENet.DestAddr[2] = bootParam.SvrAddr[2];
GateWay.ConfigPara.LTENet.DestAddr[3] = bootParam.SvrAddr[3];
GateWay.ConfigPara.LTENet.DestPort = bootParam.SvrPort;
GateWay.ConfigPara.CommUnitReadInterval = COMMUNIT_READ_SENSOR_INTERVAL_MAX;//非低功耗设备
memset(GateWay.ConfigPara.CommUnitArray, 0x00, sizeof(CommUnitData_t) * COMMUNIT_NUM_MAX);
GateWay.ConfigPara.Rs485Ch1.Enable = true;
GateWay.ConfigPara.Rs485Ch1.CommUnitEnable = false;
GateWay.ConfigPara.Rs485Ch1.BaudRate = 500000;
GateWay.ConfigPara.Rs485Ch1.UpgradeEnable = true;
GateWay.ConfigPara.Rs485Ch1.Power = false;
GateWay.ConfigPara.Rs485Ch2.Enable = true;
GateWay.ConfigPara.Rs485Ch2.BaudRate = 500000;
GateWay.ConfigPara.Rs485Ch2.UpgradeEnable = false;
GateWay.ConfigPara.Rs485Ch2.CommUnitEnable = false;
GateWay.ConfigPara.Rs485Ch2.Power = false;
GateWay.ConfigPara.Lora.OnOff = true;
GateWay.ConfigPara.Lora.ucChannel = 8;
GateWay.ConfigPara.Lora.ucPower = 20;
GateWay.ConfigPara.Lora.SignalBw = 8;
GateWay.ConfigPara.Lora.SpreadFactor = 9;
GateWay.ConfigPara.Lora.ErrorCoding = 2;
GateWay.ConfigPara.Lora.RegPreamble = 10;
GateWay.ConfigPara.Lora.FreqCent = bootParam.LoraFreq;
GateWay.ConfigPara.OutageFlag = false;
}
else {
/*防御被"洗白"的脏数据(镜像部分损坏但CRC合法):对通讯单元表做语义校验,
清除无效条目,避免乱码条目占用注册槽位导致新设备注册不上*/
for(int i = 0; i < COMMUNIT_NUM_MAX; i++) {
CommUnitPara_t *CU = &GateWay.ConfigPara.CommUnitArray[i];
uint8_t RegByte;
memcpy(&RegByte, &CU->RegFlag, 1); //绕过编译器对bool取值0/1的假定,读取原始字节
bool EntryValid = (RegByte == 0 || RegByte == 1);
if(EntryValid && RegByte == 1) {
bool MacAllFF = true, MacAll00 = true;
for(int j = 0; j < 6; j++) {
if(CU->Mac[0][j] != 0xFF) MacAllFF = false;
if(CU->Mac[0][j] != 0x00) MacAll00 = false;
}
if(CU->SensorN == 0 || CU->SensorN > SENSOR_NUM_MAX || MacAllFF || MacAll00)
EntryValid = false;
}
if(!EntryValid) {
memset(CU, 0x00, sizeof(CommUnitPara_t));
NeedSavePara = true;
}
}
if(NeedSavePara)
rt_kprintf("CommUnit table dirty, cleaned!\r\n");
}
/*函数指针不允许从Flash恢复:正常加载路径下RS485Send来自旧固件写入Flash的
代码地址,固件升级后代码布局变化会使该指针失效(野指针)。每次开机统一重设*/
GateWay.ConfigPara.Rs485Ch1.RS485Send = RS485Ch1UartSend;
GateWay.ConfigPara.Rs485Ch2.RS485Send = RS485Ch2UartSend;
/*网关MAC编码从Boot参数区(BootPara_t.GwMac)获取, 由Boot从固定地址0x4000同步
(协议规定: Mac[0]=VerInfo, Mac[1:3]=PrjNum, Mac[4:5]=GwNum)*/
for(int i = 0; i < 6; i++) {
GateWay.ConfigPara.GwMac[i] = bootParam.GwMac[i];
}
/*参照hc32l170_app UpdateInit: 保证AppFlag=APP_START_FLAG, 使Boot下次直接跳转App*/
UpdateInit();
if(GateWay.ConfigPara.OutageFlag != true && GateWay.ConfigPara.OutageFlag != false)
GateWay.ConfigPara.OutageFlag = false;
GateWay.MuchRegFlag = false;
memset(GateWay.SvrMac, 0x00, 6);
if(ChannelIsActive(GateWay.ConfigPara, CH_RS485_1)) {
GateWay.ConfigPara.Rs485Ch1.Enable = true;
GateWay.ConfigPara.Rs485Ch1.BaudRate = 500000;
}
if(GateWay.ConfigPara.Rs485Ch1.BaudRate < 2400 || GateWay.ConfigPara.Rs485Ch1.BaudRate > 921600)
GateWay.ConfigPara.Rs485Ch1.BaudRate = 500000;
RS485Ch1_Config(GateWay.ConfigPara.Rs485Ch1.BaudRate);
if(ChannelIsActive(GateWay.ConfigPara, CH_RS485_2)) {
GateWay.ConfigPara.Rs485Ch2.Enable = true;
GateWay.ConfigPara.Rs485Ch2.BaudRate = 500000;
}
if(GateWay.ConfigPara.Rs485Ch2.BaudRate < 2400 || GateWay.ConfigPara.Rs485Ch2.BaudRate > 921600)
GateWay.ConfigPara.Rs485Ch2.BaudRate = 500000;
RS485Ch2_Config(GateWay.ConfigPara.Rs485Ch2.BaudRate);
if(GateWay.ConfigPara.Rs485Ch1.Power)
RS485_CH1_POW_ON();
else
RS485_CH1_POW_OFF();
if(GateWay.ConfigPara.Rs485Ch2.Power) {
RS485_CH2_POW_OFF();
rt_thread_delay(1000);
RS485_CH2_POW_ON();
}
else
RS485_CH2_POW_OFF();
if(GateWay.ConfigPara.Lora.OnOff == true) {
LORA_POW_ON();
}
else {
LORA_POW_OFF();
}
if(LoraSetChannel(GateWay.ConfigPara.Lora.ucChannel) == false) {
GateWay.ConfigPara.Lora.ucChannel = 8;
LoraSetChannel(GateWay.ConfigPara.Lora.ucChannel);
//WritePara((uint8_t *)&GateWay.ConfigPara, sizeof(GWConfigPara_t));
}
if(LoraSetFreqCent(GateWay.ConfigPara.Lora.FreqCent) == false)
{
GateWay.ConfigPara.Lora.FreqCent = 470100000;
LoraSetFreqCent(GateWay.ConfigPara.Lora.FreqCent);
}
if(LoraSetPower(GateWay.ConfigPara.Lora.ucPower) == false) {
GateWay.ConfigPara.Lora.ucPower = 20;
LoraSetPower(GateWay.ConfigPara.Lora.ucPower);
//WritePara((uint8_t *)&GateWay.ConfigPara, sizeof(GWConfigPara_t));
}
if(LoraSetSignalBw(GateWay.ConfigPara.Lora.SignalBw) == false) {
GateWay.ConfigPara.Lora.SignalBw = 8;
LoraSetSignalBw(GateWay.ConfigPara.Lora.SignalBw);
//WritePara((uint8_t *)&GateWay.ConfigPara, sizeof(GWConfigPara_t));
}
if(LoraSetSpreadFactor(GateWay.ConfigPara.Lora.SpreadFactor) == false) {
GateWay.ConfigPara.Lora.SpreadFactor = 9;
LoraSetSpreadFactor(GateWay.ConfigPara.Lora.SpreadFactor);
//WritePara((uint8_t *)&GateWay.ConfigPara, sizeof(GWConfigPara_t));
}
if(LoraSetErrorCoding(GateWay.ConfigPara.Lora.ErrorCoding) == false) {
GateWay.ConfigPara.Lora.ErrorCoding = 2;
LoraSetErrorCoding(GateWay.ConfigPara.Lora.ErrorCoding);
//WritePara((uint8_t *)&GateWay.ConfigPara, sizeof(GWConfigPara_t));
}
if(GateWay.ConfigPara.Lora.RegPreamble > 0xFE) {
GateWay.ConfigPara.Lora.RegPreamble = 10;
LoraSetRegPreamble(GateWay.ConfigPara.Lora.RegPreamble);
//WritePara((uint8_t *)&GateWay.ConfigPara, sizeof(GWConfigPara_t));
}
/*原实现开机无条件回写参数:一方面无谓增加一次擦写磨损;另一方面若读出的
是坏数据,回写会重新计算CRC把脏数据"洗白"成永久合法,无法自愈。
仅在参数被重置或清洗过时才落盘*/
if(NeedSavePara)
WritePara((uint8_t *)&GateWay.ConfigPara, sizeof(GWConfigPara_t));
LogInit();
Header.LogEndAddr = 0;
if(ReadLogNum() > 0) {
int ret = ReadLog(&Header, NULL, 0);
if(ret > 0) {
GateWay.HistoryNum = ReadLogNum() - Header.LogIdx + 1;
rt_kprintf("History Num: %d\r\n", GateWay.HistoryNum);
}
else {
rt_kprintf("History Num: 0\r\n");
}
}
else
rt_kprintf("History Num: 0\r\n");
bool cat1Active = ChannelIsActive(GateWay.ConfigPara, CH_CAT1);
bool ethActive = ChannelIsActive(GateWay.ConfigPara, CH_ETH);
if(cat1Active) { DbgOrCat1Uart_Config(115200); CAT1_ON(); }
else { DBG_ON(); DbgOrCat1Uart_Config(500000); }
if(ethActive) { ETH_ON(); rt_thread_delay(1000); ETHReset(); }
}
void OutageUpdate(uint8_t AlarmType, bool AlarmState, uint8_t Batt)
{
GateWayAlarmType_t *Alarm;
uint8_t MegData[6],len;
len = sizeof(GateWayAlarmType_t);
MegData[0] = len & 0x00ff;;
MegData[1] = (len >> 8) & 0x00ff;
MegData[2] = NET_COMM_CMD_ALARM;
Alarm = (GateWayAlarmType_t *)&MegData[3];
Alarm->AlarmType = AlarmType;
Alarm->AlarmState = AlarmState;
Alarm->AlarmPara = Batt;
UploadSend(MegData, 6); //发送报警信息
}
/*****************************************************************************************
* 函数名称: main
* 功能描述: 主函数
* 参 数: 无
* 返 回 值: 运行错误返回-1
*****************************************************************************************/
static uint8_t LastBattery = 0xff; //上一次电池电压
int main(void)
{
uint16_t OneSecondDlyCnt = 0;
// struct tm cTime;
uint16_t PowerONLedDly = 2000;
uint32_t SystemRseetDlyCnt = 0;
uint32_t BatteryUpdateDlyCnt = 0;
uint8_t AlarmType = 0;
GateWayInit();
rt_kprintf("\r\n\r\n");
rt_kprintf("****************************************************\r\n");
rt_kprintf("** **\r\n");
rt_kprintf("** GateWay **\r\n");
rt_kprintf("** SoftWare V%d.%d **\r\n", SOFTWARE_VERSION / 10, SOFTWARE_VERSION % 10);
rt_kprintf("** HardWare V%d.%d **\r\n", HARDWARE_VERSION / 10, HARDWARE_VERSION % 10);
rt_kprintf("** Compile: %s %s **\r\n", __DATE__, __TIME__);
rt_kprintf("** **\r\n");
rt_kprintf("****************************************************\r\n\r\n");
// TimeGet(&cTime);
// TimeShow(TimeTs());
FeedDog();
//Cat1DBGOnOff(true);
GateWay.CommUnitRevCallBack = CommUnitAnalyze;
GateWay.MuchRevCallBack = MuchRevCallBack;
GateWay.AuchRevCallBack = AuchRevCallBack;
for(int i = 0; i < 6; i++) {
char name[8];
sprintf(name, "ChMQ%d", i);
GateWay.ChMQ[i] = rt_mq_create(name, 256, 5, RT_IPC_FLAG_FIFO);
}
GateWay.LoraRev_MQ = rt_mq_create("LoraRevMQ", 256, 10, RT_IPC_FLAG_FIFO);
if(GateWay.LoraRev_MQ == RT_NULL) {
rt_kprintf("LoraRev MQ Create Failed!\r\n");
}
GateWay.UartRevMutex = rt_mutex_create("urmutex", RT_IPC_FLAG_FIFO);
if(GateWay.UartRevMutex == RT_NULL) {
rt_kprintf("UR Mutex Create Failed!\r\n");
}
GateWay.EthTxMutex = rt_mutex_create("ethtxmtx", RT_IPC_FLAG_FIFO);
if(GateWay.EthTxMutex == RT_NULL) {
rt_kprintf("EthTx Mutex Create Failed!\r\n");
}
RS485Ch1_Thread = rt_thread_create("RS485Ch1", RS485Ch1_Thread_Entry, &GateWay, 2048, 3, 20);
if (RS485Ch1_Thread != RT_NULL)
rt_thread_startup(RS485Ch1_Thread);
else
return -1;
RS485Ch2_Thread = rt_thread_create("RS485Ch2", RS485Ch2_Thread_Entry, &GateWay, 2048, 3, 20);
if (RS485Ch2_Thread != RT_NULL)
rt_thread_startup(RS485Ch2_Thread);
else
return -1;
Debug_Thread = rt_thread_create("DebugUart", Debug_Thread_Entry, &GateWay, 2048, 3, 20);
if (Debug_Thread != RT_NULL)
rt_thread_startup(Debug_Thread);
else
return -1;
Cat1_Thread = rt_thread_create("Cat1", CatOne_Thread_Entry, &GateWay, 4096, 3, 20);
if (Cat1_Thread != RT_NULL)
rt_thread_startup(Cat1_Thread);
else
return -1;
Eth_Thread = rt_thread_create("Eth", Eth_Thread_Entry, &GateWay, 4096, 3, 20);
if (Eth_Thread != RT_NULL)
rt_thread_startup(Eth_Thread);
else
return -1;
Lora_Thread = rt_thread_create("Lora", Lora_Thread_Entry, &GateWay, 1024, 3, 20);
if (Lora_Thread != RT_NULL)
rt_thread_startup(Lora_Thread);
else
return -1;
while(1) {
if(PowerONLedDly > 0) {
PowerONLedDly--;
if(PowerONLedDly == 1) {
POWER_LED_OFF();
}
}
if(ChannelIsActive(GateWay.ConfigPara, CH_ETH)) EthOverHandler();
if(ChannelIsActive(GateWay.ConfigPara, CH_RS485_1) || ChannelIsActive(GateWay.ConfigPara, CH_RS485_2)
|| GateWay.ConfigPara.Rs485Ch1.UpgradeEnable || GateWay.ConfigPara.Rs485Ch2.UpgradeEnable)
RS485RxOverhandler();
DebugOrCat1RxOverhandler();
if(OneSecondDlyCnt % 200 == 0) {
FeedDog();
LORA_RX_TOGGLE();
POWER_TOGGLE();
}
OneSecondDlyCnt++;
if(OneSecondDlyCnt == 1000) {
OneSecondDlyCnt = 0;
if(GateWay.BatteryReadDlyCnt > 0) {
GateWay.BatteryReadDlyCnt--;
continue;
}
uint16_t ADValue = GetADCBuffPoint();
//V = (AD * 3.3 / 4096) * (R1+R2) / R1; R1 = 200, R2 = 120
//计算出常数为0.0021484375,扩大1000倍
float Voltage = ADValue * 2.1484375;
GateWay.Battery = toPercentage(Voltage);
//上电判断电量
if(LastBattery == 0xff) {
LastBattery = GateWay.Battery;
if(GateWay.ConfigPara.OutageFlag == true) { //有报警
AlarmType = 1;
}
else {
AlarmType = 0;
}
//BatteryUpdateDlyCnt = 2 * 60;
BatteryUpdateDlyCnt = 10;
}
else {
if(GateWay.ConfigPara.OutageFlag == false) { //没有告警,判断电池电压是否降低
if(GateWay.Battery <= LastBattery) {
if(LastBattery <= 5) {
GateWay.ConfigPara.OutageFlag = true;
WritePara((uint8_t *)&GateWay.ConfigPara, sizeof(GWConfigPara_t));
Debug_Printf("The power is cutted.(1) Bat = %d, LBat = %d\r\n", GateWay.Battery, LastBattery);
LastBattery = GateWay.Battery;
AlarmType = 1;
OutageUpdate(AlarmType, GateWay.ConfigPara.OutageFlag, LastBattery);
BatteryUpdateDlyCnt = 20 * 60;
}
else if((LastBattery - GateWay.Battery) > 2) {
GateWay.ConfigPara.OutageFlag = true;
WritePara((uint8_t *)&GateWay.ConfigPara, sizeof(GWConfigPara_t));
LastBattery = GateWay.Battery;
AlarmType = 1;
Debug_Printf("The power is cutted.(2) Bat = %d, LBat = %d\r\n", GateWay.Battery, LastBattery);
OutageUpdate(AlarmType, GateWay.ConfigPara.OutageFlag, LastBattery);
BatteryUpdateDlyCnt = 20 * 60;
}
}
else { //充电,更新上一次电池电压
LastBattery = GateWay.Battery;
}
}
else {
if(GateWay.Battery >= LastBattery) {
if(LastBattery > 95) {
GateWay.ConfigPara.OutageFlag = false;
WritePara((uint8_t *)&GateWay.ConfigPara, sizeof(GWConfigPara_t));
Debug_Printf("The power is restored.(1) Bat = %d, LBat = %d\r\n", GateWay.Battery, LastBattery);
LastBattery = GateWay.Battery;
AlarmType = 1;
OutageUpdate(AlarmType, GateWay.ConfigPara.OutageFlag, LastBattery);
BatteryUpdateDlyCnt = 90 * 60;
AlarmType = 0;
}
else if(GateWay.Battery - LastBattery > 5) {
GateWay.ConfigPara.OutageFlag = false;
WritePara((uint8_t *)&GateWay.ConfigPara, sizeof(GWConfigPara_t));
Debug_Printf("The power is restored.(2) Bat = %d, LBat = %d\r\n", GateWay.Battery, LastBattery);
LastBattery = GateWay.Battery;
AlarmType = 1;
OutageUpdate(AlarmType, GateWay.ConfigPara.OutageFlag, LastBattery);
BatteryUpdateDlyCnt = 90 * 60;
AlarmType = 0;
}
}
else { //电池继续放电,更新上一次电池电压
LastBattery = GateWay.Battery;
}
}
}
BatteryUpdateDlyCnt--;
if(BatteryUpdateDlyCnt == 0) {
if(GateWay.ConfigPara.OutageFlag) { //有报警
BatteryUpdateDlyCnt = 20 * 60;
}
else {
BatteryUpdateDlyCnt = 90 * 60;
}
OutageUpdate(AlarmType, GateWay.ConfigPara.OutageFlag, LastBattery);
}
//ADC_Start();
}
SystemRseetDlyCnt++;
if(SystemRseetDlyCnt > (24 * 60 * 60 * 1000)) {
SystemRseetDlyCnt = 0;
Debug_Printf("The system resets periodically.\r\n");
rt_thread_delay(3000);
NVIC_SystemReset();
}
rt_thread_delay(1);
}
}