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

📄 iec103_sf.cpp

📁 四方公司103规约
💻 CPP
📖 第 1 页 / 共 5 页
字号:


#include "IEC103_SF.h"

namespace IEC103Ptl_SF
{

	//初始化节点运行参数
	BOOL CIEC103_SFPtl::CreateRealRunIED(CIED *pIED)
	{
		if(pIED == NULL)
			return FALSE;

		BOOL bRtn = TRUE;
		BYTE byNodeId = pIED->m_IEDConfig.byNodeID;
		RealRunIED *pDevRun = m_IEC103Data.m_RunIed[byNodeId];
		if (!pDevRun)
		{	//如果pDevRun为空,则动态分配内存,并把其赋值给规约数据中的参数
			pDevRun = new RealRunIED;//规约退出是要释放
			if (pDevRun)
				m_IEC103Data.m_RunIed[byNodeId] = pDevRun;
		}

		if (!pDevRun)
			return FALSE;

		memset(pDevRun, 0, sizeof(RealRunIED));

		pDevRun->pDevData = pIED; 
		pDevRun->byNodeId = byNodeId;
		pDevRun->mode = 0;	
		pDevRun->fcb = 0;	
		pDevRun->acd = 0;	
		pDevRun->sendCode = pDevRun->recvCode = 0;
		pDevRun->linkQuery	= 0;	
		pDevRun->linkRes= 1;
		pDevRun->query	= 0;
		pDevRun->queryFull= 0;
		pDevRun->sin = 0;
		pDevRun->lnkNoRecvCnt = 0;
		pDevRun->bCommInitFlag = TRUE;
		pDevRun->bQuryEnd = FALSE;
		pDevRun->bGenGroupQury = FALSE;
		pDevRun->bDdQury = FALSE;
		pDevRun->nASDU5Cnt = 0;
		pDevRun->step = eInitStart;

		int i = 0;					//初始化自定义参数--组号与类型
		USERPARA para;
		for (i=0; i<IED_USER_SIZE;i++)
		{
			GinGrouptoType* ptype = &pDevRun->Grouptotype[i];
			ptype->gintype = (eGinGroupType)0;
			ptype->gingroup = 0;
			if (pIED->GetDataPara(dataUserPara,0,i,(void*)&para))
			{
				ptype->gintype = (eGinGroupType)para.wUPara0;
				ptype->gingroup = para.wUPara1;
				//printf("ptype->gintype = %d,para.wUPara0 = %d\n",ptype->gintype,para.wUPara0);
				//printf("ptype->gingroup = %d,para.wUPara1 = %d\n",ptype->gingroup,para.wUPara1);
			}
		}
		return bRtn;
	}

	// 得到 fun+inf=>nIndex 的映射关系
	int	CIEC103_SFPtl::GetnIndexbyFuninf(CIED *pIED, eDataSort datatype, FunInf &funInf)
	{
		//printf("datatype = %d,fun = %d,inf = %d\n",datatype,funInf.fun,funInf.inf);
		int nIndex = -1;
		int nSize = 0, i = 0,j;
		//得到fun+inf对应的nindex
		switch(datatype)
		{
		case dataYc:
			{
				YC_PARA para;
				for(i=0; i<pIED->m_IEDConfig.nYcNum; i++)

				{
					if(pIED->GetDataPara(dataYc,0,i, (void*)&para))
					{
						if(para.nFun == funInf.fun && para.nInfo == funInf.inf)
							nIndex = i;
					}
				}
			}
			break;
		case dataBhAc:
			{
				YC_PARA para;
				for(i=0; i<pIED->m_IEDConfig.nBhAcLoopNum; i++)

				{
					for(j=ac_Ia; j<ac_Sum; j++)
					{
						if(pIED->GetDataPara(dataBhAc,i, (eAcycItem)j,(void*)&para))
						{
							if(para.nFun == funInf.fun && para.nInfo == funInf.inf)
								nIndex = i*16 + j;
						}
					}
				}
			}
			break;
		case dataYx:
			{
				YX_PARA para;
				for(i=0; i<pIED->m_IEDConfig.nYxNum; i++)

				{
					if(pIED->GetDataPara(dataYx,0,i, (void*)&para))
					{
						if(para.nFun == funInf.fun && para.nInfo == funInf.inf)
							nIndex = i;
					}
				}
			}
			break;
		case dataBhYx:
			{
				YX_PARA para;
				for(i=0; i<pIED->m_IEDConfig.nBhNum; i++)

				{
					if(pIED->GetDataPara(dataBhYx,0,i, (void*)&para))
					{
						if(para.nFun == funInf.fun && para.nInfo == funInf.inf)
							nIndex = i;
					}
				}
			}
			break;
		case dataDd:
			{
				DD_PARA para;
				for(i=0; i<pIED->m_IEDConfig.nDdNum; i++)

				{
					if(pIED->GetDataPara(dataDd,0,i, (void*)&para))
					{
						if(para.nFun == funInf.fun && para.nInfo == funInf.inf)
							nIndex = i;
					}
				}
			}
			break;
		case dataYk:
			{
				YK_PARA para;
				for(i=0; i<pIED->m_IEDConfig.nYkNum; i++)

				{
					if(pIED->GetDataPara(dataYk,0,i, (void*)&para))
					{
						if(para.nFun == funInf.fun && para.nInfo == funInf.inf)
							nIndex = i;
					}
				}
			}
			break;
		case dataYt:
			break;
		case dataBhDz:
			break;
		default:
			break;
		}
		return nIndex;
	}

	//根据IED、数据类型和数据点号得到fun+inf
	BOOL CIEC103_SFPtl::GetFunInf(CIED *pIED, eDataSort datatype, INT nDataID, FunInf &funinf)
	{
		BOOL bRet = FALSE;
		switch(datatype)
		{
		case dataYk:
			{
				YK_PARA para;
				if(pIED->GetDataPara(dataYk,0,nDataID,(void*)&para))
				{
					funinf.fun = para.nFun;
					funinf.inf = para.nInfo;
					bRet = TRUE;
				}
			} 
			break;
		default:
			break;
		}
		return bRet;
	}

	//得到通用分类服务组个数和各个通用分类服务组号
	void CIEC103_SFPtl::GetGininf(CIED *pIED, TASK* pTask, eDataSort datatype, BYTE &byGrpnum, BYTE* pbyGrpID)
	{
		switch(datatype)
		{
		case dataBhAc:				//保护模拟量
			{
				byGrpnum = pTask->iUserData[0];			//得到要召唤的模拟量包含的通用分类服务组个数
				for(BYTE i=0; i<byGrpnum; i++)
					pbyGrpID[i] = pTask->iUserData[i+1];//把数据区中得通用分类组号考到pbyGrpID中
			}
			break;
		case dataSetting:
			{
				byGrpnum = pTask->iUserData[2];			//得到要召唤的定值组包含的通用分类服务组个数
				for(BYTE i=0; i<byGrpnum; i++)
					pbyGrpID[i] = pTask->iUserData[i+3];//把数据区中得通用分类组号考到pbyGrpID中
			}
			break;					//保护定值
		default:
			break;
		}
	}

	//得到定值组个数
	BYTE CIEC103_SFPtl::GetSettingGrpNum(CIED *pIED, TASK* pTask)
	{
		BYTE byNum = 0;
		byNum = pTask->iUserData[1];		//所有的定值组个数
		return byNum;
	}

	//得到保护定值组号gin
	//pTask->iUserData[0]:要设置的定值组号;pTask->iUserData[1]:组号; pTask->iUserData[2]:条目号
	void CIEC103_SFPtl::GetProtSetGrpGin(TASK* pTask, GIN &gin)
	{
		gin.group = pTask->iUserData[1];
		gin.entry = pTask->iUserData[2];
	}

	//得到保护复归fun+inf
	void CIEC103_SFPtl::GetProtResetFuninf(TASK* pTask, FunInf &funinf)
	{
		funinf.fun = pTask->iUserData[0];
		funinf.inf = pTask->iUserData[1];
	}

	//从规约参数中得到保护复归fun+inf以及地址
	BOOL CIEC103_SFPtl::GetProtResetFuninfFromPara(RealRunIED *pDevRun,FunInf &funinf,BYTE &addr)
	{
		USERPARA para;
		CIED *pIED = pDevRun->pDevData;
		if(!pIED)
			return FALSE;
		if(!pIED->GetDataPara(dataUserPara,0,0,(void*)&para))
			return FALSE;
		funinf.fun = para.wUPara0;		//FUN
		funinf.inf = para.wUPara1;		//INF
		addr = para.wUPara2;		//(选择)单元地址或者广播地址
		return TRUE;
	}
	//存储相应任务数据帧
	/*
	* 
	*=======================================================
	*	描述					偏移量				占位空间	
	*-------------------------------------------------------
	*	相应数据总长度			0~1				2
	*	**103数据帧总个数N		2~3				2
	*-------------------------------------------------------
	*	**103数据帧1总长度L1	4					1
	*	**103数据帧1			5~L1+5				L1
	*	**103数据帧2总长度L2	L1+6				1
	*	**103数据帧2			L1+7~L1+7+8 	L2
	*	**。。。	。。。	。。。
	*	**103数据帧2总长度LN 	X					1
	*	**103数据帧N			X~X+LN			LN
	*/
	BOOL CIEC103_SFPtl::SaveTaskRespFmt(BYTE* buf, WORD wLen, TASK* pTask)
	{
		if(!pTask->pbyBuff)
			return FALSE;
		BYTE *pbyData = pTask->pbyBuff;
		TaskRespHead *pRespHead = (TaskRespHead *)(pbyData);

		if(pTask->nDataBufLen == 0)
		{
			pRespHead->bufLen = 0;
			pRespHead->fmtNum = 0;
		}
		pRespHead->bufLen += (wLen + 1);
		pRespHead->fmtNum ++;

		*(pbyData + 4 + pTask->nDataBufLen) = lobyte(wLen);
		memcpy(pbyData + 4 + pTask->nDataBufLen + 1, buf, wLen);
		pTask->nDataBufLen += (wLen + 1);
		return TRUE;
	}

	//存储测控遥信
	void CIEC103_SFPtl::SaveCeKongYaoXin(RealRunIED *pRunIed, FunInf funInf,BYTE yxBit, TIME_4 tm)
	{
		eDataSort data;
		CIED *pIED = pRunIed->pDevData;
		int nIndex = GetnIndexbyFuninf(pIED, dataYx, funInf);//先取实遥信的索引;
		data = dataYx;
		if(nIndex == -1)
		{
			nIndex = GetnIndexbyFuninf(pIED, dataBhYx, funInf);//取保护虚遥信索引
			data = dataBhYx;
		}
		if (nIndex >= 0)
		{
			BYTE byYXRecvVal = pIED->GetDataRecvVal(data,0,nIndex);
			if(byYXRecvVal != yxBit)
			{
				//设置遥信值
				pIED->SetDataRecvVal(data,0,nIndex,yxBit);
				// 事项存储
				EVENT_STRUCT bhent;
				TIME_STRUCT sysTime;
				g_pMainApp->GetSystime(&sysTime);

				bhent.eDS		 = (eDataSource)m_pCH->m_ChConfig.eDS;	// 数据源
				bhent.eEventType = data;					// 事项类型(开关类)
				bhent.nEventNode = nIndex;					// 事项点

				bhent.nEventVal  = 0x10;					// 事项值
				if(yxBit == 1)
					bhent.nEventVal = 0x01;
				bhent.nNode      = pIED->m_IEDConfig.byNodeID;// 设备节点
				WB_UNION wb;
				wb.bwUnion.byVal[1] = tm.byLowMs;
				wb.bwUnion.byVal[0] = tm.byHighMs;
				bhent.TimeStamp.nMs = wb.bwUnion.wVal % 1000;
				bhent.TimeStamp.bySecond = wb.bwUnion.wVal / 1000;
				bhent.TimeStamp.byMinute = tm.Minutes;
				bhent.TimeStamp.byHour	 = tm.Hours;
				bhent.TimeStamp.byDay   = sysTime.byDay;
				bhent.TimeStamp.byMonth  = sysTime.byMonth;
				bhent.TimeStamp.nYear    = sysTime.nYear;

				//m_pCH->m_pYxbwSoeQue->Add(bhent);
				m_pCH->m_pYxSoeQue->Add(bhent);	
			}
		}
	}

	void CIEC103_SFPtl::SaveCeKongYaoXin(RealRunIED *pRunIed, FunInf funInf,BYTE yxBit)
	{
		//int iCnt = 1; printf("已经进入SaveCeKongYaoXin函数:%d\n",iCnt);
		eDataSort data;
		CIED *pIED = pRunIed->pDevData;
		int nIndex = GetnIndexbyFuninf(pIED, dataYx, funInf);//先取实遥信的索引;
		//printf("nIndex = %d\n",nIndex);
		data = dataYx;
		if(nIndex == -1)
		{
			nIndex = GetnIndexbyFuninf(pIED, dataBhYx, funInf);//取保护虚遥信索引
			data = dataBhYx;
		}
		if (nIndex >= 0)
		{
			BYTE byYXRecvVal = pIED->GetDataRecvVal(data,0,nIndex);
			if(byYXRecvVal != yxBit)
			{
				//设置遥信值
				pIED->SetDataRecvVal(data,0,nIndex,yxBit);
				// 事项存储
				EVENT_STRUCT bhent;
				TIME_STRUCT sysTime;
				g_pMainApp->GetSystime(&sysTime);

				bhent.eDS		 = (eDataSource)m_pCH->m_ChConfig.eDS;	// 数据源
				bhent.eEventType = data;					// 事项类型(开关类)
				bhent.nEventNode = nIndex;					// 事项点

				bhent.nEventVal  = 0x10;					// 事项值
				if(yxBit == 1)
					bhent.nEventVal = 0x01;
				bhent.nNode      = pIED->m_IEDConfig.byNodeID;// 设备节点
				bhent.TimeStamp.nMs		 = sysTime.nMs;
				bhent.TimeStamp.bySecond = sysTime.bySecond;
				bhent.TimeStamp.byMinute = sysTime.byMinute;
				bhent.TimeStamp.byHour	 = sysTime.byHour;
				bhent.TimeStamp.byDay	 = sysTime.byDay;
				bhent.TimeStamp.byMonth  = sysTime.byMonth;
				bhent.TimeStamp.nYear    = sysTime.nYear;

				//	m_pCH->m_pYxbwSoeQue->Add(bhent);
				//	m_pCH->m_pYxSoeQue->Add(bhent);	
			}
		}
	}

	//波特率
	DWORD CIEC103_SFPtl::GetChRatio(void)
	{
		DWORD dwRate = m_pCH->m_ChConfig.dwBaudRate;
		DWORD dwVal = 1200;

		if (110 == dwRate)
			dwVal = 110;
		else if (300 == dwRate)
			dwVal = 300;
		else if (600 == dwRate)
			dwVal = 600;
		else if (1200 == dwRate)
			dwVal = 1200;
		else if (2400 == dwRate)
			dwVal = 2400;
		else if (4800 == dwRate)
			dwVal = 4800;
		else if (9600 == dwRate)
			dwVal = 9600;
		else if (14400 == dwRate)
			dwVal = 14400;
		else if (19200 == dwRate)
			dwVal = 19200;
		else if (38400 == dwRate)
			dwVal = 38400;
		else if (56000 == dwRate)
			dwVal = 56000;
		else if (57600 == dwRate)
			dwVal = 57600;
		else if (115200 == dwRate)
			dwVal = 115200;
		else if (128000 == dwRate)
			dwVal = 128000;
		else if (256000 == dwRate)
			dwVal = 256000;

		return dwVal;
	}

	//参数转换函数,从flash参数转换为规约参数
	void CIEC103_SFPtl::FlashParaToPtlPara(FlashPara103 * pPara)
	{
		//先调用默认参数
		DafaultPtlPara();
		// 保护遥信复归
		if(pPara->bOrdAfmReset > 0)
			m_IEC103PtlPara.bOrdAfmReset = 1;				// 确认复归(复归命令肯定确认时,保护信号复归)
		if(pPara->bOrderReset > 0)
			m_IEC103PtlPara.bOrderReset = 1;				// 命令复归(复归命令毋须确认,保护信号即可复归)

		if(pPara->bEventVirtualYX > 0)
			m_IEC103PtlPara.bEventVirtualYX = 1;			// 故障事项虚遥信

		// 通用参数	
		if(pPara->byInitNum > 0)
			m_IEC103PtlPara.byInitNum = pPara->byInitNum;	// 初始化重传次数
		if(pPara->dwFrameOver > 0)
			m_IEC103PtlPara.dwFrameOver = pPara->dwFrameOver;	// 帧超时间隔,ms

		if(pPara->dwQuery > 0)
			m_IEC103PtlPara.dwQuery = pPara->dwQuery;		// 总查询间隔,s
		if(pPara->wTimeOver > 0)
			m_IEC103PtlPara.wTimeOver = pPara->wTimeOver;	// 校时间隔

		if(pPara->bCommAddr > 0 || pPara->bCommAddr == 0)
			m_IEC103PtlPara.bCommAddr = pPara->bCommAddr;

		if(pPara->byBHCPUAddr > 0)
			m_IEC103PtlPara.byBHCPUAddr = pPara->byBHCPUAddr;
		if(pPara->byCKCPUAddr > 0)
			m_IEC103PtlPara.byCKCPUAddr = pPara->byCKCPUAddr;
		if (pPara->bGenSelect > 0)
			m_IEC103PtlPara.bGenSel = pPara->bGenSelect;
		//if(pPara->byBhResetFun > 0)
		//	m_IEC103PtlPara.byBhResetFun = pPara->byBhResetFun;
		//if(pPara->byBhResetInf > 0)
		//	m_IEC103PtlPara.byBhResetInf = pPara->byBhResetInf;
	}

	//规约默认参数设置

⌨️ 快捷键说明

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