⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 turncontrol.c

📁 一个流量控制仪器的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
        	//根据  ucTurnType		切换的方式  判断是否暂停返回
        	
        if ( (ucTurnType != 2) & (ucTurnType != 3))
        {
        	//暂停切换  或  正常切换
        	//保存上时段的运行数据
        	
        	//1.	保存上时段的时间量
		uc5_SystemTurnTimeSaved[0] = uc5_TurnTime[0];
		uc5_SystemTurnTimeSaved[1] = uc5_TurnTime[1];
		uc5_SystemTurnTimeSaved[2] = uc5_TurnTime[2];
		uc5_SystemTurnTimeSaved[3] = uc5_TurnTime[3]; 
		uc5_SystemTurnTimeSaved[4] = uc5_TurnTime[4];
		
		//2.	保存上时段的控制量。
		uc2_SystemTurnConSaved[0] = uc2_SystemTurnCon[0];
		uc2_SystemTurnConSaved[1] = uc2_SystemTurnCon[1];
		
		//3.	保存上时段的时段量。
		ucSystemTurnNumSaved = ucSystemTurnNum;
        }
        
		//掉电复位,控制量已经读入了,不能清除!
		if(ucTurnType != 3)
		{
			//公共关闭流程
			uc2_SystemTurnCon[0] = 0;
			uc2_SystemTurnCon[1] = 0;

			fnCONoutput();
		}
        
                //上一个时段的自有关闭流程
                //!!注意:如果是暂停切换,ucTurnType=1;则不调用上时段的End函数。
        if(ucTurnType != 1)
        {                
        	pfnFunc = TurnList[ucSystemTurnNum].pfnEnd_TurnN;
        	if(pfnFunc != NULL)
                	(*pfnFunc)();				//执行操作
        }
                
                //d)	时段工作状态LED1-5,清除不显示。
        for(i=1;i++;i<6)
        	fnSet_DisplayLED(i,0,1);        //设置第i位LED不显示不闪烁 1-5


        //---------时段切换---------//
        
        //根据  ucTurnType		切换的方式  判断是否暂停返回
        if(ucTurnType == 2)
        {
        	//暂停返回
        	ucSystemTurnNum = ucSystemTurnNumSaved;
        }
        else
        {
        	//正常切换/暂停切换
        	
        	ucSystemTurnNum = ucTurnNum;
        }


        //---------下时段开始流程---------//
        
        
        
        //公共开始流程
        
        //i.	系统设置刷新
        
        	//1.	读入系统设置BUF函数:    
        fnRead_SystemSetToBuf();
        
        
        	//2.	外部4路输入检测量设置BUF数据刷新。
        fnReadBuf_SystemInputFlagPermitData();
        
	//根据  ucTurnType		切换的方式  判断是否暂停返回
    if(ucTurnType == 2)
    {
        	//暂停返回
        	
        	
        	//读入暂存的时间量
		uc5_TurnTime[0] = uc5_SystemTurnTimeSaved[0];
		uc5_TurnTime[1] = uc5_SystemTurnTimeSaved[1];
		uc5_TurnTime[2] = uc5_SystemTurnTimeSaved[2];
		uc5_TurnTime[3] = uc5_SystemTurnTimeSaved[3];
		uc5_TurnTime[4] = uc5_SystemTurnTimeSaved[4];
		
        	//读入暂存的控制量		
        	uc2_SystemTurnCon[0] = uc2_SystemTurnConSaved[0];
        	uc2_SystemTurnCon[1] = uc2_SystemTurnConSaved[1];
        	
        	//计时顺序
		bTurnTimeSortState = TurnList[ucSystemTurnNum].ucTurnTimeSortState &0x01;
		
                //下一个时段的自有初始化流程
                //注意:如果是暂停返回,ucTurnType=2;则不调用下时段的Init函数。
        	//pfnFunc = TurnList[ucSystemTurnNum].pfnInit_TurnN;
        	//if(pfnFunc != NULL)
                //	(*pfnFunc)();				//执行操作		
		
                //时段运行开始
		bSystemTurnRunEnable = 1;
	
		//ii.	根据时段工作状态ucTurnState,LED1-5显示。
		if(TurnList[ucSystemTurnNum].ucTurnState<5)
			fnSet_DisplayLED(TurnList[ucSystemTurnNum].ucTurnState+1,1,1);        //设置第i位LED显示不闪烁 1-5		
	}
	else
	if(ucTurnType == 3)
    {
		//调电复位


		//跳过时间载入

		//跳过控制量载入


        //计时顺序设置
		bTurnTimeSortState = TurnList[ucSystemTurnNum].ucTurnTimeSortState &0x01;

        //下一个时段的自有初始化流程
        pfnFunc = TurnList[ucSystemTurnNum].pfnInit_TurnN;
        if(pfnFunc != NULL)
               	(*pfnFunc)();				//执行操作

		//ii.	根据时段工作状态ucTurnState,LED1-5显示。
		if(TurnList[ucSystemTurnNum].ucTurnState<5)
			fnSet_DisplayLED(TurnList[ucSystemTurnNum].ucTurnState+1,1,1);        //设置第i位LED显示不闪烁 1-5		

        //时段运行开始
		bSystemTurnRunEnable = 1;

	}
	else
	if( (ucTurnType == 1) | (ucTurnType == 0))
	{
		
        	//正常切换/暂停切换


            //读入指定地址,大小的时段时间量:	
            //CAT24WC64P  (N<=8192)(地址:0-8191)
            //CAT24WC16P  (N<=2048)(地址:0-2047)
        	fnRead_Eeprom(TurnList[ucSystemTurnNum].uiTurnTimeAddress,
                        4,uc4_SystemTurnTime); 
                        
        	//检查数据,如果有问题,则全部设为0,并储存。报警,Beep
		if ( (uc4_SystemTurnTime[0] > 9) |		//百小时>9
			(uc4_SystemTurnTime[1] > 99) |		//小时>99
			(uc4_SystemTurnTime[2] > 59) |		//分钟>59
			(uc4_SystemTurnTime[3] > 59) )		//秒>59
		{
			//全部设为0
			uc4_SystemTurnTime[0] = 0;
			uc4_SystemTurnTime[1] = 0;
			uc4_SystemTurnTime[2] = 0;
			uc4_SystemTurnTime[3] = 0;
				
			//并储存
			//写入相应地址的数据--4字节的时间量
			//写入指定地址,4字节大小的数据:	
         	      	//CAT24WC64P  (N<=8192)(地址:0-8191)
         	       //CAT24WC16P  (N<=2048)(地址:0-2047)
        		fnWrite_Eeprom(TurnList[ucSystemTurnNum].uiTurnTimeAddress,
                   	     4,uc4_SystemTurnTime); 
                        		
                	//报警,Beep!
                        	
        	}
        	
        	//如果为正计时,则初始时间预设为0   
        	if( TurnList[ucSystemTurnNum].ucTurnTimeSortState )  
        	{
				//全部设为0
				uc4_SystemTurnTime[0] = 0;
				uc4_SystemTurnTime[1] = 0;
				uc4_SystemTurnTime[2] = 0;
				uc4_SystemTurnTime[3] = 0;
			}
        
        	//判断是否当前时间段时间为0且为倒计时
       		if( (uc4_SystemTurnTime[0] == 0) & (uc4_SystemTurnTime[1] == 0) &
        		(uc4_SystemTurnTime[2] == 0) & (uc4_SystemTurnTime[3] == 0) &
        		TurnList[ucSystemTurnNum].ucTurnTimeSortState == 0)
        	{
        		//控制量无效,为0。!!继承位也同时设为无效!!
        		uc2_SystemTurnCon[0] = 0;
        		uc2_SystemTurnCon[1] = 0;
        		
        		//发现时段为空,确定跳过标记。
        		ucTurnSkip = 1;
        	}
       	 	else
       	 	{
        	        	
                	//读入指定地址,大小的时段控制量:	
                	//CAT24WC64P  (N<=8192)(地址:0-8191)
               	 	//CAT24WC16P  (N<=2048)(地址:0-2047)
        		fnRead_Eeprom(TurnList[ucSystemTurnNum].uiTurnCONAddress,
                        	2,uc2_SystemTurnCon);
                        
                	//当继承位有效,且为暂停切换
                	if(fnBitTest(uc2_SystemTurnCon[1],7))
                	{
        			//读入暂存的控制量		
        			uc2_SystemTurnCon[0] = uc2_SystemTurnConSaved[0];
        			uc2_SystemTurnCon[1] = uc2_SystemTurnConSaved[1];	
                	}        
			}

			//计时顺序设置
        	if(TurnList[ucSystemTurnNum].ucTurnTimeSortState == 0)
        		fnSet_TurnTime(uc4_SystemTurnTime,0);     //设置时段定时器时间,倒计时
        	else
        		fnSet_TurnTime(uc4_SystemTurnTime,1);     //设置时段定时器时间,正计时
						

            //下一个时段的自有初始化流程
        	pfnFunc = TurnList[ucSystemTurnNum].pfnInit_TurnN;
        	if(pfnFunc != NULL)
                	(*pfnFunc)();				//执行操作


	
			//ii.	根据时段工作状态ucTurnState,LED1-5显示。暂停-闪烁
			if(TurnList[ucSystemTurnNum].ucTurnState<5)
			if(ucTurnType == 0)
				fnSet_DisplayLED(TurnList[ucSystemTurnNum].ucTurnState+1,1,1);        //设置第i位LED显示不闪烁 1-5
			else
				fnSet_DisplayLED(TurnList[ucSystemTurnNumSaved].ucTurnState+1,1,0);        //设置第i位LED显示闪烁 1-5


			//时段运行开始
			bSystemTurnRunEnable = 1;
		
        }
        	

        fnCONoutput();                          //输出时段控制量(格式转换)
        
        fnStart_TurnTime();                     //开始时段定时器

		//根据调电记忆标志     PP1-4	4	是否采用掉电记忆功能	0-关闭 1-打开
		if ( ucBuf_AdvanceSet[PPAD_PP1_4] ) 
		{
			//刷新系统记忆RAM数据
			fnWrite_SystemZRAM();

		}

	//网络部分
	if( bCANState )
	{
		//根据节点地址,分别处理主节点(0)、普通节点的时段信息发送。
		if( ucCANAddress_Local == 0)
		{
			//主节点
			
			//向主节点发送节点的时段切换信息。(空时段则跳过!)
			if( ucTurnSkip == 0 )
			{			
				//向消息队列加入主节点消息
				//?需要屏蔽中断吗?
				//函数使用了信号量,保证不同时操作FIFO
				EX0=0;		//外部中断0使能禁止
				MsgListAdd(0x00,ucSystemTurnNum,ucSystemTurnNumSaved);
				EX0=1;		//外部中断0使能
			}
			
		}
		else
		{
			//普通节点
			
			//向主节点发送节点的时段切换信息。(空时段则跳过!)
			if( ucTurnSkip == 0 )
			{
				//CAN
				while(CAN_SendToMaster_Turn(ucSystemTurnNum,uc4_SystemTurnTime,uc2_SystemTurnCon,ucSystemTurnNumSaved)!=0)
				{
					if(ucSystemCANErrorState)
					{
						//错误报警!
						fnAlarm(1);
	
						fnBeep(1);
						
						//防止节点在网络出错的时候死机!
						
						//网络关闭!
						bCANState = 0;
						
						//清除错误标志
						ucSystemCANErrorState = 0;
						
						//退出循环,防止死机!
						break;
						
					}
					
				}
				//CAN_SendToMaster_Turn(ucSystemTurnNum,uc4_SystemTurnTime,uc2_SystemTurnCon,ucSystemTurnNumSaved);		
		
			}			
		}
		
		
	}
	

}


/*******************************************************************
		系统主循环网络处理函数
函数原型: void RUN_network()
功能: 	系统主循环网络处理函数

涉及变量:

********************************************************************/
void RUN_network()
{
	        
        idata MsgStruct Msg;
        
        uchar tempi;
        

		//主节点消息处理
		if( bCANState )
		if( ucCANAddress_Local == 0)
		{
			
			
			//主节点
			if(MsgListGet(&Msg)==0)
			{
				//有消息需要处理
				//CAN_Master_ListTest0(253);
				//while(CAN_Master_ListTest(129,Msg.ucNodeAdd,Msg.ucTurnN,Msg.ucTurnOld) != 0)
				//	;
				//CAN_Master_ListTest(129,Msg.ucNodeAdd,Msg.ucTurnN,Msg.ucTurnOld);
				
				//节点状态是否改变
				if(TurnList[Msg.ucTurnN].ucTurnState != TurnList[Msg.ucTurnOld].ucTurnState)
				{
					//节点状态改变了
					
					//删除节点的旧状态
					tempi = ListGetTheNode(TurnList[Msg.ucTurnOld].ucTurnState,Msg.ucNodeAdd);
					
					//当状态删除出错的时候,在其它状态列表中删除,
					//这样可以避免其它的子节点异常复位的结果!
					
					if(tempi == 0xFF)
					{
						//循环遍历所有状态表,删除可能的所有
						
						//State_X0 - 1.工作列表
						if(TurnList[Msg.ucTurnOld].ucTurnState != State_X0)
							ListGetTheNode(State_X0,Msg.ucNodeAdd);
													
						//State_X1 - 2.等待列表
						if(TurnList[Msg.ucTurnOld].ucTurnState != State_X1)
							ListGetTheNode(State_X1,Msg.ucNodeAdd);
							
						//State_X2/State_X4 - 3.还原列表
						if(TurnList[Msg.ucTurnOld].ucTurnState != State_X2)
						if(TurnList[Msg.ucTurnOld].ucTurnState != State_X4)
							ListGetTheNode(State_X2,Msg.ucNodeAdd);
						
						//State_X3 - 4.备用列表
						if(TurnList[Msg.ucTurnOld].ucTurnState != State_X3)
							ListGetTheNode(State_X3,Msg.ucNodeAdd);
						
						//State_XX - 5.准备列表
						if(TurnList[Msg.ucTurnOld].ucTurnState != State_XX)
							ListGetTheNode(State_XX,Msg.ucNodeAdd);
							
												
					}
					
					//加入节点的新状态
					ListAddNode(TurnList[Msg.ucTurnN].ucTurnState,Msg.ucNodeAdd);
					
					//测试地址254!!(!!!无错误检测!!!)
					CAN_Master_ListTest(254,Msg.ucNodeAdd,TurnList[Msg.ucTurnN].ucTurnState,TurnList[Msg.ucTurnOld].ucTurnState);
					
					//还原数小于MAX ucBuf_AdvanceSet[PPAD_PP1_7]
					if(List_Return.ucListN < ucBuf_AdvanceSet[PPAD_PP1_7])
					{
						//发送还原许可
						
						tempi = ListGetFirstNode(State_X1);
						
						if(tempi !=0xFF)
						{	
							if(tempi == 0x00)
							{
								//重要,防止因为上一数据未发送完,发送失败!
								while(CAN_SendToSlave_Allow01(tempi)!=0)
								{
									if(ucSystemCANErrorState)
									{
										//错误报警!
										fnAlarm(1);
	
										fnBeep(1);
										
										//退出循环,防止死机!
										//清除错误标志
										//ucSystemCANErrorState = 0;
										break;
						
									}
					
								}
								ucTurnAllow01 = 1;
							}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -