#include "sys_config.h" #if UPLOAD_MODE_2 #include "UWater_frame_app.h" #include "UWater_eeprom_driver.h" #include "UWater_Timer1us_driver.h" #include "UWater_lptimer_driver.h" #include "UWater_rtcc_driver.h" #include "UWater_valve_driver.h" #include "UWater_Lcd_driver.h" #include "eeprom_app.h" #include "UWater_rtcc_app.h" #include "UWater_power_app.h" #include "UWater_gp22_app.h" #include "UWater_DataTools_App.h" #include "UWater_key_app.h" #include "UWater_pt_app.h" #include "UWater_DebugPrint.h" #include "UWater_Valve_app.h" #include #include "UWater_sys.h" #include "soe.h" #include "sys_processor_ble.h" static u8 s_upload_eep_complete=0; static u8 save_freeze_sate = SAVE_FREEZE_S0; //数据冻结类状态机 static u8 data_save_judge_flag = FALSE; //保存冻结类数据 static u8 sys_deal_judge_flag = FALSE; //系统处理 static DateTime sys_rtcc_time; //用于获取系统当前时间 static u16 sys_temp_min_hex;//分钟转16进制格式 //RTC故障超时时间 static u32 rtcc_err_check_time=0; static u8 rtcc_err_check_count=0; static u8 sys_rtcc_clk_source=0; static u8 sys_rtcc_check_flag=FALSE; TYP_STATE_SS ble_monitor_state=SS_STATE_S0; //广播数据更新 u8 ble_adv_buf[13]; //状态字 UNION_4U8TOU32 met_state_old; UNION_4U8TOU32 met_state_new; u8 sys_reverse_flow_state=0;//逆流标志 //流量变化计算 RTCC_To_Float sys_total_flow_new; RTCC_To_Float sys_total_flow_old; RTCC_To_Float sys_total_re_flow_new; RTCC_To_Float sys_total_re_flow_old; //离散和补传机制变量 //#define __no_init __attribute__((zero_init)) //__no_init volatile u8 upload_again_cnt_copy __attribute__((section(".ARM.__at_0x20007F34"))); /****************************************时间扫描、消息分发**********************/ void MinuteEventScan(void) { if (0x02 == (RtccCheckMsg() & 0x02))//分钟消息 { RtccClearMsg(1); RtccSetMsgApp(RtccMsg_UploadInTime); //RTCC定时上报 RtccSetMsgApp(RtccMsg_OtherProtl); //抛给其他规约的分钟消息 FrameSetMsgApp(Msg_FrozenStore); //冻结数据 data_save_judge_flag = TRUE; //保存冻结类数据 sys_deal_judge_flag = TRUE; //系统处理 RtccSetMsgApp(RtccMsg_ValveActive); } } //系统处理 void SysDealAppMachine(void) { if(sys_deal_judge_flag) { sys_deal_judge_flag = FALSE; rtcc_err_check_count=0; RtccGetDateTime(&sys_rtcc_time); if(0 == sys_rtcc_time.s.minute) //整点时间 { FrameSetMsgApp(MsgTouchKeyReset);//复位触摸按键消息 if (sys_rtcc_time.s.hour == 0x00)//0点清除触摸次数 { FrameSetMsgApp(MsgTchKey_ClearKeyLimit);//清除触摸按键限制次数 sys_rtcc_check_flag = TRUE;//检测一下时钟 BleClearResetCount();//清除每日复位次数 if((BCD2HEX(sys_rtcc_time.s.day)%Sys_data_object.P1.func_cfg_bytes[22])==0) { BleStartInitTask();//上电初始化蓝牙 } } if(sys_rtcc_time.s.hour == 0x02) //每天2点置换能器检测标志 { RtccSetMsgApp(RtccMsg_Transducer_Check); if(TRUE == CheckDiftofCalibrationFlag()) { RtccSetMsgApp(RtccMsg_DiftofCalibration);//每天2点置校准零流量标志 } } } //非检定超时不休眠防护 if (10 == LcdCheckStateApp()) //非检定状态 { PowerUnSleepSumAddSys(); } } /** 外部32768晶振失效防护: 1、main函数休眠期间收不到RTC秒中断唤醒,看门狗复位表计使表计重新选择RTC时钟。 2、检定或唤醒期间通过1us定时器计算时间超过2分钟而收不到分钟消息,则复位表计重新选择RTC时钟。 3、如果时钟已经切换到内部低速时钟,则每天重新检查一次是否外部时钟又恢复正常。 */ if(Timer1usGetTick() - rtcc_err_check_time > 1000000)//1秒,防止检定和唤醒 { rtcc_err_check_time = Timer1usGetTick(); rtcc_err_check_count++; if(rtcc_err_check_count > 120) { rtcc_err_check_count = 0; Meter_ResetCountAdd(0x08); NVIC_SystemReset(); } } if((sys_rtcc_check_flag==TRUE)&&(LcdCheckStateApp() == 10))//非检定状态 { sys_rtcc_check_flag = FALSE; if(RTC_ClkSource() == 1)//如果是内部RC { sys_rtcc_clk_source = RtccInit(); if(sys_rtcc_clk_source == 0)//如果切换成了外部RC { LPTimer1Init(sys_rtcc_clk_source); } } } } void SysDealAppPreSleep(void) { rtcc_err_check_count = 0; if(BleGetPowerState()==BlePowerOk) { if(Sys_data_object.P1.func_cfg_bytes[0] > 0)//如果在厂区时段,表计休眠则给蓝牙掉电 { if(RtccCheckTimer(RTCC_BLE_ACTIVE_TIME)==0)//手动唤醒时间结束 { BleForcePowerOff(BlePowerFactory); } } } } //查询事件上报类型 u8 GetEventUploadType(void) { return 0; } //判空闲 u8 FixedTimeNbIoTUploadIfIdle(void) { return TASK_IDLE; } /*******************************数据存储******************************/ IES_PULSE_DAY_MAX_FLOW ies_pulse_day_max_flow; static void SysCheckFlowMinMax(DateTime alarm_time) { static u16 pulse_day_max_flow_time_temp; static u32 old_total_speed = 0; static u32 new_total_speed = 0; static u8 date_flag = 0; RTCC_To_Float temp_to_gloat;//数据转换专用 if((0 == alarm_time.s.hour) && (0 == alarm_time.s.minute)) //每天0点刷新上传数据 { old_total_speed = 0; pulse_day_max_flow_time_temp =0; date_flag = 0; RtccGetDateTime(&alarm_time); ies_pulse_day_max_flow.pulse_flow_time[0] = alarm_time.s.second; ies_pulse_day_max_flow.pulse_flow_time[1] = alarm_time.s.minute; ies_pulse_day_max_flow.pulse_flow_time[2] = alarm_time.s.hour; ies_pulse_day_max_flow.pulse_flow_time[3] = alarm_time.s.weekday; ies_pulse_day_max_flow.pulse_flow_time[4] = alarm_time.s.day; ies_pulse_day_max_flow.pulse_flow_time[5] = alarm_time.s.month; ies_pulse_day_max_flow.pulse_flow_time[6] = alarm_time.s.year; ies_pulse_day_max_flow.pulse_flow_time[7] = 0x20; } //流量更新 new_total_speed = Gp30CheckDataApp(GP30_APP_INS_FLOW); if((0.9*old_total_speed) < new_total_speed < (1.1*old_total_speed)) { pulse_day_max_flow_time_temp++;//持续时间增加 ies_pulse_day_max_flow.pulse_continue_time.to_uint16 = pulse_day_max_flow_time_temp*60; temp_to_gloat.gp22_float = new_total_speed; //瞬时流量 瞬时流量单位为0.01L/H,4字节无符号整数。 ies_pulse_day_max_flow.pulse_max_flow.to_uint32 = (u32)(temp_to_gloat.gp22_float / (float)65536.00)/60; //平台转换成每小时用水量 //判断开始时间是否更新 if(date_flag==1) { date_flag = 0; RtccGetDateTime(&alarm_time); ies_pulse_day_max_flow.pulse_flow_time[0] = alarm_time.s.second; ies_pulse_day_max_flow.pulse_flow_time[1] = alarm_time.s.minute; ies_pulse_day_max_flow.pulse_flow_time[2] = alarm_time.s.hour; ies_pulse_day_max_flow.pulse_flow_time[3] = alarm_time.s.weekday; ies_pulse_day_max_flow.pulse_flow_time[4] = alarm_time.s.day; ies_pulse_day_max_flow.pulse_flow_time[5] = alarm_time.s.month; ies_pulse_day_max_flow.pulse_flow_time[6] = alarm_time.s.year; ies_pulse_day_max_flow.pulse_flow_time[7] = 0x20; } } else if(new_total_speed <= (0.9*old_total_speed))//流量变小 { pulse_day_max_flow_time_temp = 0; date_flag = 1; } else if(new_total_speed >= (1.1*old_total_speed))//流量变大 { old_total_speed = new_total_speed; pulse_day_max_flow_time_temp =0; date_flag = 0; ies_pulse_day_max_flow.pulse_flow_time[0] = alarm_time.s.second; ies_pulse_day_max_flow.pulse_flow_time[1] = alarm_time.s.minute; ies_pulse_day_max_flow.pulse_flow_time[2] = alarm_time.s.hour; ies_pulse_day_max_flow.pulse_flow_time[3] = alarm_time.s.weekday; ies_pulse_day_max_flow.pulse_flow_time[4] = alarm_time.s.day; ies_pulse_day_max_flow.pulse_flow_time[5] = alarm_time.s.month; ies_pulse_day_max_flow.pulse_flow_time[6] = alarm_time.s.year; ies_pulse_day_max_flow.pulse_flow_time[7] = 0x20; } } //获取日最高流量数据 void RtccCheck_Hight_Flow(u8 **addr) { *addr = ies_pulse_day_max_flow.byte; } void SaveFreezeData(void) { switch(save_freeze_sate) { case SAVE_FREEZE_S0: { if(data_save_judge_flag) { data_save_judge_flag = FALSE; RtccGetDateTime(&sys_rtcc_time); sys_temp_min_hex = (sys_rtcc_time.s.minute >> 4)*10 + (sys_rtcc_time.s.minute & 0x0F); if(0 ==(sys_temp_min_hex % 5))//5分钟间隔 { RtccAppCheckMiJi(sys_rtcc_time); } if(0 == sys_rtcc_time.s.minute) //整点时间 { save_freeze_sate = SAVE_FREEZE_S1; } SysCheckFlowMinMax(sys_rtcc_time); } } break; case SAVE_FREEZE_S1: { if (EepIfIdle()) { Sys_data_object.ee_data.data.work_hour++;//累计工作时间增加 EepWrite(Sys_data_object.ee_data.byte, EE_FIRST_USE_ADDR, sizeof (RTCC_EE_DATA), &s_upload_eep_complete); save_freeze_sate = SAVE_FREEZE_S2; } } break; case SAVE_FREEZE_S2://厂区时间判断 { if (EepIfIdle()) { if(0 == sys_rtcc_time.s.hour) //每天0点 { if(Sys_data_object.P1.func_cfg_bytes[0] > 0) { Sys_data_object.P1.func_cfg_bytes[0]--; EepWrite(&Sys_data_object.P1.func_cfg_bytes[0],ee_addr_compute((u8*)(&Sys_data_object.P1.func_cfg_bytes[0])),1,&s_upload_eep_complete); } } save_freeze_sate = SAVE_FREEZE_S3; } } break; case SAVE_FREEZE_S3://整点存储功耗信息 { if(TASK_IDLE == EepIfIdle()) { EepWrite(&(Sys_data_object.P1.run_information_object.total_use_sum_times_sec.to_uint8[0]), EEP_FRMAE_BATTERY_ENERGY, sizeof(Sys_data_object.P1.run_information_object), &s_upload_eep_complete); save_freeze_sate = SAVE_FREEZE_S7; } } break; case SAVE_FREEZE_S7: { if (EepIfIdle()) { save_freeze_sate = SAVE_FREEZE_S0; } } break; default: { save_freeze_sate = SAVE_FREEZE_S0; } break; } } void SysBleStateMonitor(void) { //检测流量是否变化1方 sys_total_flow_new.gp22_u32 = Gp30CheckDataApp(GP30_APP_TOTAL_FLOW); if(((sys_total_flow_new.gp22_float - sys_total_flow_old.gp22_float)>100)|| ((sys_total_flow_old.gp22_float - sys_total_flow_new.gp22_float)>100))//1立方 { sys_total_flow_old.gp22_u32 = sys_total_flow_new.gp22_u32; FrameSetMsgApp(MsgBLE_AdvChange); } //检查是否倒转 sys_total_re_flow_new.gp22_u32 = Gp30CheckDataApp(GP30_APP_TOTAL_FLOW_REVERSE); if((sys_total_re_flow_new.gp22_float - sys_total_re_flow_old.gp22_float)>1)//10L { sys_total_re_flow_old.gp22_u32 = sys_total_re_flow_new.gp22_u32; sys_reverse_flow_state=1;//设置逆流标志 } if((sys_total_flow_new.gp22_float - sys_total_flow_old.gp22_float)>1)//10L { sys_total_re_flow_old.gp22_u32 = sys_total_re_flow_new.gp22_u32;//正向超过10L,倒转计数重新开始 sys_reverse_flow_state=0;//清除逆流标志 } //检查状态是否发生变化 met_state_new = getBleWetState(); if(met_state_old.datas != met_state_new.datas) { met_state_old.datas = met_state_new.datas; FrameSetMsgApp(MsgBLE_AdvChange); } //检测是否异常复位 if(BleCheckIfResetFlag())//唤醒时蓝牙空闲状态发生复位 { BleClrIfResetFlag(); if(BleIfIdle()==TASK_IDLE)//蓝牙空闲时发生复位,则重启模组.否则就清除消息跳过 { ble_monitor_state = SS_STATE_S0; BleStartInitTask();//上电初始化蓝牙 } } //修改蓝牙配置参数 if(BleIfIdle()==TASK_IDLE) { if(FrameCheckMsgApp(MsgBLE_ConfigChange)) { FrameClearMsgApp(MsgBLE_ConfigChange); BleChangeAdvParaTask(); } } } void SysBleMonitorMachine() { switch(ble_monitor_state) { case SS_STATE_S0: { if(Sys_data_object.P1.func_cfg_bytes[0] == 0)//不是厂区模式 { if(BleGetCurConState() == CON_ING)//蓝牙连接 { Set100msTimer(TIMER_100MS_BLE_CON_REV30S,50);//设置5s等待读表数据 setBleReadAccessFlag(0);//清除鉴权标志 ble_monitor_state = SS_STATE_S20; } else if(FrameCheckMsgApp(MsgBLE_AdvChange))//更新广播数据(初始化成功\下初值\日冻结数据时间\流量变化1方) { if(BleIfIdle()==TASK_IDLE) { FrameClearMsgApp(MsgBLE_AdvChange); ble_monitor_state = SS_STATE_S3; } } else if(FrameCheckMsgApp(MsgAddr_Change))//修改表地址,重启蓝牙 { FrameClearMsgApp(MsgAddr_Change); BleStartInitTask();//上电初始化蓝牙 } } else { if(FrameCheckMsgApp(Msg_FactoryBleActive)) { FrameClearMsgApp(Msg_FactoryBleActive); if(RtccCheckTimer(RTCC_BLE_ACTIVE_TIME)==0)//只有唤醒时间结束才初始化蓝牙,节省每日初始化次数 { BleClearResetCount();//清除每日复位次数 BleStartInitTask();//上电初始化蓝牙 } RtccSetTimer(RTCC_BLE_ACTIVE_TIME,600);//厂区模式,按键唤醒蓝牙工作10分钟 } if(RtccCheckTimer(RTCC_BLE_ACTIVE_TIME)!=0) { if(BleGetCurConState() == CON_ING)//蓝牙连接 { Set100msTimer(TIMER_100MS_BLE_CON_REV30S,50);//设置5s等待读表数据 setBleReadAccessFlag(0);//清除鉴权标志 ble_monitor_state = SS_STATE_S20; } else if(FrameCheckMsgApp(MsgBLE_AdvChange))//更新广播数据(初始化成功\下初值\日冻结数据时间\流量变化1方) { if(BleIfIdle()==TASK_IDLE) { FrameClearMsgApp(MsgBLE_AdvChange); ble_monitor_state = SS_STATE_S3; } } else if(FrameCheckMsgApp(MsgAddr_Change))//修改表地址,重启蓝牙 { FrameClearMsgApp(MsgAddr_Change); BleStartInitTask();//上电初始化蓝牙 } } } } break; case SS_STATE_S20://蓝牙连接 { if(FrameCheckMsgApp(MsgBLE_ReadData))//收到抄读表数据指令(握手帧) { FrameClearMsgApp(MsgBLE_ReadData); Set100msTimer(TIMER_100MS_BLE_CON_REV30S,300);//30s Set100msTimer(TIMER_100MS_BLE_CON_ALL90S,900);//90s ble_monitor_state = SS_STATE_S21; } else if(FrameCheckMsgApp(MsgBLE_RevData))//收到的不是握手帧,断开连接 { FrameClearMsgApp(MsgBLE_RevData); BleConMacTask(CON_STOP_ORDER, NULL); Set100msTimer(TIMER_100MS_BLE_CON_REV30S,50); ble_monitor_state = SS_STATE_S22; } else if(BleGetCurConState() == CON_END)//主机主动断开连接 { ble_monitor_state = SS_STATE_S22; } else if(Check100msTimer(TIMER_100MS_BLE_CON_REV30S)==0)//5s超时没收到读表数据命令,主动断开连接 { BleConMacTask(CON_STOP_ORDER, NULL); Set100msTimer(TIMER_100MS_BLE_CON_REV30S,50); ble_monitor_state = SS_STATE_S22; } } break; case SS_STATE_S21://连接状态处理 { if(FrameCheckMsgApp(MsgBLE_RevData))//收到新指令,延时30秒 { FrameClearMsgApp(MsgBLE_RevData); Set100msTimer(TIMER_100MS_BLE_CON_REV30S,300);//30 } else if(BleGetCurConState() == CON_END)//主机主动断开连接 { ble_monitor_state = SS_STATE_S22; } else if(FrameCheckMsgApp(MsgBLE_OtaEnter))//进入OTA { FrameClearMsgApp(MsgBLE_OtaEnter); ble_monitor_state = SS_STATE_S5; } else if((Check100msTimer(TIMER_100MS_BLE_CON_REV30S)==0)||(Check100msTimer(TIMER_100MS_BLE_CON_ALL90S)==0))//超时断开连接 { BleConMacTask(CON_STOP_ORDER, NULL); Set100msTimer(TIMER_100MS_BLE_CON_REV30S,50); ble_monitor_state = SS_STATE_S22; } } break; case SS_STATE_S22://等待连接断开 { if(BleGetCurConState() == CON_END) { LcdDisplayActiveGPRS(0);//关闭无线符号 ble_monitor_state = SS_STATE_S0; } else if(Check100msTimer(TIMER_100MS_BLE_CON_REV30S)==0)//超时没有断开连接,重启蓝牙 { LcdDisplayActiveGPRS(0);//关闭无线符号 BleStartInitTask();//上电初始化蓝牙 ble_monitor_state = SS_STATE_S0; } } break; case SS_STATE_S3://更新广播信息 { //获取当前流量 QZ_U32_To_Float temp_float_data; UNION_4U8TOU32 temp_data1; UNION_2U8TOU16 temp_data2; temp_float_data.gp22_u32 = Gp30CheckDataApp(2); temp_data1.datas = (u32)temp_float_data.gp22_float*10; ble_adv_buf[0] = 12; ble_adv_buf[12]=0; //累计流量 ble_adv_buf[1] = temp_data1.data_buf[0]; ble_adv_buf[2] = temp_data1.data_buf[1]; ble_adv_buf[3] = temp_data1.data_buf[2]; ble_adv_buf[4] = temp_data1.data_buf[3]; //温度 temp_float_data.gp22_float = TempCheckValueApp(); if(temp_float_data.gp22_float<0)//低温小于0 { temp_data1.datas = -(temp_float_data.gp22_float*100); temp_data2.datas = 0x8000|temp_data1.datas; } else//低温大于0 { temp_data2.datas = (u16)(temp_float_data.gp22_float*100); } ble_adv_buf[5] = temp_data2.data_buf[0]; ble_adv_buf[6] = temp_data2.data_buf[1]; //状态字 UNION_4U8TOU32 temp_MetState; temp_MetState = getBleWetState(); ble_adv_buf[7] = temp_MetState.datas_map.data0; ble_adv_buf[8] = temp_MetState.datas_map.data1; ble_adv_buf[9] = temp_MetState.datas_map.data2; ble_adv_buf[10]= temp_MetState.datas_map.data3; //数据帧校验和 ble_adv_buf[11] = 0; for(int i=1;i<11;i++) { ble_adv_buf[11] += ble_adv_buf[i]; } //AT指令校验和 for(int i=1;i<12;i++) { ble_adv_buf[12] += ble_adv_buf[i]; } Set100msTimer(TIMER_100MS_BLE_CON_REV30S,50); ble_monitor_state = SS_STATE_S4; } break; case SS_STATE_S4://等待更新广播完成,// { if(BleIfIdle()==TASK_IDLE) { if(BleUpdataAdvDataTask(ble_adv_buf)==TRUE) { ble_monitor_state = SS_STATE_S0; } } else if(BleGetCurConState() == CON_END)//主机主动断开连接 { ble_monitor_state = SS_STATE_S0; } else if(Check100msTimer(TIMER_100MS_BLE_CON_REV30S)==0)//超时没有更新成功,重启模组 { BleStartInitTask();//上电初始化蓝牙 ble_monitor_state = SS_STATE_S0; } } break; case SS_STATE_S5://OTA升级等待,超时表计复位处理 { if(FrameCheckMsgApp(MsgBLE_OtaExit))//退出OTA { FrameClearMsgApp(MsgBLE_OtaExit); ble_monitor_state = SS_STATE_S0; } } break; default: { ble_monitor_state = SS_STATE_S0; } break; } } //判空闲 u8 BleConnectIfIdle(void) { if(ble_monitor_state == SS_STATE_S0) { return TASK_IDLE; } else { return TASK_BUSY; } } u8 GetMcuResetSouce(void) { u8 reset_souce; reset_souce = Reset_GetFlag(ResetFlagMskRstb);//RESET脚复位 reset_souce <<= 1; reset_souce |= Reset_GetFlag(ResetFlagMskSysreq);//软件复位 reset_souce <<= 1; reset_souce |= Reset_GetFlag(ResetFlagMskLockup);//系统异常复位 reset_souce <<= 1; reset_souce |= Reset_GetFlag(ResetFlagMskPca);//PCA复位 reset_souce <<= 1; reset_souce |= Reset_GetFlag(ResetFlagMskWdt);//看门狗复位 reset_souce <<= 1; reset_souce |= Reset_GetFlag(ResetFlagMskLvd);//低电压检测复位 reset_souce <<= 1; reset_souce |= Reset_GetFlag(ResetFlagMskPor1_5V);//1.5V启动复位 reset_souce <<= 1; reset_souce |= Reset_GetFlag(ResetFlagMskPor5V);//5V启动复位 reset_souce <<= 1; return reset_souce; } /******************************************************************************* * @fun_name: SystemProcessor * @brief : 上传和上传数据存储 * @param[in] : None * @param[out]: None * @retval : None * @other : ******************************************************************************/ void SystemProcessor(void) { MinuteEventScan(); SysDealAppMachine(); SaveFreezeData(); DataStoreMachine(); SysBleMonitorMachine(); SysBleStateMonitor(); } void SystemProcessorInit(void) { SaveNewSoe(SOE_SY_SYS_RESET, GetMcuResetSouce());//系统重启记录 if(Reset_GetFlag(ResetFlagMskWdt))//看门狗复位 { FrameSetMsgApp(Msg_WdtReset); //用于复位补偿 } if(Reset_GetFlag(ResetFlagMskPor5V))//欠压或硬复位 { FrameSetMsgApp(Msg_Por5VReset); //GP30复位 } Reset_ClearFlagAll();//清复位标识寄存器 DataStoreInit(); BleStartInitTask();//上电初始化蓝牙 RtccSetTimer(RTCC_BLE_ACTIVE_TIME,60);//厂区模式唤醒时间1分钟 //表计状态和累计流量初始化 met_state_new = getBleWetState(); met_state_old.datas = met_state_new.datas; sys_total_flow_new.gp22_u32 = Gp30CheckDataApp(GP30_APP_TOTAL_FLOW); sys_total_flow_old.gp22_u32 = sys_total_flow_new.gp22_u32; sys_total_re_flow_old.gp22_u32 = sys_total_re_flow_new.gp22_u32; } u8 SystemProcessorIfSleep(void) { if((DataStoreIfIdle() == TRUE)&&(BleConnectIfIdle() == TASK_IDLE)) { return TRUE; } return FALSE; } #endif