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

📄 intervalue.c

📁 一整套电梯控制器源程序
💻 C
字号:
#include "global.h"

uchar  GetVetoVal(uchar cEIdx);
uchar GetWeightVal(uchar cEIdx);
uchar GetStopCountVal(uchar cEIdx);
uchar GetElePRINoVal(uchar cEIdx);
uchar GetCurStageStartFloor(uchar cEIdx);

//根据输入数据,计算各电梯的中间数据
//注意:1)与楼层数据无关的中间淘汰数据,在此计算数值;(包括:一票否决,承载程度,停靠层站数,电梯优先级号)
//	   2)与楼层数据有关的中间淘汰数据,其他场合计算;(包括:楼层可停,到达大致时间)
//	   3)其他中间数据;
void SetPartInterVal(void)
{	
	uchar 	m_cENum	= m_pL_Data->cENum;
	uchar	i=0;
    uchar   veto_count=0;

	for(i=0; i<m_cENum; i++){
		//一票否决
		m_InterData[i].bVeto = GetVetoVal(i);
//2004.11.20 监视淘汰标记,发现异常
        if(m_InterData[i].bVeto==1){
            veto_count++;
        }
		if(i==1)
			mE_InputData.mDianTi[1].TongXun.bZhiShi=m_InterData[i].bVeto;
		if(i==2)
			mE_InputData.mDianTi[2].TongXun.bZhiShi=m_InterData[i].bVeto;

		//承载程度
		m_InterData[i].cWeight = GetWeightVal(i);
		//停靠层站数
		m_InterData[i].cStopCount = GetStopCountVal(i);
		//电梯优先级号
		m_InterData[i].cPRINo = GetElePRINoVal(i);
		//电梯当前运动阶段的起始楼层
		m_cCurStageStartFloor[i] = GetCurStageStartFloor(i);
		//门超时时间
		m_cOvertime[i] = GetDoorOvertime(i);
	}
    if(veto_count==m_cENum){ //全部淘汰时,保留1部(必须在线)
	   for(i=0; i<m_cENum; i++){
            if(e_online[i]==1){
                m_InterData[i].bVeto=0;
                break;
            }
       }
    }
}  

//中间淘汰数据"一票否决"
//涉及的输入数据:
//"群控选中""单梯/群控""准备好""门故障""满载""超载""检修""司机""直驶""保留"
//"锁梯""消防""急停""故障""警告""CAN初始化OK""门超时时间5"
uchar GetVetoVal(uchar cEIdx)
{
	E_DianTi *pEleData = &(m_pE_InputData->mDianTi[cEIdx]);
	//是否CAN在线
	//2004.11.20 测试通讯在线标记正常
/*
		if(cEIdx==1)
			mE_InputData.mDianTi[0].TongXun.bZhiShi=e_online[cEIdx];
		if(cEIdx==2)
			mE_InputData.mDianTi[3].TongXun.bZhiShi=e_online[cEIdx];
*/

	if(e_online[cEIdx]==0)	
		return 1;
	
	if(pEleData->bQunKong == 0)					//群控选中
		return 1;
	else if(pEleData->bDanOrQun == 0)			//单梯/群控
		return 1;
	else if(pEleData->bZhunBeiHao == 0)			//准备好
		return 1;
	else if(pEleData->Men.bMenGuZhang == 1)		//门故障
		return 1;
	else if(pEleData->ChengZai.bManZai == 1)	//满载
		return 1;
//	else if(pEleData->ChengZai.bChaoZai == 1)	//超载
//		return 1;
	else if(pEleData->TeBie.bJianXiu == 1)		//检修
		return 1;
//	else if(pEleData->TeBie.bSiJi == 1)			//司机	//2004.07.16 LHM(司机也参与分配) 
//		return 1;
//	else if(pEleData->TeBie.bZhiShi == 1)		//直驶
//		return 1;
    else if(pEleData->TeBie.bSiJi == 1){
//      if(pEleData->bDongOrJing == 1)          //2005.01.25  取消动静
        if(pEleData->TeBie.bZhiShi == 1){       
            return 1;
        }
	}else if(pEleData->TeBie.bBaoLiu == 1)		//保留
		return 1;
	else if(pEleData->TeBie.bSuoTi == 1)		//锁梯
		return 1;
	else if(pEleData->TeBie.bXiaoFang == 1)		//消防
		return 1;
	else if(pEleData->TeBie.bJiTing == 1){		//急停
        if(pEleData->Men.bGuanMenDaoWei==1)
        if(pEleData->bBenCengKaiMen==0){
    		return 1;
        }
	}else if(pEleData->TeBie.bGuZhang == 1)		//故障
		return 1;
	else if(pEleData->TeBie.bJingGao == 1)		//警告
		return 1;
	else if(pEleData->TongXun.bCanChuShiOK == 0)//CAN初始化OK
		return 1;
	
	//堵门时间超过"门超时5"
/*	if(GetDoorActionState(cEIdx) != Door_CloseOK){
		long  cur_elapsetime = GetTickCount();
		long  overtime = (cur_elapsetime - m_pTimer->lChaoShiTimer[cEIdx])/1000; //该电梯的门超时时间
		if(pEleData->cChaoShiTime[MenChaoShi_Num-1] <= overtime)
			return 1; 
	}*/

	//2004.11.20 测试门超时ok
    if(pEleData->TeBie.bSiJi==0)
	if(pEleData->cChaoShiTime[MenChaoShi_Num-1] <= m_cOvertime[cEIdx]){
		return 1; 
    }
	

	return 0;
}

//中间淘汰数据"承载状态"
//涉及的输入数据:
//"空载""轻载""重载""满载""超载"
//注意:若同时出现两个以上的承载信号,以承载程度大的信号为准
uchar GetWeightVal(uchar cEIdx)
{
	E_DianTi	*pEleData = &(m_pE_InputData->mDianTi[cEIdx]); 
	E_ChengZai	*pChengZai= &(pEleData->ChengZai);

	if(pChengZai->bChaoZai == 1)		//超载
		return Weight_Over;
	else if(pChengZai->bManZai == 1)	//满载
		return Weight_Full;
	else if(pChengZai->bZhongZai == 1)	//重载
		return Weight_Heavy;
	else if(pChengZai->bQingZai == 1)	//轻载
		return Weight_Light;
	else if(pChengZai->bKongZai == 1)	//空载
		return Weight_Null;
	
	return Weight_ERROR;
}

//中间淘汰数据"可停层站数"
//涉及的输入数据:
//"可到最底层""可到最高层""可停层站数"
uchar GetStopCountVal(uchar cEIdx)
{
	E_DianTi	*pEleData = &(m_pE_InputData->mDianTi[cEIdx]); 
	uchar cCanStopFloorCnt = pEleData->cZuiGaoCeng-pEleData->cZuiDiCeng+1;
	return	cCanStopFloorCnt;
}

//中间淘汰数据"电梯优先级"
//涉及的输入数据:
//"优先级号"
uchar GetElePRINoVal(uchar cEIdx)
{
	E_DianTi	*pEleData = &(m_pE_InputData->mDianTi[cEIdx]); 
	uchar cPRINo = pEleData->cYouXianJi;
	return	cPRINo;
}

//中间淘汰数据"楼层可停"
//涉及的输入数据:
//"楼层可停"
//2004.11.17 (楼层可停数据暂时未用,改用最低楼层最高楼层限制)
void  SetInterVal_FloorCanStop(uchar cLIdx, uchar updown_flg)
{
	E_DianTi *pEleData;
	uchar 	m_cENum	= m_pL_Data->cENum;
	uchar	i=0;
	uchar 	cTopFloorIdx;
	uchar 	cBottomFloorIdx;

	for(i=0; i<m_cENum; i++){
		pEleData = &(m_pE_InputData->mDianTi[i]); 
		cTopFloorIdx    = pEleData->cZuiGaoCeng-1;
		cBottomFloorIdx = pEleData->cZuiDiCeng-1;
		//楼层可停
		if(updown_flg == 1){	//上呼
//			m_InterData[i].bFloorCanStop = GetArrayData(pEleData->bShangHuKeTing, cLIdx);
//2005.05.19 不能响应最高层上呼
//			if((cLIdx>=cBottomFloorIdx)&&(cLIdx<=cTopFloorIdx)){
			if((cLIdx>=cBottomFloorIdx)&&(cLIdx<=(cTopFloorIdx-1))){
				m_InterData[i].bFloorCanStop=1;
			}else{
				m_InterData[i].bFloorCanStop=0;
			}
		}else{
//			m_InterData[i].bFloorCanStop = GetArrayData(pEleData->bXiaHuKeTing, cLIdx);
//2005.05.19 不能响应最低层下呼
//			if((cLIdx>=cBottomFloorIdx)&&(cLIdx<=cTopFloorIdx)){
			if((cLIdx>=(cBottomFloorIdx+1))&&(cLIdx<=cTopFloorIdx)){
				m_InterData[i].bFloorCanStop=1;
			}else{
				m_InterData[i].bFloorCanStop=0;
			}
		}
	}

	return;
}

//中间淘汰数据"2层以内运动"
//涉及的输入数据:
//"运动/静止""向上运动""向下运动""当前层"
//注意:1)"当前层"从1开始
//     2)参数cLIdx从0开始
//     3)介于信号可能出现问题,本函数必须考虑异常处理,异常时,暂时将值设为1,不参与新的分配,原分配撤销并分配给其他电梯
void  SetInterVal_2FloorMove(uchar cLIdx, uchar updown_flg)
{
	uchar 		m_cENum	= m_pL_Data->cENum;
	uchar		i=0;
	signed char distance=0;

	for(i=0; i<m_cENum; i++){
		E_DianTi	*pEleData  = &(m_pE_InputData->mDianTi[i]); 
		E_FangXiang	*pFangXiang= &(pEleData->FangXiang);

		if(pEleData->bDongOrJing == 1){	//电梯处于运动中
			if((pFangXiang->bShang==1) && (pFangXiang->bXia==0)){		//方向向上时,判断电梯是否在2层以内且处于运动状态
				distance = (cLIdx+1) - pEleData->cDangQianCeng;			//(负值表示外呼层低于当前层)
				if((0<=distance) && (distance<=pEleData->cMinFenPei) && (updown_flg==1) && (m_nNextStopLIdx[i]!=cLIdx))	//可以分配反向外呼/可以分配下一停靠层的顺向外呼
					m_InterData[i].b2FloorMove = 1;
				else
					m_InterData[i].b2FloorMove = 0;
			}else if((pFangXiang->bShang==0) && (pFangXiang->bXia==1)){	//方向向下时,判断电梯是否在2层以内且处于运动状态
				distance = pEleData->cDangQianCeng - (cLIdx+1);			//(负值表示外呼层高于当前层)
				if((0<=distance) && (distance<=pEleData->cMinFenPei) && (updown_flg==0) && (m_nNextStopLIdx[i]!=cLIdx))	//可以分配反向外呼/可以分配下一停靠层的顺向外呼
					m_InterData[i].b2FloorMove = 1;
				else
					m_InterData[i].b2FloorMove = 0;
			}else if((pFangXiang->bShang==0) && (pFangXiang->bXia==0)){ //无方向(原则上,电梯在运动中这种情况不可能出现,因为方向由各电梯处理后传输给群控器,但是不排除信号错误)
//2004.05.17	LHM (方向与外呼分配的计算存在时间差)
//				m_InterData[i].b2FloorMove = 1;
				m_InterData[i].b2FloorMove = 0;
			}else/* if((pFangXiang->bShang==1) && (pFangXiang->bXia==1))*/{	//截然相反的方向同时出现(原则上这种情况不可能出现,因为方向由各电梯处理后传输给群控器,但是不排除信号错误)
				m_InterData[i].b2FloorMove = 1;
			}

		}else{							//电梯处于静止中
			m_InterData[i].b2FloorMove = 0;
		}
	}

	return;
}

//设置淘汰数据"顺向"
void  SetInterVal_SameDirection(uchar cLIdx, uchar updown_flg)
{
	uchar 		m_cENum	= m_pL_Data->cENum;
	uchar		i=0;

	for(i=0; i<m_cENum; i++){
		E_DianTi	*pEleData  = &(m_pE_InputData->mDianTi[i]); 
		uchar cCurFloorIdx = pEleData->cDangQianCeng-1 ;//当前层索引
		if(updown_flg == 1){//上呼
			if(cLIdx>=cCurFloorIdx)
				m_InterData[i].bSameDirection = 1;
			else 
				m_InterData[i].bSameDirection = 0;
		}else{				//下呼
			if(cLIdx<=cCurFloorIdx)
				m_InterData[i].bSameDirection = 1;
			else 
				m_InterData[i].bSameDirection = 0;
		}
	}

	return;
}

//电梯当前运动阶段的起始楼层
//0xFF为无效值
uchar GetCurStageStartFloor(uchar cEIdx)
{
	E_DianTi	*pEleData = &(m_pE_InputData->mDianTi[cEIdx]); 
	uchar cCurStageStartFloorIdx;

//	cCurStageStartFloorIdx = pEleData->cDangQianCeng - 1;	//2004.02.20	LHM 可疑代码,应该为多余代码(需进一步确定)
	//电梯处于静止时或无效设置后,更新"当前运动阶段的起始楼层"
	if((pEleData->bDongOrJing==0) || (m_cCurStageStartFloor[cEIdx]==0xFF))	
		cCurStageStartFloorIdx = pEleData->cDangQianCeng - 1;
	else
		cCurStageStartFloorIdx = m_cCurStageStartFloor[cEIdx];

	return cCurStageStartFloorIdx;
}

//取得当前能够分配的电梯总数
uchar GetCanDistEleCount()
{
	uchar m_cENum	= m_pL_Data->cENum;
	uchar cCanDistEleCount=0;
	uchar i=0;

	for(i=0; i<m_cENum; i++){
		if(m_InterData[i].bVeto==0)
			cCanDistEleCount++;
	}
	
	return cCanDistEleCount;
}

//取得最小可到最低楼层数(0-7:地下,8-55:地上)
uchar GetMinBottomFloor()
{
	E_DianTi *pEleData  = 0;
	uchar	 m_cENum	= m_pL_Data->cENum;
	uchar	 cMinBottomFloor=55;	//初始足够大
	uchar i=0;

	for(i=0; i<m_cENum; i++){
		pEleData = &(m_pE_InputData->mDianTi[i]);
		if(e_online[i]==1)
			if(pEleData->cZuiDiCeng<cMinBottomFloor)
				cMinBottomFloor = pEleData->cZuiDiCeng;
	}	
	return cMinBottomFloor;
}

//取得最大可到最高楼层数(0-7:地下,8-55:地上)
uchar GetMaxTopFloor()
{
	E_DianTi *pEleData  = 0;
	uchar	 m_cENum	= m_pL_Data->cENum;
	uchar	 cMaxTopFloor=0;	//初始足够小
	uchar	 i=0;

	for(i=0; i<m_cENum; i++){
		pEleData = &(m_pE_InputData->mDianTi[i]);
		if(e_online[i]==1)
			if(pEleData->cZuiGaoCeng>cMaxTopFloor)
				cMaxTopFloor = pEleData->cZuiGaoCeng;
	}	
	return cMaxTopFloor;
}


//取得门超时的时间(单位:秒)
// 2004.06.17 modified by LHM 17Door
uchar GetDoorOvertime(uchar cEIdx)
{
/*	E_DianTi	*pEleData = &(m_pE_InputData->mDianTi[cEIdx]); 
	E_MenTime	*pMenTime = &(pEleData->MenTime);
	uchar overtime=0;	//该电梯的开门超时时间
	long  openedtime=0;
	long  cur_elapsetime = 0;
	uchar cDoorState = GetDoorActionState(cEIdx);

	if( cDoorState != Door_CloseOK){	//关门不到位
		openedtime = (cur_elapsetime-m_pTimer->lChaoShiTimer[cEIdx])/1000 - 
			pMenTime->cGMYanChiTime - pMenTime->cKaiMenTime - pMenTime->cGuanMenTime; //该电梯的开门超时时间
		if((0<=openedtime) && (openedtime<pEleData->cChaoShiTime[0]))
			overtime = 0;
		else if((pEleData->cChaoShiTime[0]<=openedtime) && (openedtime<pEleData->cChaoShiTime[1]))	//门超时1
			overtime = pEleData->cChaoShiTime[0];
		else if((pEleData->cChaoShiTime[1]<=openedtime) && (openedtime<pEleData->cChaoShiTime[2]))	//门超时2
			overtime = pEleData->cChaoShiTime[1];
		else if((pEleData->cChaoShiTime[2]<=openedtime) && (openedtime<pEleData->cChaoShiTime[3]))	//门超时3
			overtime = pEleData->cChaoShiTime[2];
		else if((pEleData->cChaoShiTime[3]<=openedtime) && (openedtime<pEleData->cChaoShiTime[4]))	//门超时4
			overtime = pEleData->cChaoShiTime[3];
		else if((pEleData->cChaoShiTime[4]<=openedtime))											//门超时5
			overtime = pEleData->cChaoShiTime[4];
		else												//负值
			overtime = 0;
	}else{											//关门到位
		overtime = 0;
	}
	return overtime;
*/
	E_DianTi	*pEleData = &(m_pE_InputData->mDianTi[cEIdx]); 
	E_MenTime	*pMenTime = &(pEleData->MenTime);
	uchar overtime=0;	//该电梯的开门超时时间
	signed long  openedtime=0;
	long  cur_elapsetime = 0;
	uchar cDoorState = GetDoorActionState(cEIdx);

	if( cDoorState != 1/*Door_CloseOK*/){	//关门不到位
		  openedtime = m_pTimer->lChaoShiTimer[cEIdx]/1000 - 
		  		pMenTime->cGMYanChiTime - pMenTime->cKaiMenTime - pMenTime->cGuanMenTime; //该电梯的开门超时时间
        if(openedtime>0){
	    		if((0<=openedtime) && (openedtime<pEleData->cChaoShiTime[0]))
	    			overtime = 0;
	    		else if((pEleData->cChaoShiTime[0]<=openedtime) && (openedtime<pEleData->cChaoShiTime[1]))	//门超时1
	    			overtime = pEleData->cChaoShiTime[0];
	    		else if((pEleData->cChaoShiTime[1]<=openedtime) && (openedtime<pEleData->cChaoShiTime[2]))	//门超时2
	    			overtime = pEleData->cChaoShiTime[1];
	    		else if((pEleData->cChaoShiTime[2]<=openedtime) && (openedtime<pEleData->cChaoShiTime[3]))	//门超时3
	    			overtime = pEleData->cChaoShiTime[2];
	    		else if((pEleData->cChaoShiTime[3]<=openedtime) && (openedtime<pEleData->cChaoShiTime[4]))	//门超时4
	    			overtime = pEleData->cChaoShiTime[3];
	    		else if((pEleData->cChaoShiTime[4]<=openedtime))											//门超时5
	    			overtime = pEleData->cChaoShiTime[4];
	    		else												//负值
	    			overtime = 0;
        }else{
            overtime = 0;
        }
	}else{											//关门到位
		overtime = 0;
	}
	return overtime;
}

⌨️ 快捷键说明

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