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

📄 iec103_xuji.cpp

📁 许继公司103规约源码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
				//m_pCH->m_pTaskQue->LockTask();
				break;
			case taskChThree:	
				{// 通道任务
					bRtn = ChanTask(pTask, pDevRun);
				//	if(bRtn)
				//		m_pCH->m_pTaskQue->LockTask();
				}
				break;
			default:	// 其他类型任务不支持
				pTask->eStatus = tsNull;
				break;
		}
		if (!bRtn && tsNull != pTask->eStatus)
		{
			// 召唤1级数据
			BYTE byCode = CallClass2_code;
			if (pDevRun->acd) 
				byCode = CallClass1_code;

			PackLPDU_Fix(pTask->byDestNodeID, byCode);
			bRtn = TRUE;
		}
	}
	return bRtn;
}

// 通道任务 - 校时
BOOL CIEC103_XUJIPtl::SendAdjustTime103(TASK* pTask)
{
	ASDU_6_Fmt *pFmt = (ASDU_6_Fmt *)(m_IEC103Data.m_bySend + sizeof(LPDU_Vol_Head));
	memset(pFmt, 0, sizeof(ASDU_6_Fmt));
	pFmt->head.type = 6;
	pFmt->head.vsq.vsq = 0x81;
	pFmt->head.cot = 8;
	pFmt->head.addr = 0xff;
	pFmt->head.fun = 0xff;
	pFmt->head.inf = 0;

	TIME_STRUCT st;
	g_pMainApp->GetSystime(&st);
	pFmt->dataTime.year = st.nYear % 100;
	pFmt->dataTime.month = st.byMonth;
	pFmt->dataTime.bay = st.byDay;
	pFmt->dataTime.week = 0;
	pFmt->dataTime.time.Hours = st.byHour;
	pFmt->dataTime.time.Minutes = st.byMinute;
	WORD wtmp = st.bySecond * 1000 + st.nMs;
	pFmt->dataTime.time.byLowMs = lobyte(wtmp);
	pFmt->dataTime.time.byHighMs = hibyte(wtmp);

	LPDU_Vol_Head *pHead = (LPDU_Vol_Head *)m_IEC103Data.m_bySend;
	memset(pHead, 0, sizeof(LPDU_Vol_Head));
	pHead->head1 = pHead->head2 = 0x68;
	pHead->len1 = pHead->len2 = ASDU6Fmt_LEN + 2;
	pHead->ctrl.funcode = NoReply_code;
	pHead->ctrl.prm = 1;
	pHead->addr = 0xff;

	m_IEC103Data.m_wSendNum = sizeof(LPDU_Vol_Head) + ASDU6Fmt_LEN;
	m_IEC103Data.m_bySend[m_IEC103Data.m_wSendNum ++] = SumMod(m_IEC103Data.m_bySend + 4, pHead->len1);
	m_IEC103Data.m_bySend[m_IEC103Data.m_wSendNum ++] = 0x16;

	pTask->eStatus = tsSuccess;
	return TRUE;
}

BOOL CIEC103_XUJIPtl::SendAdjustTime103(BYTE byaddr)
{
	ASDU_6_Fmt *pFmt = (ASDU_6_Fmt *)(m_IEC103Data.m_bySend + sizeof(LPDU_Vol_Head));
	memset(pFmt, 0, sizeof(ASDU_6_Fmt));
	pFmt->head.type = 6;
	pFmt->head.vsq.vsq = 0x81;
	pFmt->head.cot = 8;
	pFmt->head.addr = byaddr;
	pFmt->head.fun = 0xff;
	pFmt->head.inf = 0;

	TIME_STRUCT st;
	g_pMainApp->GetSystime(&st);
	pFmt->dataTime.year = st.nYear % 100;
	pFmt->dataTime.month = st.byMonth;
	pFmt->dataTime.bay = st.byDay;
	pFmt->dataTime.week = 0;
	pFmt->dataTime.time.Hours = st.byHour;
	pFmt->dataTime.time.Minutes = st.byMinute;
	WORD wtmp = st.bySecond * 1000 + st.nMs;
	pFmt->dataTime.time.byLowMs = lobyte(wtmp);
	pFmt->dataTime.time.byHighMs = hibyte(wtmp);

	LPDU_Vol_Head *pHead = (LPDU_Vol_Head *)m_IEC103Data.m_bySend;
	memset(pHead, 0, sizeof(LPDU_Vol_Head));
	pHead->head1 = pHead->head2 = 0x68;
	pHead->len1 = pHead->len2 = ASDU6Fmt_LEN + 2;

	if(byaddr == 0xff)
		pHead->ctrl.funcode = NoReply_code;
	else
		pHead->ctrl.funcode = SendCon_code;

	pHead->ctrl.prm = 1;
	pHead->addr = byaddr;

	m_IEC103Data.m_wSendNum = sizeof(LPDU_Vol_Head) + ASDU6Fmt_LEN;
	m_IEC103Data.m_bySend[m_IEC103Data.m_wSendNum ++] = SumMod(m_IEC103Data.m_bySend + 4, pHead->len1);
	m_IEC103Data.m_bySend[m_IEC103Data.m_wSendNum ++] = 0x16;

	return TRUE;
}

//遥控命令组帧
BOOL CIEC103_XUJIPtl::PackYaoKong(TASK *pTask, RealRunIED *pDevRun)
{
	Task103& task = m_IEC103Data.m_task103;
	YK_COMMAND* pYkCom = (YK_COMMAND *)(pTask->iUserData);
	if(!pYkCom || !pDevRun)
		return FALSE;

	CIED *pIED = pDevRun->pDevData;
	if(!pIED)
		return FALSE;

	BOOL bChk = FALSE;
	if (0 == task.wStep) 
	{
		task.wStep ++;

		FunInf funInf;
		if(!GetFunInf(pDevRun->pDevData, dataYk, pYkCom->byYkNode, funInf))// 遥控命令fun+inf
			return FALSE;

		YK_PARA para;
		if(!pIED->GetDataPara(dataYk,0,pYkCom->byYkNode,(void*)&para))
			return FALSE;

		DCC dcc = {0};
		switch(pTask->eTaskType)
		{
			case taskCmdYkSelect:			  //遥控选择
				dcc.se = 1;
				if(pYkCom->byAction == yk_PrevH)
				{
					dcc.dcs = 2;
					bChk = TRUE;
				}else if(pYkCom->byAction == yk_PrevF)
				{
					dcc.dcs = 1;
					bChk = TRUE;
				}
				break;

			case taskCmdYkExecute:			   //遥控执行
				if (pYkCom->byAction == yk_exec )
				{
					dcc.dcs = (m_IEC103Data.m_OldCmd.dcc).dcs; // 动作类型
					bChk = TRUE;
				}
				break;

			case taskCmdYkCancel:			  //遥控撤销
				if (pYkCom->byAction == yk_cancel) {
					dcc.dcs = (m_IEC103Data.m_OldCmd.dcc).dcs; // 动作类型描述
					dcc.se = 1;
					dcc.act = 1;
					bChk = TRUE;
				}
				break;

			default:
				break;
		}
		if (!bChk)
			return bChk;

		// 记录动作类型描述
		m_IEC103Data.m_OldCmd.dcc = dcc;

		// 组帧
		ASDU_64_Fmt *pFmt = (ASDU_64_Fmt *)(m_IEC103Data.m_bySend + sizeof(LPDU_Vol_Head));
		pFmt->head.type = 64;
		pFmt->head.vsq.vsq = 0x81;
		pFmt->head.cot = 12;
		pFmt->head.addr = para.nReserved0;//分cpu地址号
		pFmt->head.funInf = funInf;
		pFmt->dcc = dcc;
		pFmt->rii = m_IEC103Data.m_bySin ++;

		m_IEC103Data.m_wSendNum = sizeof(ASDU_64_Fmt);
		PackLPDU(pTask->byDestNodeID, SendCon_code);
	}
	return bChk;
}

//召唤保护模拟量
//召唤保护模拟量,pTask->iUserData数组中填放数据说明
//   0						1.....		
// 要召唤模拟量组包含的		通用分类组号	
//	通用分类组个数
BOOL CIEC103_XUJIPtl::PackCallProtMea(TASK *pTask, RealRunIED *pDevRun)
{
	Task103 &task = m_IEC103Data.m_task103;
	GenerReadDesc &genRead = task.genRead;

	if (0 == task.wStep) 
	{	
		// 没有保护模拟量,则不进行组帧命令
		if(pDevRun->pDevData->m_IEDConfig.nBhAcLoopNum <= 0)
		{
			return FALSE;
		}

	//	InitTaskRespBuf(pTask);

		genRead.grpCnt = 0;
		GetGininf(pDevRun->pDevData, pTask, dataBhAc, genRead.grpNum, genRead.readGrp);
	}
	
	return PackGenerReadCmd(pTask, pDevRun);
}

//召唤保护定值
//召唤保护定值,pTask->iUserData数组中填放数据说明
//   0				1				2					3.....
//召唤定值组号	定值组总个数  要召唤定值组包含的	通用分类组号	
//								通用分类组个数
BOOL CIEC103_XUJIPtl::PackCallProtSetting(TASK *pTask, RealRunIED *pDevRun)
{
	Task103 &task = m_IEC103Data.m_task103;
	GenerReadDesc &genRead = task.genRead;

	if (0 == task.wStep)
	{
		BYTE byReadID = pTask->iUserData[0];		//得到要召唤的定值组号
		BOOL bChk = FALSE;
		if (pDevRun->pDevData->m_IEDConfig.nDzNum > 0)
		{
			// 召唤的定值组号
			if (0xff == pTask->iUserData[0])	
				byReadID = 0;

			BYTE bySettingGrpNum = GetSettingGrpNum(pDevRun->pDevData, pTask);
			if (byReadID < bySettingGrpNum)
			{
				//InitTaskRespBuf(pTask);
				genRead.grpCnt = 0;
				GetGininf(pDevRun->pDevData, pTask, dataSetting, genRead.grpNum, genRead.readGrp);
				bChk = TRUE;
			}
		}
		if (!bChk) 
			return FALSE;
	}
	return PackGenerReadCmd(pTask, pDevRun);
}
//修改保护定值
/*
*PackModifyProtSetting - 修改保护定值组帧
* 固定格式
*	描述					偏移量				占位空间	
*-------------------------------------------------------
*	相应数据总长度			0~1				2
*	**103数据帧总个数N		2~3				2
*/
BOOL CIEC103_XUJIPtl::PackModifyProtSetting(TASK *pTask, RealRunIED *pDevRun)
{
	Task103 &task = m_IEC103Data.m_task103;
	GenerWriteDesc &genWrite = task.genWrite;

	//BYTE byAddr = pDevRun->pDevData->m_IEDConfig.byNodeAddr;
	BYTE byAddr = 0;
	if(m_IEC103PtlPara.bCommAddr)
		byAddr = m_IEC103PtlPara.byBHCPUAddr;
	else
		byAddr = pDevRun->pDevData->m_IEDConfig.byNodeAddr;

	if(!pTask->bWithDataF || pTask->pbyBuff == NULL)//没有用户附加数据,直接返回
		return FALSE;
	ModifyProtSettingHead *pProtSetHead = (ModifyProtSettingHead *)(pTask->pbyBuff);
	BYTE  byLinkLen = 0;
	if (0 == task.wStep) 
	{
		genWrite.wSendFmtCnt = 0;
		genWrite.wSendPos = 4;
		genWrite.rii = m_IEC103Data.m_bySin ++;

		// 去除第一组的定值组号
		byLinkLen = *(pTask->pbyBuff + genWrite.wSendPos);
		genWrite.wSendPos += 1;
		genWrite.wSendFmtCnt ++;
	}

	if (task.wStep % 2 == 0) 
	{		
		if(task.wStep != 0)
		{
			byLinkLen = *(pTask->pbyBuff + genWrite.wSendPos);
			genWrite.wSendPos += 1;
			genWrite.wSendFmtCnt ++;
		}
		memcpy(m_IEC103Data.m_bySend, pTask->pbyBuff + genWrite.wSendPos, byLinkLen);
		genWrite.wSendPos += byLinkLen;

		task.wStep ++;

		ASDU_10_Head *pFmtHead = (ASDU_10_Head *)(m_IEC103Data.m_bySend + sizeof(LPDU_Vol_Head));
		pFmtHead->head.type = 10;
		pFmtHead->head.vsq.vsq = 0x81;
		pFmtHead->head.cot = 40;
		pFmtHead->head.addr = byAddr;
		pFmtHead->head.fun = 254;
		pFmtHead->head.inf = (genWrite.wSendFmtCnt == pProtSetHead->fmtNum) ?250 : 249;
		pFmtHead->rii = genWrite.rii;
		pFmtHead->ngd.count = (task.wStep / 2) % 2;
		pFmtHead->ngd.cont = (genWrite.wSendFmtCnt != pProtSetHead->fmtNum);

		m_IEC103Data.m_wSendNum = byLinkLen - 8;
		PackLPDU(pTask->byDestNodeID, SendCon_code);

		return TRUE;
	}

	return FALSE;
}

//确认保护定值
BOOL CIEC103_XUJIPtl::PackEnableProtSetting(TASK *pTask, RealRunIED *pDevRun)
{
	return PackGenerExec(pTask, pDevRun, TRUE);
}

//取消修改保护定值
BOOL CIEC103_XUJIPtl::PackCancelProtSetting(TASK *pTask, RealRunIED *pDevRun)
{
	return PackGenerExec(pTask, pDevRun, FALSE);
}

//设置保护定值组
BOOL CIEC103_XUJIPtl::PackModifyProtSettingGroup(TASK *pTask, RealRunIED *pDevRun)
{
	//BYTE byAdd = pDevRun->pDevData->m_IEDConfig.byNodeAddr;
	BYTE byAddr = 0;
	if(m_IEC103PtlPara.bCommAddr)
		byAddr = m_IEC103PtlPara.byBHCPUAddr;
	else
		byAddr = pDevRun->pDevData->m_IEDConfig.byNodeAddr;

	Task103 &task = m_IEC103Data.m_task103;
	if (0 == task.wStep)
	{
		task.wStep ++;

		ASDU_10_Head *pHead = (ASDU_10_Head *)(m_IEC103Data.m_bySend + sizeof(LPDU_Vol_Head));
		pHead->head.type = 10;
		pHead->head.vsq.vsq = 0x81;
		pHead->head.cot = 40;
		pHead->head.addr = byAddr;
		pHead->head.fun = 254;
		pHead->head.inf = 249;
		pHead->rii = m_IEC103Data.m_bySin ++;
		pHead->ngd.cont = pHead->ngd.count = 0;
		pHead->ngd.num = 1;
		
		ASDU_10_Item *pItem = (ASDU_10_Item *)(pHead + 1);
		GIN gin;
		GetProtSetGrpGin(pTask, gin);
		pItem->gin = gin;
		pItem->gdd.byDataTyp = 3;
		pItem->gdd.byDataSize = 1;
		pItem->gdd.num = 1;
		pItem->gdd.cont = 0;
		pItem->kod = 1;
		pItem->byVal = pTask->iUserData[0];

		m_IEC103Data.m_wSendNum = sizeof(ASDU_10_Head) + sizeof(ASDU_10_Item);
		PackLPDU(pTask->byDestNodeID, SendCon_code);
		return TRUE;		
	}
	
	return FALSE;
}

//确认设置的保护定值组
BOOL CIEC103_XUJIPtl::PackEnableProtSettingGroup(TASK *pTask, RealRunIED *pDevRun)
{
	return PackGenerExec(pTask, pDevRun, TRUE);
}

//取消修改保护定值组
BOOL CIEC103_XUJIPtl::PackCancelProtSettingGroup(TASK *pTask, RealRunIED *pDevRun)
{
	return PackGenerExec(pTask, pDevRun, FALSE);
}

// 保护复归
BOOL CIEC103_XUJIPtl::PackProtRes(TASK *pTask, RealRunIED *pDevRun)
{
	BYTE byAdd = pDevRun->pDevData->m_IEDConfig.byNodeAddr;

	BOOL bRtn = FALSE;
	Task103 &task = m_IEC103Data.m_task103;
	if (0 == task.wStep) 
	{
		ASDU_20_Fmt *pFmt = (ASDU_20_Fmt *)(m_IEC103Data.m_bySend + sizeof(LPDU_Vol_Head));
		pFmt->head.type = 20;
		pFmt->head.vsq.vsq = 0x81;
		pFmt->head.cot =  20;
		
		FunInf funinf;
		BYTE bycpuaddr;
		if(!GetProtResetFuninfFromPara(pDevRun,funinf,bycpuaddr))
			return FALSE;
		pFmt->head.addr = bycpuaddr;
		pFmt->head.funInf = funinf;
		pFmt->dco = Off_dco;
		pFmt->rii = m_IEC103Data.m_bySin ++;

		m_IEC103Data.m_wSendNum = sizeof(ASDU_20_Fmt);
		PackLPDU(pTask->byDestNodeID, SendCon_code);

		task.wStep ++;
		bRtn = TRUE;
		ResetBhYx(pTask,pDevRun);
	}

	return bRtn;
}

//对保护装置虚摇信信号进行复归
void CIEC103_XUJIPtl::ResetBhYx(TASK *pTask, RealRunIED *pDevRun)
{
	CIED *pIED = pDevRun->pDevData;
	int nBhYxNum = pIED->m_IEDConfig.nBhNum;
	for(int i=0; i<nBhYxNum; i++)
	{
		pIED->SetDataRecvVal(dataBhYx,0,i,0);
	}
}

// 通道任务
//任务区结构描述
//---------------------------------
// 总长度		0~1			2
// 帧个数		2~3			2
// 第1帧长度	4			1
// 第1帧		5			L+5
BOOL CIEC103_XUJIPtl::ChanTask(TASK *pTask, RealRunIED *pDevRun)
{
	Task103 &task = m_IEC103Data.m_task103;
	GenerWriteDesc &genWrite = task.genWrite;
	
	BYTE *pbyData = pTask->pbyBuff;
	if(!pTask->bWithDataF || pbyData == NULL)//没有附加数据
		return FALSE;
	
	WORD *pwLen = (WORD *)pbyData;
	WORD *pwFmtCnt = (WORD *)(pbyData + 2);
	genWrite.wSendNum = *(WORD *)(pbyData + 2);

	BYTE byAsduLen = 0;
	ASDU_Head *pHead = NULL;
	if (0 == task.wStep)
	{
		genWrite.wSendFmtCnt = 0;
		genWrite.wSendPos = 4;
		genWrite.rii = m_IEC103Data.m_bySin ++;

		byAsduLen = pbyData[genWrite.wSendPos];
		genWrite.wSendPos++;
		genWrite.wSendFmtCnt++;
		pHead = (ASDU_Head *)(pbyData + genWrite.wSendPos);
		// 复归命令
		if (C_GRC_NA_3 == pHead->type) 
		{	
			//task.pTask->status = timeOut;
		}
		else if (10 == pHead->type || 21 == pHead->type)
			;//InitTaskRespBuf(pTask);
	}

	if (task.wStep % 2 == 0)
	{
		// 链路数据
		if(task.wStep != 0)
		{
			byAsduLen = pbyData[genWrite.wSendPos];
			genWrite.wSendPos++;
			genWrite.wSendFmtCnt++;
			pHead = (ASDU_Head *)(pbyData + genWrite.wSendPos);

⌨️ 快捷键说明

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