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

📄 diaobiao97.cpp

📁 一个电度表的通信规约,组态王调用此程序,具体方法代码中有注释.
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//返回值:连接成功返回true,否则返回:false;																 //
//																										 //
///////////////////////////////////////////////////////////////////////////////////////////////////////////
DLL_EXPORT bool  Connect(void *pThis,LPSTR type ,void *lpRD,void *lpSD,void *lpCB,void *lpMsg,void * lpExit,void *pCommPort,WORD ChannelID,int box_count)
{
	CallbackStruct * pCallback;
	pCallback=(CallbackStruct *)TlsGetValue(dwTlsIndex);
	if(!pCallback)
		return false;
	pCallback->pThis=pThis;
	pCallback->fnReceiveData=(lpReceiveData)lpRD;
	pCallback->fnSendData=(lpSendData)lpSD;
	pCallback->fnClearBuff=(lpClearBuff)lpCB;
	pCallback->fnOnEventMessage=(lpOnEventMessage)lpMsg;
	pCallback->pPort=pCommPort;
	pCallback->ChannelID=ChannelID;
    pCallback->fnIsExit=(lpIsExit)lpExit;
	pCallback->BoxCount=box_count;
	
	if(::strcmp(type,"com")==0 || ::strcmp(type,"COM")==0)
		pCallback->PortType=TY_COM;
	else if(::strcmp(type,"net")==0 || ::strcmp(type,"NET")==0)
		pCallback->PortType=TY_TCP;
	else if(::strcmp(type,"udp")==0 || ::strcmp(type,"UDP")==0)
		pCallback->PortType=TY_UDP;
	return true;
}
///////////////////////////////******##Disconnect接口说明##******///////////////////////////////////////
//						
//功能:此函数被主程序通信线程退出时调用,使DLL程序能正常退出;
//
//参数:无;
//返回值:暂无定义;
//
////////////////////////////////////////////////////////////////////////////////////////

DLL_EXPORT bool Disconnect(void)
{
	
	return true;
}
///////////////////////////////******##Initialize接口说明##******///////////////////////////////////////
//						
//功能:此函数被主程序通信线程开始执行并调用Connect后调用,使DLL程序能初始化;
//
//参数:无;
//返回值:无;
//
////////////////////////////////////////////////////////////////////////////////////////

DLL_EXPORT void Initialize(void)
{
	InitErrorCount();
}



//组ID
#define GROUP_YC   49
#define GROUP_YX   51
#define GROUP_GZ   52
#define GROUP_DZ   47
#define GROUP_TT   67
#define GROUP_PARA 6
#define GROUP_YK   66


int bcdtoint(int ibcd) //转换BCD码为整数
{
	int result;
	char buff[5];
	memset(buff,0,5);
	sprintf(buff,"%02x",ibcd);
	result=atoi(buff);
	return result;
}



float ProcData(UCHAR *mInBuff)
{
  	float fValue;
    int j=12;
	int Value1,Value2,Value3,Value4;
    Value1=bcdtoint(mInBuff[j]-0x33);
	Value2=bcdtoint(mInBuff[j+1]-0x33);
	Value3=bcdtoint(mInBuff[j+2]-0x33);
	Value4=bcdtoint(mInBuff[j+3]-0x33);
	char cValue[10];
	memset(cValue,0,10);
	sprintf(cValue,"%d%d%d.%d",Value4,Value3,Value2,Value1);
    fValue=atof(cValue);
	return fValue;
}


///////////////////////////////******##WriteData接口说明##******///////////////////////////////////////
//						
//功能:此函数被主程序通信线程循环调用,以下发命令;
//
//参数:Addr:单元箱地址;type:下发的数据类型,为以下值:CMD_YK_SELECT,CMD_YK_CANCEL,CMD_YK_EXEC,CMD_TIME
//      CMD_YT,CMD_UPDATE_DATA
//		分别表示:遥控选择,遥控退出,遥控执行,对时,遥调,刷新数据;
//      groupID:组ID,item_count:组内数据条目个数,pItem:组内数据指针
//      write_index:写序号,write_value:写数据值
////////////////////////////////////////////////////////////////////////////////////////
DLL_EXPORT bool WriteData(long Addr,WORD type,WORD groupID,WORD item_count,CItem * pItem,int write_index,double write_value)
{
	
	switch(type)
	{
	case CMD_UPDATE_DATA:
		
		break;
	case CMD_YT:
		
		break;
	case CMD_YK_SELECT:
		return true;
	case CMD_YK_CANCEL:
		return true;
	case CMD_YK_EXEC:
		break;
	case CMD_TIME:
		
		return true;
		
	default : return false;
	}
	
	return 0;
	
}
///////////////////////////////******##ReadData接口说明##******///////////////////////////////////////
//						
//功能:此函数被主程序通信线程循环调用,以读取/刷新实时数据;
//
//参数:Addr:单元箱地址;
//      groupID:组ID,item_count:组内数据条目个数,pItem:组内数据指针
//      excount:扩展数据个数,扩展数据包括:TY_SOE_YX1,TY_SOE_GZ,TY_SOE_YCH,TY_SOE_YCL分别表示:遥信变位SOE,保护SOE,遥测越上限SOE,遥测越下限SOE,没有扩展数据时必须设为0;
//		pExData:用以返回扩展数据的地址,扩展数据的存储空间由此函数中分配,主程序负责释放,
//		errcount:返回此次读取数据过程中错误帧数;
//      bCommState:传进来的是装置的先前通信状态,bCommState:返回装置的通信状态,TRUE:正常,FALSE:中断;
//
//返回值:暂未定义;
//
////////////////////////////////////////////////////////////////////////////////////////

void  ReadParaDB(long Addr,char *sztemp)
{	
	char strAddr[10];
	memset(strAddr,0,10);
    sprintf(strAddr,"%d",Addr);
	char m_sFilePath[255];	
	char szPath[255];
	memset(szPath,0,255);
    memset(m_sFilePath,0,255);	
	GetCurrentDirectory(sizeof(szPath),szPath);
	sprintf(m_sFilePath,"%s\\diandubaio97.ini",szPath);		
	int nDataNum = GetPrivateProfileString("biaohao", strAddr, "", sztemp, 128, m_sFilePath);
}


int itobcd(int ihex) //整数转换为BCD码
{
    int result;
	int hi=ihex/10;
	int Lo=ihex%10;
	hi=(hi<<4)&0xf0;   
	result=hi|Lo;
	return result;
}


float makeFrameSend(long Addr,WORD item_count,CItem * pItem,BYTE AddrHi,BYTE addrLo,int * excount,EventData * * pExData,DWORD *errcount,bool * bCommState)
{   
   	UCHAR OutBuff[20];//向串口写数据缓冲区
	UCHAR reBuff[100];//从串口读数据保存缓冲区
	char errBuff[80];
	int iRecount=0;
	int iSum=0;
	int DataCount=18;
	int iSendLen=14;
	float fValue=0.0;

	char cBiaoHao[20];
	memset(cBiaoHao,0,20);
    ReadParaDB(Addr,cBiaoHao);
    for(int k=0;k<6;k++)
	{
	  char cA[2];	  
      memcpy(cA,&cBiaoHao[2*k],2);
      OutBuff[6-k]=itobcd(atoi(cA));  
	}

	OutBuff[0]=0x68;  

	OutBuff[7]=0x68;
	OutBuff[8]=0x01;
	OutBuff[9]=0x02;	
	OutBuff[10]=AddrHi+0x33;
	OutBuff[11]=addrLo+0x33;
	OutBuff[12]=0x00;
	for(int i=0;i<12;i++)
	{
      iSum+=OutBuff[i];
	}
	OutBuff[12]=iSum%256;
	OutBuff[13]=0x16;
     
	CallbackSendData(Addr,(char *)OutBuff,iSendLen);//发送循检数据
	Sleep(100);
	iRecount=CallbackReceiveData(Addr,(char *)reBuff,DataCount);;

    if(iRecount<DataCount)//接收响应数据
	{
         ::Sleep(100);
			if(!CallbackReceiveData(Addr,(char *)(reBuff+iRecount),DataCount-iRecount))//接收响应数据
			{
				*errcount=1;
				::sprintf(errBuff,"表号为:%s的电度表没有响应(数据地址%02x%02x)!",cBiaoHao,addrLo,AddrHi);
				CallbackOnEventMessage(errBuff,TY_EVENT);
				if(AddErrorCount(Addr,1)>20)//连续20错误,报通信中断
					* bCommState=0;
			}
			else
			{
				fValue=::ProcData((UCHAR *)reBuff);
				ClearErrorCount(Addr);//通信正常,清除计数
				* bCommState=true;	
				*excount=0;
				*pExData=0;
			}
	}
  	else
		{
			fValue=::ProcData((UCHAR *)reBuff);
				ClearErrorCount(Addr);//通信正常,清除计数
				* bCommState=true;	
				*excount=0;
				*pExData=0;
		}

return 	fValue;
	
}

BYTE BHi[20]={0x10,0x11,0x12,0x13,0x14,0x20,0x21,0x22,0x23,0x24,0x10,0x11,0x12,0x13,0x14,0x20,0x21,0x22,0x23,0x24};

DLL_EXPORT int ReadData(long Addr,WORD groupID,WORD item_count,CItem * pItem,int * excount,EventData * * pExData,DWORD *errcount,bool * bCommState)
{	
	CallbackClearBuff(TY_TXANDRXCLEAR);//清除缓冲区
	int i=0,j=0;
	switch(groupID)
	{
	case GROUP_YC:
		if (item_count==0)  return false;
	    
		for( i=1;i<21;i++)
		{
			for( j=0;j<item_count;j++)
			{
               if(i==pItem[j].m_BoxIndexID)
			   {
                  if(i<11)
					 pItem[j].m_Value.dblVal = makeFrameSend(Addr,item_count,pItem,BHi[i-1],0x90,excount,pExData,errcount,bCommState);
				  else
					 pItem[j].m_Value.dblVal =makeFrameSend(Addr,item_count,pItem,BHi[i-1],0x91,excount,pExData,errcount,bCommState);
				  pItem[j].m_Status=TRUE; 
				  break;
			   }
			}

		}
		break;
	case GROUP_YX:		
		break;
	case GROUP_GZ:		
		break;
	case GROUP_DZ:		
		break;
    case GROUP_TT:		
		break;
    case GROUP_PARA:		
		break;
	default : return 0;
	}
	
lable1:
	int n;
	if(* bCommState==0)//通信状态
	{
		for( n=0;n<item_count;n++)
		{
			pItem[n].m_Status=false;
		}
	}
	::Sleep(20);
	return 0;
}


⌨️ 快捷键说明

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