?? iec103_sf.cpp
字號(hào):
void CIEC103_SFPtl::DafaultPtlPara(void)
{
// 保護(hù)遙信復(fù)歸
m_IEC103PtlPara.bOrdAfmReset = 0; // 確認(rèn)復(fù)歸(復(fù)歸命令肯定確認(rèn)時(shí),保護(hù)信號(hào)復(fù)歸)
m_IEC103PtlPara.bOrderReset = 0; // 命令復(fù)歸(復(fù)歸命令毋須確認(rèn),保護(hù)信號(hào)即可復(fù)歸)
// 信息存儲(chǔ)
m_IEC103PtlPara.bEventVirtualYX = 0; // 故障事項(xiàng)虛遙信
// 通用參數(shù)
m_IEC103PtlPara.byInitNum = 1; // 初始化重傳次數(shù)
m_IEC103PtlPara.dwFrameOver = 2000; // 幀超時(shí)間隔,ms
m_IEC103PtlPara.dwQuery = 180; // 總查詢間隔,s
m_IEC103PtlPara.wTimeOver = 600; // 校時(shí)間隔,s
m_IEC103PtlPara.bCommAddr = 1; // 默認(rèn)為1,才有cpu地址,否則為單元地址(即鏈路層地址)
m_IEC103PtlPara.byBHCPUAddr = 1; // 保護(hù)cpu地址,默認(rèn)為1
m_IEC103PtlPara.byCKCPUAddr = 2; // 測(cè)控cpu地址,默認(rèn)為2
m_IEC103PtlPara.bGenSel = 1;
//m_IEC103PtlPara.byBhResetFun = 0;
//m_IEC103PtlPara.byBhResetInf = 0;
}
//通道任務(wù)監(jiān)視函數(shù)
BOOL CIEC103_SFPtl::WatchTask(TASK* &ptask, eTaskTyp tasktyp, BYTE byNodeID)
{
ptask = m_pCH->GetWaitingTask(tasktyp, byNodeID);
if (ptask)
return TRUE;
return FALSE;
}
//規(guī)約初始化
void CIEC103_SFPtl::InitPtl(void)
{
int i;
FlashPara103 * pflashpara = NULL;
pflashpara = (FlashPara103*)(m_pCH->m_PtlPara);
if(pflashpara)
FlashParaToPtlPara(pflashpara);
else
DafaultPtlPara();
m_pCH->m_ChConfig.byPtlKind=0;
m_ePtlType = ptlSIFANG103;
for(i=0; i<m_pCH->m_ChConfig.byIEDNum; i++)
{
CIED *pIED = m_pCH->m_pIED[i];
if(pIED == NULL)
continue;
CreateRealRunIED(pIED);
m_IEC103Data.m_addrtoID[pIED->m_IEDConfig.byNodeAddr] = pIED->m_IEDConfig.byNodeID;
}
// 規(guī)約運(yùn)行步驟
m_IEC103Data.m_runStep = PtlRun_PackASDU;
m_IEC103Data.m_byCycCnt = 0;
// 規(guī)約任務(wù)區(qū)
memset(&m_IEC103Data.m_task103, 0, sizeof(m_IEC103Data.m_task103));
// 服務(wù)原語
memset(&m_IEC103Data.m_prmSend, 0, sizeof(CommPrim));
memset(&m_IEC103Data.m_prmRecv, 0, sizeof(CommPrim));
// 收發(fā)緩沖區(qū)
m_IEC103Data.m_wLinkLen = 0;
m_IEC103Data.m_wSendNum = 0;
// 計(jì)時(shí)器初始化
DWORD dwRatio = GetChRatio();
DWORD dwDly = (3*11*1000 + dwRatio-1) / dwRatio;
// 幀超時(shí)時(shí)間
m_IEC103Data.m_frmOver.SetWaitSpan(m_IEC103PtlPara.dwFrameOver);
// 幀間隔時(shí)間
m_IEC103Data.m_frmDly33.SetWaitSpan(dwDly*300);
// 總召喚間隔
m_IEC103Data.m_queryCnt.SetWaitSpan((m_IEC103PtlPara.dwQuery/2) * 1000);
m_IEC103Data.m_queryCnt.Start(m_nCnt);
//校時(shí)間隔
m_IEC103Data.m_timeover.SetWaitSpan(m_IEC103PtlPara.wTimeOver * 1000);
m_IEC103Data.m_timeover.Start(m_nCnt);
// 通道無數(shù)據(jù)接收監(jiān)視,
m_IEC103Data.m_lnkSerialError = 0;
m_IEC103Data.m_bySendCnt = 0;
m_IEC103Data.m_bySin = 0;
memset(&m_IEC103Data.m_OldCmd, 0, sizeof(m_IEC103Data.m_OldCmd));
QueryRecvLPDU();
m_nCnt = 0;
SetTimer(2);
m_bAdjustTime = false;
}
void CIEC103_SFPtl::OnTimer(void)
{
m_nCnt++;
}
//組幀函數(shù)
INT CIEC103_SFPtl::Frame(BYTE* pSendBuf, INT nLen)
{
INT nret = 0;
// 總召喚/召喚脈沖計(jì)數(shù)定時(shí)到
if (m_IEC103Data.m_queryCnt.IsOverTime(m_nCnt))//調(diào)試1000
{
m_IEC103Data.m_queryCnt.Start(m_nCnt);
for (int i = 0; i < CH_MAX_IED_NUM; i++)
{
RealRunIED *pRunIED = m_IEC103Data.m_RunIed[i];
if(pRunIED)
{
pRunIED->queryFull ^= 1; // 查詢標(biāo)志取反
pRunIED->query = 1;
}
}
}
/*應(yīng)用層組幀
* 1) 發(fā)送通道任務(wù)命令
* 2) 發(fā)送普通的循環(huán)任務(wù)
*/
if (PtlRun_PackASDU == m_IEC103Data.m_runStep)
{
// 要求進(jìn)行組幀處理
m_IEC103Data.m_wSendNum = 0;
m_IEC103Data.m_wLinkLen = 0;
// 初始化服務(wù)原語
memset(&m_IEC103Data.m_prmSend, 0, sizeof(CommPrim));
memset(&m_IEC103Data.m_prmRecv, 0, sizeof(CommPrim));
// 通道任務(wù)檢測(cè)
if (!PackTask()) //無任務(wù)時(shí),則執(zhí)行PackCyc();若有任務(wù),則先執(zhí)行任務(wù)
{
PackCyc(); // 循環(huán)查詢?nèi)蝿?wù)
}
// 轉(zhuǎn)入鏈路幀發(fā)送過程
m_IEC103Data.m_bySendCnt = 0;
if (m_IEC103Data.m_wSendNum > 0)
m_IEC103Data.m_runStep = PtlRun_SendLPDU;
}
// 輔機(jī)直接轉(zhuǎn)入鏈路接收過程中
/*if (!lpCh->m_pDevDB->GetCcsModule( ))
{
pPtlData->m_runStep = PtlRun_RecvLPDU;
QueryRecvLPDU(lpCh);
}*/
// 等待鏈路接收
if (PtlRun_RecvLPDU == m_IEC103Data.m_runStep)
{
if (m_IEC103Data.m_frmOver.IsOverTime(m_nCnt))
{
m_IEC103Data.m_bySendCnt ++;
if (m_IEC103Data.m_bySendCnt > 2)
{
NoLPDU();
m_IEC103Data.m_runStep = PtlRun_PackASDU;
}
else
m_IEC103Data.m_runStep = PtlRun_SendLPDU;
}
}
// 鏈路層發(fā)送
if (PtlRun_SendLPDU == m_IEC103Data.m_runStep)
{
// 主機(jī)發(fā)送數(shù)據(jù),輔機(jī)僅接收數(shù)據(jù)
//if (lpCh->m_pDevDB->GetCcsModule( ))
//{
// 等待超時(shí)監(jiān)視
if(m_bAdjustTime)
{
m_bAdjustTime = false;
m_IEC103Data.m_runStep = PtlRun_PackASDU;
nret = m_IEC103Data.m_wSendNum;
}
else
nret = PtlSendLPDU();
memcpy(pSendBuf, m_IEC103Data.m_bySend, nret);
//}
}
return nret;
}
// 鏈路層傳輸服務(wù)
// 1. 站初始化
// 2. 鏈路狀態(tài)控制
BOOL CIEC103_SFPtl::PackLinkCmm(BYTE byNodeID)
{
RealRunIED *pDevRun = m_IEC103Data.m_RunIed[byNodeID];
if(!pDevRun)
return FALSE;
if (!pDevRun->linkQuery && !pDevRun->linkRes)
return FALSE;
if (pDevRun->linkRes)
{
PackLPDU_Fix(byNodeID, ResCU_code);
pDevRun->bCommInitFlag = TRUE;
pDevRun->nASDU5Cnt = 0;
pDevRun->step = eInitStart;
}
else if (pDevRun->linkQuery)
{ // 鏈路狀態(tài)
PackLPDU_Fix(byNodeID, QueryLink_code);
}
return TRUE;
}
// 固定幀長(zhǎng)鏈路數(shù)據(jù)組幀
void CIEC103_SFPtl::PackLPDU_Fix(BYTE byNodeID, BYTE byCode)
{
// if(m_IEC103Data.m_frmOver.IsOverTime(m_nCnt))
{
PackLPDU(byNodeID, byCode);
}
}
void CIEC103_SFPtl::PackLPDU(BYTE byNodeID, BYTE code)
{
RealRunIED *pDevRun = m_IEC103Data.m_RunIed[byNodeID];
if(!pDevRun)
return;
LinkCtrl linkCtrl;
linkCtrl.funcode = code;
linkCtrl.res = 0;
linkCtrl.prm = 1;
switch(code)
{
case ResCU_code:
case ResFcb_code:
m_IEC103Data.m_lnkSvrCls = SendConfirm;
linkCtrl.fcvDfc = 0;
break;
case NoReply_code:
m_IEC103Data.m_lnkSvrCls = SendNoreply;
linkCtrl.fcvDfc = 0;
break;
case QueryLink_code:
m_IEC103Data.m_lnkSvrCls = RequestRespond;
linkCtrl.fcvDfc = 0;
break;
case SendCon_code:
m_IEC103Data.m_lnkSvrCls = SendConfirm;
linkCtrl.fcvDfc = 1;
break;
case CallClass1_code:
case CallClass2_code:
m_IEC103Data.m_lnkSvrCls = RequestRespond;
linkCtrl.fcvDfc = 1;
break;
default:
break;
}
// 鏈路幀控制字
linkCtrl.fcbAcd = 0;
if (linkCtrl.fcvDfc)
{
pDevRun->fcb = ~pDevRun->fcb;
linkCtrl.fcbAcd = pDevRun->fcb;
}
if (0 == m_IEC103Data.m_wSendNum)
{ // 固定幀長(zhǎng)
LPDU_Fix_Fmt *pFmt = (LPDU_Fix_Fmt *)(m_IEC103Data.m_bySend);
pFmt->head = 0x10;
pFmt->ctrl = linkCtrl;
pFmt->addr = pDevRun->pDevData->m_IEDConfig.byNodeAddr;
pFmt->sum = pFmt->ctrl.lnkCtrl + pFmt->addr;
pFmt->tail = 0x16;
m_IEC103Data.m_wSendNum = sizeof(LPDU_Fix_Fmt);
}
else
{
LPDU_Vol_Head *pHead = (LPDU_Vol_Head *)(m_IEC103Data.m_bySend);
pHead->head1 = pHead->head2 = 0x68;
pHead->len1 = pHead->len2 = m_IEC103Data.m_wSendNum + 2;
pHead->ctrl = linkCtrl;
pHead->addr = pDevRun->pDevData->m_IEDConfig.byNodeAddr;
m_IEC103Data.m_wSendNum += sizeof(LPDU_Vol_Head);
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;
}
}
//循環(huán)查詢組幀
/****
*PackCyc - 循環(huán)查詢組幀函數(shù)
*
*功能:
* 1。總查詢命令
* 2。故障錄波
* 3。通用分類服務(wù)總查詢
* 4。通用2級(jí)數(shù)據(jù)查詢
*
****/
void CIEC103_SFPtl::PackCyc(void)
{
RealRunIED *pDevRun = m_IEC103Data.m_RunIed[m_IEC103Data.m_byCycCnt];
if (pDevRun)
{
if (!PackLinkCmm(m_IEC103Data.m_byCycCnt))
{ // 鏈路層組幀
/*
* 應(yīng)用層組幀
*
*命令優(yōu)先級(jí)
* 1。擾動(dòng)數(shù)據(jù)傳輸
* 2。通用分類服務(wù)總查詢
* 3。召喚電度脈沖量
* 4。總查詢(總召喚)
* 5。循環(huán)查詢2級(jí)數(shù)據(jù)
**/
if(pDevRun->bCommInitFlag && !pDevRun->acd)
{
if(eInitTime == pDevRun->step && pDevRun->nASDU5Cnt>=2)//校時(shí)
{
SendAdjustTime103(pDevRun->pDevData->m_IEDConfig.byNodeAddr);
}
else if(eInitGenAsk == pDevRun->step)//總召喚
{
Pack_Asdu_7(m_IEC103Data.m_byCycCnt);
}
else if(eInitGenGroupAsk == pDevRun->step)//通用分類服務(wù)總召喚 new
{
pDevRun->bGenGroupQury = TRUE; //new
Pack_ASDU_21(m_IEC103Data.m_byCycCnt);
}
else
{
BYTE Code = CallClass2_code;
PackLPDU_Fix(m_IEC103Data.m_byCycCnt, Code);
}
}
else if (!pDevRun->acd && pDevRun->query && !pDevRun->bCommInitFlag)
{
if (!pDevRun->queryFull)
{// 召喚電度量
if(pDevRun->pDevData->m_IEDConfig.nDdNum > 0)
{
if (m_IEC103PtlPara.bGenSel) //在規(guī)約參數(shù)中,若設(shè)置bGenSel為1,
{ //則采用通用分類方式召喚電度量
pDevRun->bDdQury = TRUE;
Pack_ASDU_21(m_IEC103Data.m_byCycCnt); //new
//printf("電度召喚:pDevRun->query = %d\n",pDevRun->query);
}
else
Pack_Asdu_88(m_IEC103Data.m_byCycCnt);
}
}
else// 總召喚
{
Pack_Asdu_7(m_IEC103Data.m_byCycCnt);
if (pDevRun->bQuryEnd)
{
pDevRun->bQuryEnd = FALSE;
pDevRun->bGenGroupQury = TRUE; //new
Pack_ASDU_21(m_IEC103Data.m_byCycCnt); //四方
}
}
// 清除查詢標(biāo)志
pDevRun->query = 0;
}
else if(m_IEC103Data.m_timeover.IsOverTime(m_nCnt) && !pDevRun->bCommInitFlag)//校時(shí)
{
m_IEC103Data.m_timeover.Start(m_nCnt);
BYTE byaddr = 0xff;
SendAdjustTime103(byaddr);
m_bAdjustTime = true;
}
else
{ // 通用查詢
BYTE byCode = CallClass2_code;
if (pDevRun->acd)
byCode = CallClass1_code;
PackLPDU_Fix(m_IEC103Data.m_byCycCnt, byCode);
}
}
}
m_IEC103Data.m_byCycCnt = (m_IEC103Data.m_byCycCnt+1) % CH_MAX_IED_NUM;
}
//asdu88
void CIEC103_SFPtl::Pack_Asdu_88(BYTE byNodeID)
{
RealRunIED *pDevRun = m_IEC103Data.m_RunIed[byNodeID];
BYTE byAddr = 0;
if(m_IEC103PtlPara.bCommAddr)
byAddr = m_IEC103PtlPara.byCKCPUAddr;
else
byAddr = pDevRun->pDevData->m_IEDConfig.byNodeAddr;
ASDU_88_Fmt *pFmt = (ASDU_88_Fmt *)(m_IEC103Data.m_bySend + sizeof(LPDU_Vol_Head));
pFmt->head.type = 88;
pFmt->head.vsq.vsq = 0x81;
pFmt->head.cot = 0x02;
pFmt->head.addr = byAddr;//
pFmt->head.fun = 1;
pFmt->head.inf = 0;
pFmt->qcc.frz = 0;
pFmt->qcc.rqt = 5;
pFmt->rii = m_IEC103Data.m_bySin ++;
m_IEC103Data.m_wSendNum = sizeof(ASDU_88_Fmt);
PackLPDU(byNodeID, SendCon_code);
}
//asdu7
void CIEC103_SFPtl::Pack_Asdu_7(BYTE byNodeID)
{
RealRunIED *pDevRun = m_IEC103Data.m_RunIed[byNodeID];
BYTE byAddr = 0;
if(m_IEC103PtlPara.bCommAddr)
byAddr = m_IEC103PtlPara.byCKCPUAddr;
else
byAddr = pDevRun->pDevData->m_IEDConfig.byNodeAddr;
ASDU_7_Fmt *pFmt = (ASDU_7_Fmt *)(m_IEC103Data.m_bySend + sizeof(LPDU_Vol_Head));
pFmt->head.type = 7;
pFmt->head.vsq.vsq = 0x81;
pFmt->head.cot = 9;
pFmt->head.addr = byAddr;
pFmt->head.fun = 0xff;
pFmt->head.inf = 0;
pFmt->scn = m_IEC103Data.m_bySin ++;
m_IEC103Data.m_wSendNum = sizeof(ASDU_7_Fmt);
PackLPDU(byNodeID, SendCon_code);
}//end Pack_ASDU7()
//通用分類服務(wù)總查詢 ASDU21
void CIEC103_SFPtl::Pack_ASDU_21(BYTE byNodeID)
{
RealRunIED* pRunIED = m_IEC103Data.m_RunIed[byNodeID];
BYTE addr = 0;
if (m_IEC103PtlPara.bCommAddr)//1:CPU地址
addr = m_IEC103PtlPara.byCKCPUAddr;
else
addr = pRunIED->pDevData->m_IEDConfig.byNodeAddr;
if (pRunIED->bGenGroupQury)
{
ASDU_21_Qury* pFmt = (ASDU_21_Qury*)(m_IEC103Data.m_bySend + sizeof(LPDU_Vol_Head));
pFmt->head.type = C_GC_NA_3;//0x15
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -