MaopaiJD_Winccpp

#include "apdefap.h"

int gscAction( void )
{

  	
	//==================== 【公共临时局部变量定义区】====================
	//系统时间相关变量,用于获取本地时分秒、换算当日总分钟做定时判断
	struct tm* pLocalTime;  //系统时间结构体指针,存放解析后的时/分/秒/日/月/年
	time_t lTime;           //时间戳变量,存储从1970至今的秒数原始时间
	int CurHour;            //提取当前系统小时,范围0~23
	int CurMin;             //提取当前系统分钟,范围0~59
	int CurSec;             //提取当前系统秒,仅用于计时累加,定时判断不使用
	int CurTotalMin;        //当日总分钟 = 小时*60+分钟,统一换算后简化定时区间对比逻辑
	
	//模式控制、计时相关变量
	unsigned long AltEn;        //整机模式总开关变量,DWord类型:0关闭/1手动/2时长轮换/4时控轮换
	unsigned long SetMin;       //模式2专用:单台风机设定运行时长,单位分钟
	unsigned long Min_Cnt;      //全局运行累计分钟计时器,所有运行模式共用
	unsigned long Sec_Cnt;      //全局运行累计秒计时器,所有运行模式共用
	unsigned long RunFlag;      //当前运行风机标记:0无风机运行/1风机1运行/2风机2运行
	unsigned long C_HHMM;
	unsigned long C_StartHHMM,C_SotopHHMM;
	
	
	static BOOL TimerSwitchBit;        //模式4专用切换位BOOL变量,0启动风机1,1启动风机2,定时有效边沿自动取反
	static BOOL TimerSwitchBitp;        //模式4专用切换位BOOL变量,0启动风机1,1启动风机2,定时有效边沿自动取反
	BOOL bAnyMotorRun;          //公共判断标记:任意一台风机输出启动信号则置1,用于统一计时逻辑
	
	//PLC侧风机硬件状态反馈点位
	BOOL bM1Remote;    //风机1远程自动模式反馈,等于3代表切本地手动,需整机停机保护
	BOOL bM1Fault;     //风机1故障报警信号,1=故障,0=正常
	BOOL bM2Remote;    //风机2远程自动模式反馈,等于3代表切本地手动,需整机停机保护
	BOOL bM2Fault;     //风机2故障报警信号,1=故障,0=正常
	
	//画面手动操作按钮变量,模式1手动模式使用
	BOOL bManualM1Start;    //画面手动启动风机1按钮,1=按下启动,0=松开停止
	BOOL bManualM2Start;    //画面手动启动风机2按钮,1=按下启动,0=松开停止
	
	//模式4时控专用标记
	BOOL bTimerValid = 0;   //定时总有效标记,初始0;M1任意一组启用定时在当前时间区间内置1
	int i;                  //定时循环遍历索引,循环0~19,遍历20组定时参数
	
	//==================== 【第一步:统一读取系统本地时间】====================
	lTime = time(NULL);                 //获取当前系统时间戳,返回秒数存入lTime
	pLocalTime = localtime(&lTime);     //将时间戳转换为本地时区可读时间结构体
	CurHour = pLocalTime->tm_hour;      //从结构体取出当前小时赋值给CurHour
	CurMin  = pLocalTime->tm_min;       //从结构体取出当前分钟赋值给CurMin
	CurSec  = pLocalTime->tm_sec;       //从结构体取出当前秒赋值给CurSec
	CurTotalMin = CurHour * 60 + CurMin;//换算当前时间为当日总分钟,用于定时区间对比
	C_HHMM = CurHour*100 + CurMin ;
	
	//==================== 【第二步:一次性读取全部外部标签变量】====================
	AltEn = GetTagDWord("Alt_Enable");              //读取整机模式总开关DWord变量
	SetMin = GetTagDWord("Run_Time_Min");           //读取模式2单台风机设定运行分钟
	Min_Cnt = GetTagDWord("Min_Cnt");               //读取全局累计分钟计时器当前值
	Sec_Cnt = GetTagDWord("Sec_Cnt");               //读取全局累计秒计时器当前值
	RunFlag = GetTagDWord("Run_Motor_Flag");        //读取当前运行风机标记
	//TimerSwitchBit = GetTagBit("Timer_Switch_Cnt"); //读取模式4风机切换BOOL位
	
	bManualM1Start = GetTagBit("Manual_M1_Start");  //读取画面手动风机1启动按钮状态
	bManualM2Start = GetTagBit("Manual_M2_Start");  //读取画面手动风机2启动按钮状态
	
	bM1Remote = GetTagBit("LCFJ1.Remote");          //读取风机1远程/本地模式反馈
	bM1Fault = GetTagBit("LCFJ1.Fault");            //读取风机1故障信号
	bM2Remote = GetTagBit("LCFJ2.Remote");          //读取风机2远程/本地模式反馈
	bM2Fault = GetTagBit("LCFJ2.Fault");            //读取风机2故障信号
	
	C_StartHHMM = GetTagDWord("Sk_StartHm");        //读取当前运行风机标记
	C_SotopHHMM = GetTagDWord("Sk_SotopHm");        //读取当前运行风机标记
	
	//==================== 【最高优先级保护逻辑1:两台风机同时故障,整机强制停机清零】====================
	if(bM1Fault == 1 && bM2Fault == 1)  //判断风机1、风机2同时存在故障报警
	{
		SetTagBit("LCFJ1.Start_Button", 0); //输出风机1启动信号置0,停止风机1
		SetTagBit("LCFJ1.Stop_Button", 1);  //输出风机1停止信号置1,强制停机
		SetTagBit("LCFJ2.Start_Button", 0); //输出风机2启动信号置0,停止风机2
		SetTagBit("LCFJ2.Stop_Button", 1);  //输出风机2停止信号置1,强制停机
		
		SetTagDWord("Min_Cnt", 0);          //运行分钟计时器清零
		SetTagDWord("Sec_Cnt", 0);          //运行秒计时器清零
		SetTagDWord("Run_Motor_Flag", 0);   //运行风机标记置0,无风机运行
		SetTagBit("Timer_Switch_Cnt", 0);   //模式4风机切换位复位初始0
		//SetTagDWord("Alt_Enable", 0); // 
		return 0;   //保护触发,直接结束本次动作循环,不再执行后续逻辑
	}
	
	//==================== 【最高优先级保护逻辑2:任意风机切本地非远程模式,整机停机清零】====================
	if(bM1Remote == 0 ||  bM2Remote == 0)    //风机1或风机2本地模式反馈等于3,退出自动控制
	{
		SetTagBit("LCFJ1.Start_Button", 0); //风机1启动输出关闭
		SetTagBit("LCFJ1.Stop_Button", 1);  //风机1停止输出打开
		SetTagBit("LCFJ2.Start_Button", 0); //风机2启动输出关闭
		SetTagBit("LCFJ2.Stop_Button", 1);  //风机2停止输出打开
		
		SetTagDWord("Min_Cnt", 0);          //分钟计时清零
		SetTagDWord("Sec_Cnt", 0);          //秒计时清零
		SetTagDWord("Run_Motor_Flag", 0);   //运行标记清零
		SetTagBit("Timer_Switch_Cnt", 0);   //时控切换位复位
		
		
		return 0;   //保护触发,直接退出本次循环
	}
	
	//==================== 【模式4专用:遍历20组定时,判断当前时间是否在定时区间内】====================
	bTimerValid = 0;    //定时有效标记先初始化为0,默认定时未激活
	for(i = 0; i < 1; i++)    //循环i从0到19,遍历全部20组M1定时参数
	{
		char szEn[30];      //字符缓冲区,拼接每组定时启用变量名,长度30足够存储
		char szStart[30];   //字符缓冲区,拼接每组定时启动时间变量名
		char szStop[30];    //字符缓冲区,拼接每组定时停止时间变量名
		int En;             //本组定时启用状态:1启用,0禁用
		int StartHHMM;      //本组启动时间合并数字,格式HHMM,例0830=8点30分
		int StopHHMM;       //本组停止时间合并数字,格式HHMM,例2300=23点整
		int S_H, S_M;       //拆分后启动小时、启动分钟
		int E_H, E_M;       //拆分后停止小时、停止分钟
		int StartMin;       //本组启动时间换算当日总分钟
		int EndMin;         //本组停止时间换算当日总分钟
		
		sprintf(szEn, "M1_En%d", i);            //拼接变量名:M1_En0、M1_En1...M1_En19
		sprintf(szStart, "M1_Start_T%d", i);    //拼接变量名:M1_Start_T0~M1_Start_T19
		sprintf(szStop, "M1_Stop_T%d", i);      //拼接变量名:M1_Stop_T0~M1_Stop_T19
		
		// En = GetTagDWord(szEn);                 //读取当前组定时启用状态
		En = 1;                 //读取当前组定时启用状态
		if(En != 1) continue;                  //本组定时未启用,跳过本组,判断下一组定时
		
		// StartHHMM = GetTagDWord(szStart);       //读取本组启动HHMM时间数值
		// StopHHMM = GetTagDWord(szStop);         //读取本组停止HHMM时间数值
		
		StartHHMM = C_StartHHMM;       //读取本组启动HHMM时间数值
		StopHHMM   =  C_SotopHHMM;         //读取本组停止HHMM时间数值
		
		
		
		S_H = StartHHMM / 100;                  //整除100拆分出启动小时
		S_M = StartHHMM % 100;                  //对100取余拆分出启动分钟
		E_H = StopHHMM / 100;                   //整除100拆分出停止小时
		E_M = StopHHMM % 100;                   //对100取余拆分出停止分钟
		
		StartMin = S_H * 60 + S_M;              //启动时间换算当日总分钟
		EndMin = E_H * 60 + E_M;                //停止时间换算当日总分钟
		
		if(StartMin <= EndMin)                  //定时区间不跨零点,如0800~1800,当天内区间
		{
			if(CurTotalMin >= StartMin && CurTotalMin < EndMin) //当前时间落在定时区间内
			{
				bTimerValid = 1;    //置定时总有效标记为1
				break;              //找到有效定时组,跳出循环无需判断剩余定时
				
			}
		}
		else                                    //定时跨零点场景,如2330~0120,跨次日凌晨
		{
			if(CurTotalMin >= StartMin || CurTotalMin < EndMin) //当前时间在跨天区间内
			{
				bTimerValid = 1;    //置定时总有效标记为1
				break;              //找到有效定时,直接跳出循环
				
			}
		}
		
	}
	
	//==================== 【模式分支选择器:根据AltEn切换对应控制逻辑】====================
	switch(AltEn)  //依据整机模式开关值,进入对应功能分支
	{
		//==================== Case0:模式0,整机关闭,全部风机停机、所有标记清零 ====================
	case 1:
	{
		SetTagBit("LCFJ1.Start_Button", 0); //风机1启动输出关闭
		SetTagBit("LCFJ1.Stop_Button", 1);  //风机1停止输出打开
		SetTagBit("LCFJ2.Start_Button", 0); //风机2启动输出关闭
		SetTagBit("LCFJ2.Stop_Button", 1);  //风机2停止输出打开
		
		SetTagDWord("Min_Cnt", 0);          //运行分钟计时清零
		SetTagDWord("Sec_Cnt", 0);          //运行秒计时清零
		SetTagDWord("Run_Motor_Flag", 0);   //运行风机标记清零
		// SetTagBit("Timer_Switch_Cnt", 0);   //时控模式切换位复位0
		RunFlag = 0;
		TimerSwitchBitp=0;
		
		SetTagBit("Manual_M1_Start",0);    //切换至手动模式,复位风机1手动启动按钮锁存
		SetTagBit("Manual_M2_Start",0);    //切换至手动模式,复位风机2手动启动按钮锁存
		break;  //退出case0分支,执行后续统一计时逻辑
	}
		
		//==================== Case1:模式1,手动模式,画面按钮独立控制两台风机 ====================
	case 2:
		{
			//SetTagBit("Manual_M1_Start",0);    //切换至手动模式,复位风机1手动启动按钮锁存
			//SetTagBit("Manual_M2_Start",0);    //切换至手动模式,复位风机2手动启动按钮锁存
			SetTagBit("Timer_Switch_Cnt", 0);  //切换手动,复位时控专用切换位
			TimerSwitchBitp=0;
			//----------------------风机1手动启停控制逻辑----------------------
			if(bManualM1Start == 1)    //画面手动启动风机1按钮按下
			{
				SetTagBit("LCFJ1.Start_Button", 1); //风机1启动输出置1,启动风机
				SetTagBit("LCFJ1.Stop_Button", 0);  //风机1停止输出置0,解除停机指令
				if(RunFlag != 1)    //当前运行标记不是风机1,代表刚切换启动风机1
				{
					Min_Cnt = 0;    //切换风机时计时清零
					Sec_Cnt = 0;
					RunFlag = 1;    //更新运行标记为风机1
				}
			}
			else    //手动按钮松开,停止风机1
			{
				SetTagBit("LCFJ1.Start_Button", 0); //关闭风机1启动输出
				SetTagBit("LCFJ1.Stop_Button", 1);  //打开风机1停止输出
			}
			
			//----------------------风机2手动启停控制逻辑----------------------
			if(bManualM2Start == 1)    //画面手动启动风机2按钮按下
			{
				SetTagBit("LCFJ2.Start_Button", 1); //风机2启动输出置1,启动风机
				SetTagBit("LCFJ2.Stop_Button", 0);  //风机2停止输出置0,解除停机指令
				if(RunFlag != 2)    //当前运行标记不是风机2,刚切换启动风机2
				{
					Min_Cnt = 0;    //切换风机计时清零
					Sec_Cnt = 0;
					RunFlag = 2;    //更新运行标记为风机2
				}
			}
			else    //手动按钮松开,停止风机2
			{
				SetTagBit("LCFJ2.Start_Button", 0); //关闭风机2启动输出
				SetTagBit("LCFJ2.Stop_Button", 1);  //打开风机2停止输出
			}
			
			
			
			if((bManualM2Start == 0) && (bManualM1Start == 0))
			{
				
				RunFlag = 0; 
				Min_Cnt = 0;    //切换风机计时清零
				Sec_Cnt = 0;
			}
			break;  //退出case1手动分支,执行统一计时逻辑
		}
		
		//==================== Case2:模式2,时长自动轮换模式,两台风机互斥定时切换 ====================
	case 3:
		{
			SetTagBit("Manual_M1_Start",0);    //进入轮换模式,复位手动风机1按钮
			SetTagBit("Manual_M2_Start",0);    //进入轮换模式,复位手动风机2按钮
			SetTagBit("Timer_Switch_Cnt", 0);  //切换轮换模式,复位时控切换位
			TimerSwitchBitp=0;
			if (RunFlag == 0)  //无风机运行,初始化默认启动风机2
			{
				RunFlag = 2;    //运行标记设为风机2
				Min_Cnt = 0;    //计时清零
				Sec_Cnt = 0;
			}
			
			//----------------------风机运行故障自动切换逻辑----------------------
			if(RunFlag == 1 && bM1Fault == 1)  //当前运行风机1且风机1故障
			{
				RunFlag = 2;    //切换运行风机2
				Min_Cnt = 0;    //切换风机计时清零
				Sec_Cnt = 0;
			}
			if(RunFlag == 2 && bM2Fault == 1)  //当前运行风机2且风机2故障
			{
				RunFlag = 1;    //切换运行风机1
				Min_Cnt = 0;    //切换风机计时清零
				Sec_Cnt = 0;
			}
			
			//----------------------互斥输出风机启停信号 + 时长到达切换逻辑----------------------
			if(RunFlag == 1)  //标记为风机1运行
			{
				SetTagBit("LCFJ1.Start_Button", 1); //风机1启动输出打开
				SetTagBit("LCFJ1.Stop_Button", 0);  //风机1停止输出关闭
				SetTagBit("LCFJ2.Start_Button", 0); //风机2启动输出关闭
				SetTagBit("LCFJ2.Stop_Button", 1);  //风机2停止输出打开
				if(Min_Cnt >= SetMin)  //累计运行分钟达到设定轮换时长
				{
					RunFlag = 2;    //切换运行风机2
					Min_Cnt = 0;    //新风机启动计时清零
					Sec_Cnt = 0;
				}
			}
			else if(RunFlag == 2)  //标记为风机2运行
			{
				SetTagBit("LCFJ1.Start_Button", 0); //风机1启动输出关闭
				SetTagBit("LCFJ1.Stop_Button", 1);  //风机1停止输出打开
				SetTagBit("LCFJ2.Start_Button", 1); //风机2启动输出打开
				SetTagBit("LCFJ2.Stop_Button", 0);  //风机2停止输出关闭
				if(Min_Cnt >= SetMin)  //累计运行分钟达到设定轮换时长
				{
					RunFlag = 1;    //切换运行风机1
					Min_Cnt = 0;    //新风机启动计时清零
					Sec_Cnt = 0;
				}
			}
			break;  //退出case2轮换分支,执行统一计时逻辑
		}
		
		//==================== Case4:模式4,时控轮换模式,定时有效交替运行风机1/2 ====================
	case 4:
		{
			SetTagBit("Manual_M1_Start",0);    //进入时控轮换,复位手动风机1按钮
			SetTagBit("Manual_M2_Start",0);    //进入时控轮换,复位手动风机2按钮
			
			if(bTimerValid == 0)  //当前时间不在定时区间内,定时失效
			{
				SetTagBit("LCFJ1.Start_Button", 0); //风机1启动输出关闭
				SetTagBit("LCFJ1.Stop_Button", 1);  //风机1停止输出打开
				SetTagBit("LCFJ2.Start_Button", 0); //风机2启动输出关闭
				SetTagBit("LCFJ2.Stop_Button", 1);  //风机2停止输出打开
				SetTagDWord("Run_Motor_Flag", 0);   //运行标记清零
				TimerSwitchBitp =0;
				RunFlag = 0;
				break;  //定时失效,退出case4分支,执行计时逻辑
			}
			
			//if(RunFlag == 0)  //定时刚从失效变为有效,首次触发,切换风机顺序
			//{
			//	TimerSwitchBit = !TimerSwitchBit;   //BOOL切换位取反,0变1、1变0
			//	SetTagBit("Timer_Switch_Cnt", TimerSwitchBit); //回写切换位变量
			////	Min_Cnt = 0;    //定时重新触发,计时清零
			//	Sec_Cnt = 0;
			//	if(TimerSwitchBit == 0) //切换位为0,本次启动风机1
			//		RunFlag = 1;
			//	else                    //切换位为1,本次启动风机2
			//		RunFlag = 2;
			//}
			
			
			if(TimerSwitchBitp == 0)
			{
				TimerSwitchBitp =1;
				TimerSwitchBit=!TimerSwitchBit;
				//SetTagBit("Timer_Switch_Cnt", TimerSwitchBit); //回写切换位变量
				Min_Cnt = 0;    //定时重新触发,计时清零
				Sec_Cnt = 0;
				if(TimerSwitchBit == 0) //切换位为0,本次启动风机1
					RunFlag = 1;
				else                    //切换位为1,本次启动风机2
					RunFlag = 2;
				
			}
			
			
			
			
			
			
			
			
			
			
			//----------------------时控运行中风机故障自动切换----------------------
			if(RunFlag == 1 && bM1Fault == 1)  //当前运行风机1故障
			{
				RunFlag = 2;    //切换风机2运行
				Min_Cnt = 0;    //故障切换计时清零
				Sec_Cnt = 0;
			}
			if(RunFlag == 2 && bM2Fault == 1)  //当前运行风机2故障
			{
				RunFlag = 1;    //切换风机1运行
				Min_Cnt = 0;    //故障切换计时清零
				Sec_Cnt = 0;
			}
			
			//----------------------时控互斥输出风机启停信号----------------------
			if(RunFlag == 1)  //标记风机1运行
			{
				SetTagBit("LCFJ1.Start_Button", 1); //风机1启动打开
				SetTagBit("LCFJ1.Stop_Button", 0);  //风机1停止关闭
				SetTagBit("LCFJ2.Start_Button", 0); //风机2启动关闭
				SetTagBit("LCFJ2.Stop_Button", 1);  //风机2停止打开
			}
			else if(RunFlag == 2)  //标记风机2运行
			{
				SetTagBit("LCFJ1.Start_Button", 0); //风机1启动关闭
				SetTagBit("LCFJ1.Stop_Button", 1);  //风机1停止打开
				SetTagBit("LCFJ2.Start_Button", 1); //风机2启动打开
				SetTagBit("LCFJ2.Stop_Button", 0);  //风机2停止关闭
			}
			break;  //退出case4时控分支,执行统一计时逻辑
		}
		
	}
	
	//==================== 【全模式统一计时逻辑:任意风机运行则累加时分,无运行清零】====================
	// bAnyMotorRun = (GetTagBit("LCFJ1.Start_Button") || GetTagBit("LCFJ2.Start_Button"));
	bAnyMotorRun = RunFlag;
	//读取最终输出启动点位,两台任意一台输出1,标记bAnyMotorRun置1
	if(bAnyMotorRun > 0)  //存在风机正在运行
	{
		Sec_Cnt = Sec_Cnt + 1; //运行秒计数器+1,每秒动作触发一次则秒+1
		if(Sec_Cnt >= 60)     //秒计数达到60秒,进位分钟
		{
			Sec_Cnt = 0;      //秒计数器归零
			Min_Cnt = Min_Cnt + 1; //分钟计数器+1
		}
	}
	else  //无任何风机输出运行信号
	{
		Min_Cnt = 0;  //分钟计时清零
		Sec_Cnt = 0;  //秒计时清零
		RunFlag = 0;  //运行风机标记清零,代表无风机运行
	}
	
	//==================== 回写更新所有计时、运行标记外部变量 ====================
	SetTagDWord("Min_Cnt", Min_Cnt);        //回写累计分钟计时器
	SetTagDWord("Sec_Cnt", Sec_Cnt);        //回写累计秒计时器
	SetTagDWord("Run_Motor_Flag", RunFlag);  //回写当前运行风机标记
	SetTagDWord("SyHHMM", C_HHMM);  //回写当前运行风机标记
	
	return 0;   //全局动作正常执行完毕,返回0标准结束值
	
}

 

posted @ 2026-06-29 15:29  MaopaiJD  阅读(12)  评论(0)    收藏  举报