Maopaijd Wincc Lcfj

#include "apdefap.h"

//WinCC全局动作入口函数,脚本周期默认1s执行一次
int gscAction( void )
{
	//整机模式总开关DWord变量:0关闭/1手动/3自动轮换/4时控模式
	unsigned long AltEn;
	//全局运行累计分钟计时器,所有运行模式共用,画面显示用
	unsigned long Min_Cnt;
	//全局运行累计秒计时器,所有运行模式共用,画面显示用
	unsigned long Sec_Cnt;
	//当前运行风机标记:0无风机运行/1风机1运行/2风机2运行
	unsigned long RunFlag;
	//自动模式废弃旧周期计时器(兼容旧变量,保留读写)
	unsigned long Auto_Cnt;
	//自动模式全局总累计计时器,单位分钟,模式3下运行/停机全程累加,用于风机轮换判断
	unsigned long Auto_Total_Cnt;
	//风机1单次设定运行时长,单位分钟
	unsigned long M1_Run_Min;
	//风机1单次设定停机时长,单位分钟
	unsigned long M1_Stop_Min;
	//风机2单次设定运行时长,单位分钟
	unsigned long M2_Run_Min;
	//风机2单次设定停机时长,单位分钟
	unsigned long M2_Stop_Min;
	//自动模式总切换时长阈值,总时长达到且允许切换则互换主风机
	unsigned long Auto_Total_Min;

	//【静态局部变量,函数调用间保持数值,无需外部变量】
	//自动模式单轮周期秒计时
	static unsigned long cycle_sec ;
	//自动模式单轮周期分钟计时
	static unsigned long cycle_min ;
	//风机A(风机1)运行状态:0运行、1停机
	static int Fan_StatusA;
	//风机B(风机2)运行状态:0运行、1停机
	static int Fan_StatusB;
	//指定风机固定运行开关  0固定风机1 1固定风机2
	unsigned long Run_Fan_x;
	//指定风机固定开关上次状态缓存标记,静态持久化
	static unsigned long last_Run_Fan_x = 888;
	//天数切换开关BOOL:0=风机1主循环,1=风机2主循环
	static BOOL Day_Switch;
	//自动模式首次初始化标记,切换自动模式时复位
	BOOL Auto_Init_Flag;
	//公共判断标记:任意一台风机输出启动信号则置1,用于统一计时逻辑
	BOOL bAnyMotorRun;

	//PLC侧风机1远程自动模式反馈点位
	BOOL bM1Remote;
	//PLC侧风机1故障报警信号,1=故障,0=正常
	BOOL bM1Fault;
	//PLC侧风机2远程自动模式反馈点位
	BOOL bM2Remote;
	//PLC侧风机2故障报警信号,1=故障,0=正常
	BOOL bM2Fault;

	//画面手动操作按钮变量,模式1手动模式使用
	BOOL bManualM1Start;
	//画面手动操作按钮变量,模式1手动模式使用
	BOOL bManualM2Start;
	// 天数切换允许开关:1允许总时长到切换风机,0禁止切换
	BOOL Auto_Switch_Enable;

	BOOL bTimerValid; //时控区间有效标记,1=当前在定时区间,0=不在
	static BOOL	TimerSwitchBit; //时控自动轮换风机切换标记,静态保存
	static BOOL	TimerSwitchBitp;//时控区间进入单次触发标记,静态保存

	unsigned long Sk_startHM;//时控开始时间,HHMM格式数字
	unsigned long Sk_endHM;//时控结束时间,HHMM格式数字

	//==================== 【公共临时局部变量定义区】====================
	//系统时间结构体指针,存放解析后的时/分/秒/日/月/年
	struct tm* pLocalTime;
	//时间戳变量,存储从1970至今的总秒数原始时间
	time_t lTime;
	//提取当前系统小时,数值范围0~23
	int CurHour;
	//提取当前系统分钟,数值范围0~59
	int CurMin;
	//提取当前系统秒,仅用于计时累加,定时判断不使用
	int CurSec;
	//当日总分钟 = 小时*60+分钟,统一换算后简化定时区间对比逻辑
	int CurTotalMin;
	//当前时间合并为HHMM格式数字,用于画面显示、定时区间对比
	unsigned long C_HHMM;
	//时控停止区间倒计时秒计数器,静态持久化
	static unsigned long sotop_sec=0;

	//==================== 【第一步:统一读取系统本地时间】====================
	//获取当前系统UTC时间戳,返回1970至今总秒数存入lTime变量
	lTime = time(NULL);
	//将时间戳转换为本地时区可读时间结构体,赋值给指针pLocalTime
	pLocalTime = localtime(&lTime);
	//从时间结构体取出当前小时赋值给CurHour变量
	CurHour = pLocalTime->tm_hour;
	//从时间结构体取出当前分钟赋值给CurMin变量
	CurMin  = pLocalTime->tm_min;
	//从时间结构体取出当前秒赋值给CurSec变量
	CurSec  = pLocalTime->tm_sec;
	//换算当前时间为当日总分钟,用于周期计时判断
	CurTotalMin = CurHour * 60 + CurMin;
	//拼接当前时分HHMM数字,用于定时区间对比、画面时间显示标签
	C_HHMM = CurHour*100 + CurMin ;

	//==================== 【第二步:一次性读取全部外部标签变量】====================
	//读取整机模式总开关DWord变量
	AltEn = GetTagDWord("Alt_Enable");
	//读取全局累计分钟计时器当前存储值
	Min_Cnt = GetTagDWord("Min_Cnt");
	//读取全局累计秒计时器当前存储值
	Sec_Cnt = GetTagDWord("Sec_Cnt");
	//读取当前正在运行的风机标记
	RunFlag = GetTagDWord("Run_Motor_Flag");
	//读取自动模式废弃旧周期计时器(兼容旧变量,保留读写)
	Auto_Cnt = GetTagDWord("Auto_Cnt");
	//读取自动模式总累计计时器当前值
	Auto_Total_Cnt = GetTagDWord("Auto_Total_Cnt");

	//读取画面手动风机1启动按钮状态
	bManualM1Start = GetTagBit("Manual_M1_Start");
	//读取画面手动风机2启动按钮状态
	bManualM2Start = GetTagBit("Manual_M2_Start");

	//读取风机1远程/本地模式反馈信号
	bM1Remote = GetTagBit("LCFJ1.Remote");
	//读取风机1故障报警点位状态
	bM1Fault = GetTagBit("LCFJ1.Fault");
	//读取风机2远程/本地模式反馈信号
	bM2Remote = GetTagBit("LCFJ2.Remote");
	//读取风机2故障报警点位状态
	bM2Fault = GetTagBit("LCFJ2.Fault");

	//读取自动模式主风机切换开关
	Day_Switch = GetTagBit("Day_Switch");
	//读取风机1单次运行设定时长
	M1_Run_Min = GetTagDWord("M1_Run_Min");
	//读取风机1单次停机设定时长
	M1_Stop_Min = GetTagDWord("M1_Stop_Min");
	//读取风机2单次运行设定时长
	M2_Run_Min = GetTagDWord("M2_Run_Min");
	//读取风机2单次停机设定时长
	M2_Stop_Min = GetTagDWord("M2_Stop_Min");
	//读取自动模式总切换时长阈值
	Auto_Total_Min = GetTagDWord("Auto_Total_Min");
	//读取自动模式首次初始化标记
	Auto_Init_Flag = GetTagBit("Auto_Init_Flag");
	//读取切换允许开关状态
	Auto_Switch_Enable = GetTagBit("Auto_Switch_Enable");
	//获取固定要运行的风机选择开关
	Run_Fan_x = GetTagBit("Run_Fan_x");
	//读取 时控的启动时间和停止时间
	Sk_startHM = GetTagDWord("Sk_startHM");
	Sk_endHM = 	GetTagDWord("Sk_endHM");

	//==================== 【最高优先级保护逻辑1:两台风机同时故障,整机强制停机清零】====================
	//判断风机1、风机2同时存在故障报警
	if(bM1Fault == 1 && bM2Fault == 1)
	{
		//风机1启动输出置0,停止风机1
		SetTagBit("LCFJ1.Start_Button", 0);
		//风机1停止输出置1,强制停机指令
		SetTagBit("LCFJ1.Stop_Button", 1);
		//风机2启动输出置0,停止风机2
		SetTagBit("LCFJ2.Start_Button", 0);
		//风机2停止输出置1,强制停机指令
		SetTagBit("LCFJ2.Stop_Button", 1);

		//全局运行分钟计时器清零复位
		SetTagDWord("Min_Cnt", 0);
		//全局运行秒计时器清零复位
		SetTagDWord("Sec_Cnt", 0);
		//运行风机标记清零,标记无风机运行
		SetTagDWord("Run_Motor_Flag", 0);
		//自动模式废弃周期计时器清零
		SetTagDWord("Auto_Cnt",0);
		//自动模式总累计计时器清零复位
		SetTagDWord("Auto_Total_Cnt",0);
		//静态分秒计时器清零
		cycle_min = 0;
		cycle_sec = 0;
		//自动模式初始化标记复位
		SetTagBit("Auto_Init_Flag",0);
		//保护触发,直接结束本次动作循环,不再执行后续逻辑
		return 0;
	}

	//==================== 【最高优先级保护逻辑2:任意风机切本地非远程模式,整机停机清零】====================
	//风机1或风机2切换至本地手动模式,退出自动控制逻辑
	if(bM1Remote == 0 ||  bM2Remote == 0)
	{
		//关闭风机1启动输出信号
		SetTagBit("LCFJ1.Start_Button", 0);
		//打开风机1强制停机输出
		SetTagBit("LCFJ1.Stop_Button", 1);
		//关闭风机2启动输出信号
		SetTagBit("LCFJ2.Start_Button", 0);
		//打开风机2强制停机输出
		SetTagBit("LCFJ2.Stop_Button", 1);

		//全局分钟计时清零
		SetTagDWord("Min_Cnt", 0);
		//全局秒计时清零
		SetTagDWord("Sec_Cnt", 0);
		//运行风机标记清零
		SetTagDWord("Run_Motor_Flag", 0);
		//自动模式废弃周期计时器清零复位
		SetTagDWord("Auto_Cnt",0);
		//自动模式总累计计时器清零复位
		SetTagDWord("Auto_Total_Cnt",0);
		//静态分秒计时器清零
		cycle_min = 0;
		cycle_sec = 0;
		//自动模式初始化标记复位
		SetTagBit("Auto_Init_Flag",0);
		//保护触发,直接退出本次循环
		return 0;
	}
	
	//参数最小阈值检测,防止参数设0导致死循环
	if(M1_Run_Min <= 0)		M1_Run_Min=1;
	if(M1_Stop_Min <=0)		M1_Stop_Min=1;
	if(M2_Run_Min <= 0)		M2_Run_Min=1;
	if(M2_Stop_Min <= 0)		M2_Stop_Min=1;
	if(Auto_Total_Min <= 0)		Auto_Total_Min=5;

	//==================== 【模式分支选择器:根据AltEn切换对应控制逻辑】====================
	switch(AltEn)
	{
			//==================== Case1:模式0,整机关闭,全部风机停机、所有标记清零 ====================
		case 1:
		{
			//关闭风机1启动输出
			SetTagBit("LCFJ1.Start_Button", 0);
			//开启风机1停机输出
			SetTagBit("LCFJ1.Stop_Button", 1);
			//关闭风机2启动输出
			SetTagBit("LCFJ2.Start_Button", 0);
			//开启风机2停机输出
			SetTagBit("LCFJ2.Stop_Button", 1);

			//内存全局分钟计时器清零
			Min_Cnt=0;
			//写入外部标签全局分钟计时器清零
			SetTagDWord("Min_Cnt", 0);
			//内存全局秒计时器清零
			Sec_Cnt=0;
			//写入外部标签全局秒计时器清零
			SetTagDWord("Sec_Cnt", 0);
			//运行风机外部标记清零
			SetTagDWord("Run_Motor_Flag", 0);
			//内存废弃周期计时器清零
			Auto_Cnt=0;
			//写入外部废弃周期计时器清零
			SetTagDWord("Auto_Cnt",0);
			//内存自动总计时清零
			Auto_Total_Cnt=0;
			//写入外部自动总计时清零
			SetTagDWord("Auto_Total_Cnt",Auto_Total_Cnt);

			//静态自动周期分秒计时器清零
			cycle_min = 0;
			cycle_sec = 0;
			//复位自动模式初始化标记
			SetTagBit("Auto_Init_Flag",0);
			//本地内存运行标记清零
			RunFlag = 0;

			//复位画面风机1手动启动按钮锁存
			SetTagBit("Manual_M1_Start",0);
			//复位画面风机2手动启动按钮锁存
			SetTagBit("Manual_M2_Start",0);
			//时控单次触发标记复位,为下次进入做好准备
			TimerSwitchBitp = 0;
			//本地运行标记清零
			RunFlag = 0;
			//退出模式0分支
			break;
		}

			//==================== Case2:模式2,手动模式,画面按钮独立控制两台风机 ====================
		case 2:
		{
			//清空自动模式废弃周期计时器
			SetTagDWord("Auto_Cnt",0);
			//内存自动总计时清零
			Auto_Total_Cnt=0;
			//写入外部自动总计时清零
			SetTagDWord("Auto_Total_Cnt",Auto_Total_Cnt);
			//自动周期静态计时器清零
			cycle_min = 0;
			cycle_sec = 0;
			//时控单次触发标记复位
			TimerSwitchBitp = 0;
			//运行标记清零
			RunFlag = 0;
			//复位自动初始化标记
			SetTagBit("Auto_Init_Flag",0);
			//----------------------风机1手动启停控制逻辑----------------------
			//画面手动启动风机1按钮按下
			if(bManualM1Start == 1)
			{
				//风机1启动输出置1,启动风机
				SetTagBit("LCFJ1.Start_Button", 1);
				//风机1停止输出置0,解除停机指令
				SetTagBit("LCFJ1.Stop_Button", 0);

				//全局运行秒计数器+1,脚本周期1秒触发一次
				Sec_Cnt = Sec_Cnt + 1;
				//秒计数达到60秒,执行进位分钟逻辑
				if(Sec_Cnt >= 60)
				{
					//秒计数器归零
					Sec_Cnt = 0;
					//全局分钟计数器+1
					Min_Cnt = Min_Cnt + 1;
				}

				//当前运行标记不是风机1,代表刚切换启动风机1
				if(RunFlag != 1)
				{
					//更新运行标记为风机1
					RunFlag = 1;
				}
			}
			//手动按钮松开,停止风机1
			else
			{
				//关闭风机1启动输出
				SetTagBit("LCFJ1.Start_Button", 0);
				//打开风机1停止输出停机指令
				SetTagBit("LCFJ1.Stop_Button", 1);
			}

			//----------------------风机2手动启停控制逻辑----------------------
			//画面手动启动风机2按钮按下
			if(bManualM2Start == 1)
			{
				//风机2启动输出置1,启动风机
				SetTagBit("LCFJ2.Start_Button", 1);
				//风机2停止输出置0,解除停机指令
				SetTagBit("LCFJ2.Stop_Button", 0);

				//全局运行秒计数器+1,脚本周期1秒触发一次
				Sec_Cnt = Sec_Cnt + 1;
				//秒计数达到60秒,执行进位分钟逻辑
				if(Sec_Cnt >= 60)
				{
					//秒计数器归零
					Sec_Cnt = 0;
					//全局分钟计数器+1
					Min_Cnt = Min_Cnt + 1;
				}

				//当前运行标记不是风机2,刚切换启动风机2
				if(RunFlag != 2)
				{
					//更新运行标记为风机2
					RunFlag = 2;
				}
			}
			//手动按钮松开,停止风机2
			else
			{
				//关闭风机2启动输出
				SetTagBit("LCFJ2.Start_Button", 0);
				//打开风机2停机输出指令
				SetTagBit("LCFJ2.Stop_Button", 1);
			}

			//两个手动按钮全部松开,无风机手动运行
			if((bManualM2Start == 0) && (bManualM1Start == 0))
			{
				//运行标记置0,无风机运行
				RunFlag = 0;
				//全局分钟计时清零
				Min_Cnt = 0;
				//全局秒计时清零
				Sec_Cnt = 0;
			}
			//退出手动模式分支
			break;
		}

			//Case3:模式3 自动轮换模式(模式3下风机运行/停机总计时全程累加)
		case 3:
		{
			//进入自动模式,复位风机1手动按钮锁存
			SetTagBit("Manual_M1_Start",0);
			//进入自动模式,复位风机2手动按钮锁存
			SetTagBit("Manual_M2_Start",0);
			//时控单次触发标记复位
			TimerSwitchBitp = 0;
			//运行标记清零
			RunFlag = 0;

			//判断时控起止时间是否不一致,启用定时区间限制
			if(Sk_endHM !=  Sk_startHM)
			{
				//结束时间小于开始时间,代表跨天定时区间(如22点~次日6点)
				if(Sk_endHM <  Sk_startHM)
				{
					// 判断当前时间不在跨天区间内
					if(!(C_HHMM >= Sk_startHM || C_HHMM < Sk_endHM))
					{
						//自动周期计时清零
						cycle_min = 0;
						cycle_sec = 0;
						//画面显示计时同步清零
						Min_Cnt = cycle_min;
						Sec_Cnt = cycle_sec;
						//写入外部画面计时标签
						SetTagDWord("Min_Cnt", Min_Cnt);
						SetTagDWord("Sec_Cnt", Sec_Cnt);
						//停止区间秒计数器自增
						sotop_sec +=1;
						//停止秒满60进位总累计分钟
						if(sotop_sec > 59)
						{
							//停止秒清零
							sotop_sec = 0;
							//自动总计时+1分钟
							Auto_Total_Cnt = Auto_Total_Cnt + 1;
						}
						
						//总时长达标且允许切换,互换主风机
						if(Auto_Total_Cnt >= Auto_Total_Min && Auto_Switch_Enable)
						{
							//翻转主风机切换标记
							Day_Switch = !Day_Switch;
							//写入外部切换标签
							SetTagBit("Day_Switch",Day_Switch);
							//总累计计时清零重新开始
							Auto_Total_Cnt = 0;
						}
						//不在定时区间直接跳出自动模式逻辑
						break;
					}
				}
				//结束时间大于等于开始时间,当日区间(如8点~18点)
				else
				{
					//判断当前时间不在当日定时区间内
					if(!(C_HHMM >= Sk_startHM && C_HHMM < Sk_endHM))
					{
						//自动周期计时清零
						cycle_min = 0;
						cycle_sec = 0;
						//画面计时同步清零
						Min_Cnt = cycle_min;
						Sec_Cnt = cycle_sec;
						//写入外部计时标签
						SetTagDWord("Min_Cnt", Min_Cnt);
						SetTagDWord("Sec_Cnt", Sec_Cnt);
						//停止区间秒计数器自增
						sotop_sec +=1;
						//停止秒满60进位总累计分钟
						if(sotop_sec > 59)
						{
							sotop_sec = 0;
							Auto_Total_Cnt = Auto_Total_Cnt + 1;
						}
						//总时长达标且允许切换,互换主风机
						if(Auto_Total_Cnt >= Auto_Total_Min && Auto_Switch_Enable)
						{
							Day_Switch = !Day_Switch;
							SetTagBit("Day_Switch",Day_Switch);
							Auto_Total_Cnt = 0;
						}
						//不在定时区间跳出自动逻辑
						break;
					}
				}	
			}
			//处于定时区间,清空停止区间秒计数器
			sotop_sec = 0;

			//自动模式每秒+1秒计数
			cycle_sec = cycle_sec + 1;
			//满60秒进位分钟,总切换计时同步+1
			if(cycle_sec > 59)
			{
				//周期分钟+1
				cycle_min = cycle_min + 1;
				//周期秒清零
				cycle_sec = 0;
				//全局自动轮换总计时+1分钟
				Auto_Total_Cnt = Auto_Total_Cnt + 1;
			}

			//当切换关闭时 可以指定要运行的风机 开启时 自动切换风机 
			if(!Auto_Switch_Enable)
			{
    			// 检测Run_Fan_x发生变化,仅变化时执行一次
    			if(Run_Fan_x != last_Run_Fan_x)
    			{
        			//固定选择风机1
        			if(Run_Fan_x == 0)
        			{
            			Day_Switch = 0;
            			SetTagBit("Day_Switch", 0);
        			}
        			//固定选择风机2
        			else if(Run_Fan_x == 1)
        			{
            			Day_Switch = 1;
            			SetTagBit("Day_Switch", 1);
        			}
					//切换风机后重置周期计时
					cycle_min = 0;
					cycle_sec = 0;
					Auto_Total_Cnt=0;
        			//更新上次状态缓存,阻止重复执行
        			last_Run_Fan_x = Run_Fan_x;
   				}
			}

			//天数切换开关=0:风机1作为主循环风机运行
			if(Day_Switch == 0)
			{
				//自动模式首次进入初始化逻辑
				if(Auto_Init_Flag == 0)
				{
					//首次执行强制停止风机2
					SetTagBit("LCFJ2.Start_Button",0);
					SetTagBit("LCFJ2.Stop_Button",1);
					//静态分秒计时器清零
					cycle_min = 0;
					cycle_sec = 0;
					//初始化标记置1,避免重复初始化
					Auto_Init_Flag = 1;
					SetTagBit("Auto_Init_Flag",1);
					//风机1状态初始化为运行状态
					Fan_StatusA=0;
				}

				//故障切换逻辑:当前运行风机1且风机1故障
				if(RunFlag == 1 && bM1Fault == 1)
				{
					//切换运行标记为风机2
					RunFlag = 2;
					//周期计时全部清零
					cycle_min = 0;
					cycle_sec = 0;
					Auto_Total_Cnt = 0;
				}

				//风机状态0:运行阶段
				if(Fan_StatusA == 0)
				{
					//运行分钟达到设定时长
					if(cycle_min >= M1_Run_Min)
					{
						//切换为停机状态
						Fan_StatusA = 1;
						//周期计时清零重新累计停机时长
						cycle_sec = 0;
						cycle_min = 0;
					}
				}
				//风机状态1:停机阶段
				else
				{
					//停机时长到达设定停机分钟
					if(cycle_min >= M1_Stop_Min)
					{
						//切回运行状态
						Fan_StatusA = 0;
						//周期计时清零重新累计运行时长
						cycle_sec = 0;
						cycle_min = 0;
						//总时长达标且允许切换,互换主风机
						if(Auto_Total_Cnt >= Auto_Total_Min && Auto_Switch_Enable)
						{
							//切换为主风机2
							SetTagBit("Day_Switch",1);
							//全部计时清零
							cycle_min = 0;
							cycle_sec = 0;
							Auto_Total_Cnt = 0;
							//重置初始化标记,下次循环重新初始化
							Auto_Init_Flag = 0;
							SetTagBit("Auto_Init_Flag",0);
						}
					} 
				}

				//风机1运行阶段:cycle_min未到达设定运行分钟
				if(Fan_StatusA == 0)
				{
					//风机1启动输出打开,风机2强制停机
					SetTagBit("LCFJ1.Start_Button",1);
					SetTagBit("LCFJ1.Stop_Button",0);
					SetTagBit("LCFJ2.Start_Button",0);
					SetTagBit("LCFJ2.Stop_Button",1);
					//运行标记设为风机1
					RunFlag = 1;
				}
				//风机1停机阶段:运行结束,未走完运行+停机总时长
				if(Fan_StatusA == 1)
				{
					//两台风机全部停机
					SetTagBit("LCFJ1.Start_Button",0);
					SetTagBit("LCFJ1.Stop_Button",1);
					SetTagBit("LCFJ2.Start_Button",0);
					SetTagBit("LCFJ2.Stop_Button",1);
					//无风机运行标记
					RunFlag = 0;
				}
			}
			//天数切换开关=1:风机2作为主循环风机运行
			else
			{
				//自动模式首次进入初始化逻辑
				if(Auto_Init_Flag == 0)
				{
					//首次进入强制停止风机1
					SetTagBit("LCFJ1.Start_Button",0);
					SetTagBit("LCFJ1.Stop_Button",1);
					//周期计时清零
					cycle_min = 0;
					cycle_sec = 0;
					//初始化标记置1,防止重复初始化
					Auto_Init_Flag = 1;
					SetTagBit("Auto_Init_Flag",1);
					//风机2初始状态为运行
					Fan_StatusB = 0;
				}

				//故障切换逻辑:当前运行风机2且风机2故障
				if(RunFlag == 2 && bM2Fault == 1)
				{
					//切换运行标记为风机1
					RunFlag = 1;
					//全部周期计时清零
					cycle_min = 0;
					cycle_sec = 0;
					Auto_Total_Cnt = 0;
				}

				//风机2状态0:运行阶段
				if(Fan_StatusB == 0)
				{
					//运行时长到达设定分钟
					if(cycle_min >= M2_Run_Min)
					{
						//切换为停机状态
						Fan_StatusB = 1;
						//计时清零累计停机时长
						cycle_sec = 0;
						cycle_min = 0;
					}
				}
				//风机2状态1:停机阶段
				else
				{
					//停机时长到达设定值
					if(cycle_min >= M2_Stop_Min)
					{
						//切回运行状态
						Fan_StatusB = 0;
						//计时清零重新累计运行时长
						cycle_sec = 0;
						cycle_min = 0;
						//风机2完整一轮启停循环结束
						if(Auto_Total_Cnt >= Auto_Total_Min && Auto_Switch_Enable)
						{
							//切换主风机为风机1
							SetTagBit("Day_Switch",0);
							//全部计时清零
							cycle_min = 0;
							cycle_sec = 0;
							Auto_Total_Cnt = 0;
							//重置初始化标记
							Auto_Init_Flag = 0;
							SetTagBit("Auto_Init_Flag",0);
						}
					} 
				}

				//风机2运行阶段
				if(Fan_StatusB == 0)
				{
					//风机2启动,风机1停机
					SetTagBit("LCFJ2.Start_Button",1);
					SetTagBit("LCFJ2.Stop_Button",0);
					SetTagBit("LCFJ1.Start_Button",0);
					SetTagBit("LCFJ1.Stop_Button",1);
					//运行标记风机2
					RunFlag = 2;
				}
				//风机2停机阶段
				if(Fan_StatusB == 1)
				{
					//两台风机全部停机
					SetTagBit("LCFJ2.Start_Button",0);
					SetTagBit("LCFJ2.Stop_Button",1);
					SetTagBit("LCFJ1.Start_Button",0);
					SetTagBit("LCFJ1.Stop_Button",1);
					//无风机运行标记
					RunFlag = 0;
				}
			}
			//将静态分秒计时赋值给全局显示变量Min_Cnt、Sec_Cnt
			Min_Cnt = cycle_min;
			Sec_Cnt = cycle_sec;
			//退出自动模式分支
			break;
		}
		case 4://时控模式
		{
			//清空自动模式废弃周期计时器
			SetTagDWord("Auto_Cnt",0);
			//内存自动总计时清零
			Auto_Total_Cnt=0;
			//写入外部自动总计时清零
			SetTagDWord("Auto_Total_Cnt",Auto_Total_Cnt);

			//每次进入时控模式重新初始化定时有效标记
			bTimerValid = 0;
			//判断定时结束时间小于开始时间=跨天定时区间
			if(Sk_endHM <  Sk_startHM)
			{
    			// 跨天区间:当前时间 >= 开始时间  OR 当前时间 < 结束时间
    			if(C_HHMM >= Sk_startHM || C_HHMM < Sk_endHM)
    			{
        			bTimerValid = 1; // 区间内,触发切换标记
    			}
			}
			//当日定时区间(结束时间大于等于开始时间)
			else
			{
    			// 当天区间:开始 ≤ 当前 ≤ 结束
    			if(C_HHMM >= Sk_startHM && C_HHMM < Sk_endHM)
    			{
        			bTimerValid = 1; // 区间内,触发切换标记
    			}
			}

			//进入时控轮换,复位手动风机1按钮锁存
			SetTagBit("Manual_M1_Start",0);
			//进入时控轮换,复位手动风机2按钮锁存
			SetTagBit("Manual_M2_Start",0);

			//当前时间不在定时区间内,定时失效
			if(bTimerValid  == 0)
			{
    			//风机1启动输出关闭
    			SetTagBit("LCFJ1.Start_Button", 0);
    			//风机1停止输出打开
    			SetTagBit("LCFJ1.Stop_Button", 1);
    			//风机2启动输出关闭
    			SetTagBit("LCFJ2.Start_Button", 0);
    			//风机2停止输出打开
    			SetTagBit("LCFJ2.Stop_Button", 1);
    			//运行标记清零
    			SetTagDWord("Run_Motor_Flag", 0);
    			//时控单次触发标记复位
    			TimerSwitchBitp = 0;
    			//本地运行标记清零
    			RunFlag = 0;
    			//定时失效,退出case4分支
    			break;
			}

			//当切换关闭时 可以指定要运行的风机 开启时 自动切换风机 
			if(!Auto_Switch_Enable)//手动固定风机模式
			{
    			// 检测Run_Fan_x发生变化 或 首次进入区间,仅执行一次
    			if(Run_Fan_x != last_Run_Fan_x || TimerSwitchBitp == 0 )
    			{
					//标记本次区间已完成风机选择,不再重复执行
					TimerSwitchBitp = 1;
        			//固定风机1运行
        			if(Run_Fan_x == 0)
        			{
            			RunFlag = 1;	
        			}
        			//固定风机2运行
        			else if(Run_Fan_x == 1)
        			{
            			RunFlag = 2;
        			}
        			// 更新上次状态缓存,阻止重复执行
					Min_Cnt = 0;
    				Sec_Cnt = 0;
        			last_Run_Fan_x = Run_Fan_x;
   				}
			}

			//自动轮换模式,首次进入定时区间切换风机
			if(TimerSwitchBitp == 0 && Auto_Switch_Enable)
			{
					//标记区间已初始化风机选择
					TimerSwitchBitp = 1;
    				//翻转风机切换静态标记
    				TimerSwitchBit = !TimerSwitchBit;
    				// 仅首次进入区间清零计时
    				Min_Cnt = 0;
    				Sec_Cnt = 0;
    				//根据翻转标记选择运行风机
    				if(TimerSwitchBit == 0)  RunFlag = 1;
    				else RunFlag = 2;	
			}

			//----------------------时控运行中风机故障自动切换----------------------
			//当前运行风机1故障
			if(RunFlag == 1 && bM1Fault == 1)
			{
				//切换风机2运行
				RunFlag = 2;
				//故障切换计时清零
				Min_Cnt = 0;
				Sec_Cnt = 0;
			}
			//当前运行风机2故障
			if(RunFlag == 2 && bM2Fault == 1)
			{
				//切换风机1运行
				RunFlag = 1;
				//故障切换计时清零
				Min_Cnt = 0;
				Sec_Cnt = 0;
			}
			
			//----------------------时控互斥输出风机启停信号----------------------
			//标记风机1运行
			if(RunFlag == 1)
			{
				//风机1启动打开
				SetTagBit("LCFJ1.Start_Button", 1);
				//风机1停止关闭
				SetTagBit("LCFJ1.Stop_Button", 0);
				//风机2启动关闭
				SetTagBit("LCFJ2.Start_Button", 0);
				//风机2停止打开
				SetTagBit("LCFJ2.Stop_Button", 1);
				//全局运行秒计数器+1,脚本周期1秒触发一次
				Sec_Cnt = Sec_Cnt + 1;
				//秒计数达到60秒,执行进位分钟逻辑
				if(Sec_Cnt >= 60)
				{
					//秒计数器归零
					Sec_Cnt = 0;
					//全局分钟计数器+1
					Min_Cnt = Min_Cnt + 1;
				}
			}
			//标记风机2运行
			if(RunFlag == 2)
			{
				//风机1启动关闭
				SetTagBit("LCFJ1.Start_Button", 0);
				//风机1停止打开
				SetTagBit("LCFJ1.Stop_Button", 1);
				//风机2启动打开
				SetTagBit("LCFJ2.Start_Button", 1);
				//风机2停止关闭
				SetTagBit("LCFJ2.Stop_Button", 0);
				//全局运行秒计数器+1,脚本周期1秒触发一次
				Sec_Cnt = Sec_Cnt + 1;
				//秒计数达到60秒,执行进位分钟逻辑
				if(Sec_Cnt >= 60)
				{
					//秒计数器归零
					Sec_Cnt = 0;
					//全局分钟计数器+1
					Min_Cnt = Min_Cnt + 1;
				}
			}
		}
	}

	//==================== 回写更新所有计时、运行标记外部变量 ====================
	//回写全局分钟计时画面标签
	SetTagDWord("Min_Cnt", Min_Cnt);
	//回写全局秒计时画面标签
	SetTagDWord("Sec_Cnt", Sec_Cnt);
	//回写当前运行风机标记外部标签
	SetTagDWord("Run_Motor_Flag", RunFlag);
	//回写废弃自动周期计时器
	SetTagDWord("Auto_Cnt", Auto_Cnt);
	//回写自动轮换总累计计时器
	SetTagDWord("Auto_Total_Cnt", Auto_Total_Cnt);
	
	//回写风机1运行时长参数标签
	SetTagDWord("M1_Run_Min", M1_Run_Min);
	//回写风机1停机时长参数标签
	SetTagDWord("M1_Stop_Min", M1_Stop_Min);
	//回写风机2运行时长参数标签
	SetTagDWord("M2_Run_Min", M2_Run_Min);
	//回写风机2停机时长参数标签
	SetTagDWord("M2_Stop_Min", M2_Stop_Min);
	//回写自动轮换总切换阈值参数标签
	SetTagDWord("Auto_Total_Min", Auto_Total_Min);

	//全局动作正常执行完毕,返回0标准结束值
	return 0;
}

 

posted @ 2026-07-09 16:13  MaopaiJD  阅读(14)  评论(0)    收藏  举报