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

📄 distribute.c

📁 一整套电梯控制器源程序
💻 C
📖 第 1 页 / 共 2 页
字号:
#include "global.h"

uchar Is3FloorDistributed(uchar cLIdx, uchar updown_flg);
uchar IsLastOneDistribution(uchar cLIdx, uchar updown_flg);
uchar IsSomeoneNextStopFloor(uchar cLIdx, uchar updown_flg);
void SetNearNextStopFloorLIdx(uchar cEIdx); //LHM dyn_test temp动态测试专用变量(移植时删除)
void DistributeEle(void)
{
	uchar m_cLNum = LNum_MAX;
	uchar m_cENum = m_pL_Data->cENum;
	uchar cCurFloorIdx=0;
	uchar i=0,j=0;
	uchar updown_flg;	//1上 0下
	uint  out_id=0;		//楼层数(其中5位有效)
	uchar a=0;
	uchar xdata *can_p;
	uchar cSendLIdx=0;
	uchar ret0=0;
	uchar ret1=0;

	E_WaiHu *pWaiHu = &(m_pE_InputData->mWaiHu);


	//上呼分配(从下而上进行分配)		
	uchar cLIdx = m_CalUpLIdx;	//(取值0-55)
	uchar bVal;	//外呼数值

	//设置中间数据"楼层可停"
	SetInterVal_FloorCanStop(cLIdx, 1);
	//设置中间数据"2层以内运动"
	SetInterVal_2FloorMove(cLIdx, 1);
	//设置中间数据"顺向"
	SetInterVal_SameDirection(cLIdx, 1);

	if(GetArrayData(pWaiHu->bShang, cLIdx) == 1){	//若该层有上呼,进行电梯分配
		updown_flg = D_Up;	//设置上标记
		bVal	   = 1; 
		//若有一部电梯恰好到达外呼层,顺向,零速信号为1或运行停止信号为0,则撤销外呼点灯
		if(IsWithdrawOutLight(cLIdx,updown_flg)){

			SetOutCallLight(cLIdx, updown_flg, 0);
//2004.11.17
//为避免撤灯时,发生闪烁,取消提前撤灯(需要进一步确认)
			//为了及时外呼撤灯,提前发送撤灯数据
			for(a=0; a<m_cENum; a++){
				if(e_online[a]==1){
//2004.11.24    LHM
//                  cSendLIdx=cLIdx-LNum_MAX_UNDERGROUND+1; 
                    cSendLIdx=cLIdx-mE_InputData.mDianTi[a].cJuDiCengShu-LNum_MAX_UNDERGROUND+1; 
                    out_id=cSendLIdx;            //计算外呼标志符
                    out_id=out_id<<5;                                            
                    out_id=out_id|0x4800;                                       
                    can_p=canx_cs[a];
	         	    //can是否在线  
		            if((*(can_p+2)&0x4)==0x4){   // 发送缓冲区空
						*(can_p+16)=0x02;                                      
						*(can_p+17)=out_id>>8;
						*(can_p+18)=out_id&0xff;
						*(can_p+19)=0x5a;        //命令3
						*(can_p+20)=0xa0;        //外呼灯
						*(can_p+1)=0x1;          //发送请求
		            }
				}
			}
    	}
		//进行外呼分配
//		if(cLIdx==9)
//			mE_InputData.mDianTi[0].TongXun.bZhiShi=IsLastOneDistribution(cLIdx, updown_flg);
        ret0 = IsSomeoneNextStopFloor(cLIdx, updown_flg);
        ret1 = IsLastOneDistribution(cLIdx, updown_flg);
		if( /*(!Is3FloorDistributed(cLIdx, updown_flg)) && */(ret0==0) && (ret1==0) )
			OptimizeArrange(cLIdx, updown_flg);

	}else{
		updown_flg = D_Up;	//设置上标记
		bVal	   = 0;
		//确保取消外呼点灯
		SetOutCallLight(cLIdx, updown_flg, bVal);
		//确保取消外呼分配
		SetOutCallDistribution(cLIdx, updown_flg, bVal);	
	} 

	cLIdx = m_CalDownLIdx;
	//设置中间数据"楼层可停"
	SetInterVal_FloorCanStop(cLIdx, 0);
	//设置中间数据"2层以内运动"
	SetInterVal_2FloorMove(cLIdx, 0);
	//设置中间数据"顺向"
	SetInterVal_SameDirection(cLIdx, 0);

	if(GetArrayData(pWaiHu->bXia, cLIdx) == 1){//若该层有下呼,进行电梯分配
		updown_flg = D_Down;	//设置下标记
		bVal	   = 1;	
		if(IsWithdrawOutLight(cLIdx,updown_flg)){
			SetOutCallLight(cLIdx, updown_flg, 0);
//2004.11.17
//为避免撤灯时,发生闪烁,取消提前撤灯(需要进一步确认)
			//为了及时外呼撤灯,提前发送撤灯数据
			for(a=0; a<8; a++){
				if(e_online[a]==1){
//2004.11.24    LHM
//                  cSendLIdx=cLIdx-LNum_MAX_UNDERGROUND+1; 
                    cSendLIdx=cLIdx-mE_InputData.mDianTi[a].cJuDiCengShu-LNum_MAX_UNDERGROUND+1; 
                    out_id=cSendLIdx;         //计算外呼标志符
                    out_id=out_id<<5;                                            
                    out_id=out_id|0x4800;                                       
                    can_p=canx_cs[a];
	         	           //can是否在线 
		            if((*(can_p+2)&0x4)==0x4){    //发送缓冲区空  
						*(can_p+16)=0x02;                                      
						*(can_p+17)=out_id>>8;
						*(can_p+18)=out_id&0xff;
						*(can_p+19)=0x5a;         //命令3 
						*(can_p+20)=0x0a;         //外呼灯
						*(can_p+1)=0x1;           //发送请求	 
		            }
				}
			}
		}
		//进行外呼分配
	//	if(cLIdx==9){
	//		mE_InputData.mDianTi[0].TongXun.bZhiShi=IsLastOneDistribution(cLIdx, updown_flg);
	//		P1_7=0;
	//	}
        ret0 = IsSomeoneNextStopFloor(cLIdx, updown_flg);
        ret1 = IsLastOneDistribution(cLIdx, updown_flg);
		//if( (!Is3FloorDistributed(cLIdx, updown_flg)) && (!IsSomeoneNextStopFloor(cLIdx, updown_flg))&&(!IsLastOneDistribution(cLIdx, updown_flg)) )
		if( /*(!Is3FloorDistributed(cLIdx, updown_flg)) && */(ret0==0) && (ret1==0) )
			OptimizeArrange(cLIdx, updown_flg);
	}else{
		updown_flg = D_Down;	//设置下标记
		bVal	   = 0;
		//确保取消外呼点灯
		SetOutCallLight(cLIdx, updown_flg, bVal);
		//确保取消外呼分配
		SetOutCallDistribution(cLIdx, updown_flg, bVal);	
	}

    //2004.11.25 added by LHM循环设置点灯数据
    LoopSetCallLightData(m_CalUpLIdx, m_CalDownLIdx);

	//取得各电梯下一停靠层索引和搜索方向
	for(i=0; i<m_cENum; i++){
		SetNearNextStopFloorLIdx(i);
	}


	//下一楼层
	m_CalUpLIdx++;			//上呼层索引
	if(m_CalUpLIdx>=m_cLNum)
		m_CalUpLIdx=0;

	if(m_CalDownLIdx==0)	//下呼层索引
		m_CalDownLIdx=mL_Data.cLNum-1;
	else
		m_CalDownLIdx--;
}

//外呼是否已经分配给"三层以内(含三层)到达且处于运动中的电梯"
uchar Is3FloorDistributed(uchar cLIdx, uchar updown_flg)
{
	uchar m_cLNum = LNum_MAX;
	uchar m_cENum = m_pL_Data->cENum;
	uchar i=0,j=0;
	signed char distance=0;
	E_DianTi	*pEleData; 
	E_FangXiang	*pFangXiang;				//方向数据
	E_XiangYing *pXiangYing;	//外呼分配数据
	uchar       cCurFloorIdx;			//当前层


	for(i=0; i<m_cENum; i++){
		pEleData    = &(m_pE_InputData->mDianTi[i]); 
		pFangXiang  = &(pEleData->FangXiang);				//方向数据
		pXiangYing  = &(m_pE_OutputData->mXiangYing[i]);	//外呼分配数据
		cCurFloorIdx = pEleData->cDangQianCeng-1;			//当前层
		if(updown_flg == D_Up){	//上呼
			//外呼层到当前层的间隔楼层数("-1"是因为"当前层"从1开始)
			if( cLIdx >= cCurFloorIdx)
				distance = cLIdx - cCurFloorIdx;
			else
				distance = cCurFloorIdx - cLIdx;
			//三层以内,运行方向向上,运动中,并且已分配
//2004.05.25 LHM 修正原因:下位机负责定向,定向用到外呼分配,而撤销外呼用到方向,为避免三角连锁错误,故对于正常到达的电梯在开关门状态时,不必进行分配.
//			if( (0<=distance) && (distance<=pEleData->cMinCancelFenPei) && (pEleData->bDongOrJing ==1) && (pXiangYing->bShang[cLIdx]==1)){
			if( (0<=distance) && (distance<=pEleData->cMinCancelFenPei) && (pEleData->bDongOrJing ==1) && (GetArrayData(pXiangYing->bShang, cLIdx)==1)){
					if((pFangXiang->bShang==1) && (pFangXiang->bXia==0) && (cLIdx>=cCurFloorIdx))
						return 1;
					else if((pFangXiang->bShang==0) && (pFangXiang->bXia==1) && (cLIdx<=cCurFloorIdx))
						return 1;
			}
			if(cCurFloorIdx==cLIdx)
			if(pEleData->bDongOrJing ==0)
			if(GetArrayData(pXiangYing->bShang, cLIdx)==1){
					if((pFangXiang->bShang==1) && (pFangXiang->bXia==0) && (cLIdx>=cCurFloorIdx))
						return 1;
					else if((pFangXiang->bShang==0) && (pFangXiang->bXia==1) && (cLIdx<=cCurFloorIdx))
						return 1;
			}
		}else{					//下呼
			//外呼层到当前层的间隔楼层数("-1"是因为"当前层"从1开始)
			if( cLIdx >= cCurFloorIdx)
				distance = cLIdx - cCurFloorIdx;	 
			else
				distance = cCurFloorIdx - cLIdx;
			//三层以内,运行方向向上,运动中,并且已分配
//			if( (0<=distance) && (distance<=pEleData->cMinCancelFenPei) && (pEleData->bDongOrJing ==1) && (pXiangYing->bXia[cLIdx]==1)){
			if( (0<=distance) && (distance<=pEleData->cMinCancelFenPei) && (pEleData->bDongOrJing ==1) && (GetArrayData(pXiangYing->bXia, cLIdx)==1)){
				if((pFangXiang->bShang==1) && (pFangXiang->bXia==0) && (cLIdx>=cCurFloorIdx))
					return 1;
				else if((pFangXiang->bShang==0) && (pFangXiang->bXia==1) && (cLIdx<=cCurFloorIdx))
					return 1;
			}
			if(cCurFloorIdx==cLIdx)
			if(pEleData->bDongOrJing ==0)
			if(GetArrayData(pXiangYing->bXia, cLIdx)==1){
				if((pFangXiang->bShang==1) && (pFangXiang->bXia==0) && (cLIdx>=cCurFloorIdx))
					return 1;
				else if((pFangXiang->bShang==0) && (pFangXiang->bXia==1) && (cLIdx<=cCurFloorIdx))
					return 1;
			}
		}
	}

	return 0;
}

//外呼是否是某电梯最后一个外呼分配,且当前层与最后一个外呼之间无内选
uchar IsLastOneDistribution(uchar cLIdx, uchar updown_flg)
{
	uchar m_cLNum = LNum_MAX;
	uchar m_cENum = m_pL_Data->cENum;
    uchar m_cEleIdx=0xFF;                  //该外呼已经分配给该部电梯
	uchar i=0,j=0;


	E_DianTi	*pEleData; 
	E_FangXiang	*pFangXiang;				//方向数据
	E_XiangYing *pXiangYing;	//外呼分配数据
	uchar       cCurFloorIdx;			//当前层
	uchar cTopFloor		= pEleData->cZuiGaoCeng-1;	//可到最高层(-1是因为楼层计数从1开始)
	uchar cBottomFloor	= pEleData->cZuiDiCeng-1;	//可到最底层(-1是因为楼层计数从1开始)

	uchar count=0;
	uchar cIsExistNeiXuan=0;
    
	for(i=0; i<m_cENum; i++){
		pEleData    = &(m_pE_InputData->mDianTi[i]); 
		pXiangYing  = &(m_pE_OutputData->mXiangYing[i]);	//外呼分配数据
		if(updown_flg==1){						//上呼
            if(GetArrayData(pXiangYing->bShang, cLIdx)==1){
                m_cEleIdx=i;
            }
        }else if(updown_flg==0){                //下呼
            if(GetArrayData(pXiangYing->bXia, cLIdx)==1){
                m_cEleIdx=i;
            }
        }
    }
    
    if(m_cEleIdx==0xFF){    //尚未分配给任意一部电梯
        return 0;
    }
    
	pEleData    = &(m_pE_InputData->mDianTi[m_cEleIdx]); 
	pXiangYing  = &(m_pE_OutputData->mXiangYing[m_cEleIdx]);	//外呼分配数据
	pFangXiang  = &(pEleData->FangXiang);				        //方向数据
	cCurFloorIdx = pEleData->cDangQianCeng-1;			        //当前层
	cTopFloor	= pEleData->cZuiGaoCeng-1;	//可到最高层(-1是因为楼层计数从1开始)
	cBottomFloor= pEleData->cZuiDiCeng-1;	//可到最底层(-1是因为楼层计数从1开始)
    
    //计算该部电梯的已有外呼分配数目
    count=0;
	for(j=0; j<m_cLNum; j++){
		if(GetArrayData(pXiangYing->bShang, j)==1)
			count++;
		if(GetArrayData(pXiangYing->bXia, j)==1)
			count++;
	}
    //判断是否是最后一个外呼分配
    if(count!=1)
        return 0;
/*	 else{
	 	  if(pEleData->bDongOrJing==1)
	 	  		return 1;
		  else
		  		return 0;
	 }

	 return 1;
*/

    cIsExistNeiXuan=0;
    //判断是否在当前层与外呼之间存在内选
    if(updown_flg==1){       //上呼
		//当前层沿着运行方向是否有内选
		if((pFangXiang->bShang==1)&&(pXiangYing->bXia==0)){
			if(cCurFloorIdx>cLIdx){
//				if(cCurFloorIdx==cTopFloor){
//					cIsExistNeiXuan=0;
//				}else{
					for(j=(cCurFloorIdx+1); j<=cTopFloor; j++){    
						if(GetArrayData(pEleData->bNeiXuan, j)==1)
							cIsExistNeiXuan=1;
					}
//				}
			}else if(cCurFloorIdx<cLIdx){
				for(j=(cCurFloorIdx+1); j<=(cLIdx-1); j++){
					if(GetArrayData(pEleData->bNeiXuan, j)==1)
						cIsExistNeiXuan=1;
				}
			}else{
				cIsExistNeiXuan=0;
			}
		}else if((pFangXiang->bShang==0)&&(pFangXiang->bXia==1)){
			if(cCurFloorIdx>cLIdx){
				for(j=(cLIdx+1); j<=(cCurFloorIdx-1); j++){
					if(GetArrayData(pEleData->bNeiXuan, j)==1)
						cIsExistNeiXuan=1;
				}
			}else if(cCurFloorIdx<cLIdx){
//				if(cIsExistNeiXuan==cBottomFloor){
//					cIsExistNeiXuan=0;
//				}else{
					for(j=cBottomFloor; j<=(cCurFloorIdx-1); j++){
						if(GetArrayData(pEleData->bNeiXuan, j)==1)
							cIsExistNeiXuan=1;
					}
//				}
			}else{
				cIsExistNeiXuan=0;
			}
		}else{
			cIsExistNeiXuan=0;
		}
    }else if(updown_flg==0){
		//当前层与外呼层之间是否有内选
		if((pFangXiang->bShang==1)&&(pFangXiang->bXia==0)){
			if(cCurFloorIdx>cLIdx){
//				if(cCurFloorIdx==cTopFloor){
//					cIsExistNeiXuan=0;
//				}else{
					for(j=(cCurFloorIdx+1); j<=cTopFloor; j++){
						if(GetArrayData(pEleData->bNeiXuan, j)==1)

⌨️ 快捷键说明

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