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

📄 functions.cpp

📁 modbus通讯原代码工程程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	buf[1] = 0x0F;
	buf[2] = 0;
	buf[3] = ykno;
	buf[4] = 0;
	buf[5] = 1;
	buf[6] = 1;
	buf[7] = value;
	WORD crc = CRC16(buf, 8);
	buf[8] = LOBYTE(crc);
	buf[9] = HIBYTE(crc);
}

// 解遥控报文
local 
BOOL Explain_YK(BYTE *buf,RTU *rtu)
{
/* ADDR	  0FH	 遥控对象   QUANTITY  CRC16     10+8=18
   1byte  1byte	 2byte	    2byte	  2byte */
	if( (buf[0]!=rtu->Addr) ||
		(buf[1]!=0x0F) ||
		(buf[2]!=rtu->YkNoHigh) ||
		(buf[3]!=rtu->YkNoLow) ||
		(MAKEWORD(buf[4],buf[5])!=0x0001) )  //
		return FALSE;

	WORD crc = CRC16(buf, 6);
	if(crc!=MAKEWORD(buf[6],buf[7]))
		return FALSE;

	return TRUE;
}

//
void Explain_YKYT_SELECT(BOOL rel,CChannel *tempCh,RTU *pRtu)
{
	pRtu->YKEchoFlag = TRUE;
	pRtu->YKEcho[1] = rel?0x33:0xFF;	
    tempCh->nWaitRcv = 0;
}

//
local
BOOL Explain(CChannel *tempCh,CSystemPara *sp,RTU *pRtu,int num)
{
	BOOL rel = FALSE;
	switch (tempCh->nWaitRcv)
	{
	case CMD_YC1:		
		rel = Explain_YC1(tempCh->RcvBuf,pRtu);
		break;
	case CMD_YC2:		
		rel = Explain_YC2(tempCh->RcvBuf,pRtu);
		break;
	case CMD_YC3:		
		rel = Explain_YC3(tempCh->RcvBuf,pRtu);
		break;
	case CMD_YX:		
		rel = Explain_YX(tempCh->RcvBuf,pRtu,tempCh,sp);
		break;
	case CMD_YK:		
		rel = Explain_YK(tempCh->RcvBuf,pRtu);
		break;
	case CMD_YT:		
		rel = Explain_YT(tempCh->RcvBuf,pRtu);
		break;
	case CMD_YK_SELECT:			
	case CMD_YT_SELECT:		
		rel = Explain_YX(tempCh->RcvBuf,pRtu,tempCh,sp);
		Explain_YKYT_SELECT(rel,tempCh,pRtu);
		break;
	}

	if(rel)
		pRtu->nReply = NORMAL_REPLY;

	return rel;
}

//
local 
BOOL AddDataToList(CChannel *tempCh, COMDATA *cd)
{
	if(tempCh->DGramLink != NULL)
	{
		delete tempCh->DGramLink;
		tempCh->DGramLink = NULL;
	}
	tempCh->DGramLink = cd;
	tempCh->scflag = WAITSEND;

	return TRUE;
}

//
void MakeFrame(CChannel *tempCh, CSystemPara *sp, BYTE RtuNo, BYTE type)
{
	BYTE      *buf;
	BYTE      lenth;
	COMDATA   *tempCd;
	RTU       *pRtu = sp->m_rtus[RtuNo];

	tempCd = new COMDATA();
	tempCd->RtuNo = RtuNo;
	lenth = (type==CMD_YK)?10:8;
	tempCd->SendBuf = new BYTE[lenth];
	tempCd->SendNum = lenth; 
	buf = tempCd->SendBuf;
	memset(buf,0,lenth);

	switch(type)
	{
	case CMD_YX:		
		tempCd->RecNum = 41; 		
		MakeFrame_YX(buf,pRtu->Addr);
		break;
	case CMD_YC1:		
		tempCd->RecNum = 49; 		
		MakeFrame_YC1(buf,pRtu->Addr);
		break;
	case CMD_YC2:		
		tempCd->RecNum = 45; 		
		MakeFrame_YC2(buf,pRtu->Addr);
		break;
	case CMD_YC3:		
		tempCd->RecNum = 45; 		
		MakeFrame_YC3(buf,pRtu->Addr);
		break;
	case CMD_YK_SELECT:
	case CMD_YT_SELECT:
		tempCd->RecNum = 41; 		
		MakeFrame_YX(buf,pRtu->Addr);
		break;
	case CMD_YK:
		// sp->YKReserved[3]:	0-21 遥控序号
		tempCd->RecNum = 8; 		
		                            /* 遥控对象 */      /* 值 */
		MakeFrame_YK(buf,pRtu->Addr,sp->YKReserved[3]+1,sp->YKReserved[7]);
		break;	
	case CMD_YT:
		{// sp->YKReserved[3]:	0-2 遥调序号 0 - 一/二段控母电压	1 - 一组电池电压	2 - 二组电池电压
			BYTE yttype, tmp;

			if(sp->YKReserved[3]==0)
				yttype = U_M_YT;
			else if(sp->YKReserved[3]==1)
			{
				// 一组电池均充:YX17
				tmp = pRtu->YxwValue[1] & 0x0002;
				yttype = (tmp)?U_EC_YT:U_VC_YT;
			}
			else if(sp->YKReserved[3]==2)
			{
				// 二组电池均充:YX23
				tmp = pRtu->YxwValue[1] & 0x0080;
				yttype = (tmp)?U_EC_YT:U_VC_YT;
			}

			tempCd->RecNum = 8; 
			                            /* 遥调对象 */   /* 值 */
			MakeFrame_YT(buf,pRtu->Addr,     yttype,     MAKEWORD(sp->YKReserved[7],sp->YKReserved[8]));
		}
		break;
	}
	AddDataToList(tempCh, tempCd);

	if(type==CMD_YK_SELECT)
		pRtu->nYKYTSelect = CMD_YK_SELECT;
	else if(type==CMD_YT_SELECT)
		pRtu->nYKYTSelect = CMD_YT_SELECT;
	else
		pRtu->nYKYTSelect = 0;
}

//
int GetYKYTCmdInfoFromHMI(CChannel *tempCh,CSystemPara *sp)
{
	int nCommand = NULL_YKYT;	

	if( (tempCh->nFlagYK != 0xAA) && (tempCh->nFlagYK != 0xCC) )
		return nCommand;

	switch (sp->YKReserved[0])
	{
	case 0x11:
		nCommand = (tempCh->nFlagYK == 0xAA)?SELECT_YK:SELECT_YT;
		break;
	case 0x22:
		nCommand = (tempCh->nFlagYK == 0xAA)?EXECUTE_YK:EXECUTE_YT;
		break;
	case 0x33:
		nCommand = (tempCh->nFlagYK == 0xAA)?CANCEL_YK:CANCEL_YT;
		break;
	default:
		break;
	}	

	tempCh->nFlagYK = 0;

	return nCommand;
}

//
void OnYKYT(CChannel *tempCh,CSystemPara *sp, int type)
{
	BYTE RtuNo = (BYTE)tempCh->ykrtuno;
	switch(type)
	{
	case SELECT_YK:
		MakeFrame(tempCh,sp,RtuNo,CMD_YK_SELECT);
		break;
	case EXECUTE_YK:
		MakeFrame(tempCh,sp,RtuNo,CMD_YK);
		break;
	case SELECT_YT:	
		MakeFrame(tempCh,sp,RtuNo,CMD_YT_SELECT);	
		break;
	case EXECUTE_YT:	
		MakeFrame(tempCh,sp,RtuNo,CMD_YT);
		break;
	}
}

//
void GetNextDGRAMType(CChannel *tempCh,RTU *pRtu,BYTE *type)
{
	BYTE reply =pRtu->nReply;

	if( (reply == NO_REPLY) || (reply == INVALID_REPLY) || (reply == SENDFAIL_REPLY) )
	{
		*type = CMD_YX;
		return;
	}	

	switch(pRtu->nDGRAMTypeLast)
	{
	case CMD_YC1:
		*type = CMD_YC2;
		break;
	case CMD_YC2:
		*type = CMD_YC3;
		break;
	case CMD_YC3: 
		*type = CMD_YX;
		break;
	case CMD_YX:
		*type = CMD_YC1;
		break;
	case CMD_YK:
	case CMD_YK_SELECT:	
	case CMD_YT:
	case CMD_YT_SELECT:
	case CMD_NULL:
		*type = CMD_YX;
		break;
	default:
		break;
	}
}

//
void ReleaseMem(CChannel *tempCh)
{
	COMDATA *tempCD,*tempCD2;
	tempCD = tempCh->DGramLink;
	while(tempCD != NULL)
	{
		tempCD2 = tempCD->next;
		delete tempCD;
		tempCD = tempCD2;
	}
	tempCh->DGramLink = NULL;
}

//
void OnNormal(CChannel *tempCh, CSystemPara *sp)
{
	BYTE   RtuNo;
	RTU    *pRtu;	
	BYTE   DGramType;
	int    RtuNum = tempCh->channel.GetRtuNum();	
	BOOL   bSpyChan = (RtuNum == tempCh->GZRtuNum); // TRUE:该通道已被链入故障通道表链,处被探测状态 	

	if(tempCh->DGramLink == NULL) 
	{// 通道启用后,尚未组报文

		for(int i=0;i<RtuNum;i++)
		{// RTU协议参数初始化
			RtuNo = (BYTE)tempCh->channel.GetRtuNo(i);
			pRtu = sp->m_rtus[RtuNo];
			pRtu->nReply = NORMAL_REPLY;
			pRtu->nDGRAMTypeLast = CMD_NULL;
			pRtu->nYKYTSelect = 0;
		} 

		if(bSpyChan)
		{// 依次探测不同的RTU	
			if(tempCh->nNextRtuIndex+1>RtuNum)
				tempCh->nNextRtuIndex = 0;	
		}
		else
			tempCh->nNextRtuIndex = 0;

		tempCh->nWaitRcv = 0;		
	
		RtuNo = (BYTE)tempCh->channel.GetRtuNo(tempCh->nNextRtuIndex);	
		MakeFrame(tempCh,sp,RtuNo,CMD_YX);

		tempCh->nNextRtuIndex++;

		return;
	}

	if(tempCh->nNextRtuIndex+1>RtuNum)
		tempCh->nNextRtuIndex = 0;	

	RtuNo = (BYTE)tempCh->channel.GetRtuNo(tempCh->nNextRtuIndex);
	pRtu = sp->m_rtus[RtuNo];

   	if(pRtu->nReply == UNCERTAIN_REPLY)
	{// 收操作尚未进行	
		return;
	}
	
	GetNextDGRAMType(tempCh,pRtu,&DGramType);
	MakeFrame(tempCh,sp,RtuNo,DGramType);     

	tempCh->nNextRtuIndex++;
}

//
local 
void OnError(CChannel *tempCh,RTU *pRtu,BYTE RtuNo)
{
	SetChanGZPara(tempCh,pRtu,RtuNo,CHANJAM);	

	if(tempCh->GZRtuNum == (BYTE)tempCh->channel.GetRtuNum())
	{// 在此通道即将被移出正常通道链表前释放相应的内存
		ReleaseMem(tempCh);	
		tempCh->scflag = ALREADYSEND;
	}
}

//
local 
void OnYKYTFailure(RTU *pRtu)
{
	pRtu->YKEchoFlag = TRUE;
	pRtu->YKEcho[1] = 0xFF;
}

//
local
void OnRcvFailure(CChannel *tempCh, CSystemPara *sp, RTU *pRtu, BYTE RtuNo)
{
	if( (tempCh->nWaitRcv == CMD_YK_SELECT) || (tempCh->nWaitRcv == CMD_YK) ||
		(tempCh->nWaitRcv == CMD_YT_SELECT) || (tempCh->nWaitRcv == CMD_YT) )
		OnYKYTFailure(pRtu);				
	
	pRtu->nReply = NO_REPLY;		
	
	tempCh->nWaitRcv = 0;

	tempCh->bShowRcvBuf = SHW_ERROR;
	OnError(tempCh,pRtu,RtuNo);
}

//
local 
void AfterSend(CChannel *tempCh, CSystemPara *sp, COMDATA *tempCd,BOOL bSuccess)
{
	BYTE  RtuNo = tempCd->RtuNo;
	RTU   *pRtu = sp->m_rtus[RtuNo];
	BYTE  nDGramType = tempCd->SendBuf[1];

	if(pRtu->nYKYTSelect)
	{// 遥控选择/遥调选择
		nDGramType = pRtu->nYKYTSelect;
		pRtu->nYKYTSelect = 0;
	}
	
	tempCh->bShowSendBuf = (bSuccess)?SHW_NORM:SHW_ERROR;		
	tempCh->nWaitRcv = bSuccess?nDGramType:0;	
	tempCh->scflag = ALREADYSEND;
	tempCh->nRtuNo = RtuNo;
	pRtu->nDGRAMTypeLast = nDGramType;	

	if(!bSuccess)
	{
		pRtu->nReply = SENDFAIL_REPLY;
		OnError(tempCh,pRtu,RtuNo);
	}
	else
		pRtu->nReply = UNCERTAIN_REPLY;

	if(nDGramType==CMD_YT)
	{
		pRtu->YTValueLow = tempCd->SendBuf[5];
		pRtu->YTValueHigh = tempCd->SendBuf[4];
		pRtu->YTRegLow = tempCd->SendBuf[3];
	}
	else if(nDGramType==CMD_YK)
	{
		pRtu->YkNoHigh = 0;
		pRtu->YkNoLow = tempCd->SendBuf[3];	
	}	
}

//
void SendDGram(CChannel *tempCh, CSystemPara *sp)
{
	COMDATA  *tempCd = NULL;
	DWORD    num;

	if(tempCh->DGramLink!=NULL)
	{
		if(tempCh->scflag != WAITSEND)
		{// 链表里的报文是陈旧的报文
			return;
		}

		tempCd = tempCh->DGramLink;	
	}	

	if(tempCd == NULL)
		return;

	BOOL bSuccess = WriteChan(tempCh,sp,tempCd->SendBuf,tempCd->SendNum,&num);
//	OutDGram_DEBUG(tempCd->SendBuf,num,1);
	if(!bSuccess)
		AfterSend(tempCh,sp,tempCd,FALSE);
	else
		AfterSend(tempCh,sp,tempCd,TRUE);
}

//
void RcvDGram(CChannel *tempCh, CSystemPara *sp)  
{
	DWORD num;

	BYTE RtuNo = tempCh->nRtuNo;
	RTU  *pRtu = sp->m_rtus[RtuNo];

	BYTE *RcvBuf = tempCh->RcvBuf;
	BOOL bSpyChan = SpyChanGram(tempCh,sp,RcvBuf,0,&num);

	if( (!bSpyChan) || (num == 0) )
	{	
		OnRcvFailure(tempCh,sp,pRtu,RtuNo);
	}
	else
	{
		int nBytesInChan = num;
		BOOL bReadSuccess = ReadChan(tempCh,sp,tempCh->RcvBuf,nBytesInChan,&num);
				
	    if(bReadSuccess && num != 0)
		{			
//			OutDGram_DEBUG(tempCh->RcvBuf,num,0);	
			
			if(!Explain(tempCh,sp,pRtu,num))
				OnRcvFailure(tempCh,sp,pRtu,RtuNo);	
			else
			{
				tempCh->nWaitRcv = 0;	
				tempCh->bShowRcvBuf = SHW_NORM;	
				SetChanGZPara(tempCh,pRtu,RtuNo,CHANNORM);
			}					
		}
		else
			OnRcvFailure(tempCh,sp,pRtu,RtuNo);	
		
		memset(RcvBuf,MAX_RECV_LEN,0);
	}
}

⌨️ 快捷键说明

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