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

📄 slavews.c

📁 各种规约电表程序的(包手DL645,威胜,西门子等,的库程序)极大方便远程抄表系统
💻 C
字号:
#define ARM_SLAVEWS_GLOBALS#include "cfg_ISlave.h"int fd;int WS_SendFrame( int fd, INT8U addr, INT8U cmd, INT8U *pData, INT8U dataSize);int WS_ReceiveFrame(int fd, INT8U *pbuf,INT16U bufsize, INT16U * psize);int WS_ReadCostPeriod(INT8U port, INT16U LCId, INT8U VsAddr,  INT8U *pBuff, INT16U *pLength);BOOL IsVSReadId( INT16U Id);BOOL  IsVSWriteId( INT16U Id );void TimeToBcd(INT8U *pSrc, INT32U length, INT8U *pDest);int WS_ReadData(int fd, INT16U dataAddr, INT8U size, INT8U meterAddr, INT8U *pBuf);int WS_ReadDataRepeat(int fd, INT16U dataAddr, INT8U size, INT8U meterAddr, INT8U * pBuf);typedef  struct tagWSRetFrameType{	INT8U slaveNo;	INT8U retch1;	INT8U retch2;	INT8U endch;	}_PACKED_  WSRetFrameType;typedef  struct tagWSUpFrameType{	INT8U slaveNo;	INT8U cmd;	INT16U dataAddr;	INT8U dataLen;	INT8U data[1];}_PACKED_  WSUpFrameType;typedef  struct tagVSTableType{	unsigned short id; 	unsigned short MeterStartAddress;	unsigned char size;}_PACKED_  VSTableType;#define WS_CMD_READ        				0X55#define WS_CMD_SET         					0XAA#define WS_CMD_BROADCAST    0XCC#define WS_FRAME_END_CH    0x0dconst VSTableType VSReadTable[]={	//****************************	//本月电量                //	//正向有功  //	0x9010, 0x1001,4,	0x9011, 0x1005,4,	0x9012, 0x1002,4,	0x9013, 0x1003,4,	0x9014, 0x1004,4,	0x901f, 0x1001,20,	//反向有功  //	0x9020, 0x1010,4,	0x9021, 0x1014,4,	0x9022, 0x1011,4,	0x9023, 0x1012,4,	0x9024, 0x1013,4,	0x902f, 0x1010,20,	//正向无功  //	//反向无功  //	//一象限无功 //	0x9130, 0x1006,4,	0x9131, 0x100a,4,	0x9132, 0x1007,4,	0x9133, 0x1008,4,	0x9134, 0x1009,4,	0x913f, 0x1006,20,	//四象限无功 //	0x9140, 0x100b,4,	0x9141, 0x100f,4,	0x9142, 0x100c,4,	0x9143, 0x100d,4,	0x9144, 0x100e,4,	0x914f, 0x100b,20,	//二象限无功 //	0x9150, 0x1015,4,	0x9151, 0x1019,4,	0x9152, 0x1016,4,	0x9153, 0x1017,4,	0x9154, 0x1018,4,	0x915f, 0x1015,20,	//三象限无功 //	0x9160, 0x101a,4,	0x9161, 0x101e,4,	0x9162, 0x101b,4,	0x9163, 0x101c,4,	0x9164, 0x101d,4,	0x916f, 0x101a,20,	//*****************************	//最大xu量	// 正向有功	//	0xa010, 0x1065,2,	0xa011, 0x1061,2,	0xa012, 0x1062,2,	0xa013, 0x1063,2,	0xa014, 0x1064,2,	0xa01f, 0x1061,10,	// 反向有功	//	0xa020, 0x106f,2,	0xa021, 0x106b,2,	0xa022, 0x106c,2,	0xa023, 0x106d,2,	0xa024, 0x106e,2,	0xa02f, 0x106b,10,	// 上月正向有功	//	0xa410, 0x1085,2,	0xa411, 0x1081,2,	0xa412, 0x1082,2,	0xa413, 0x1083,2,	0xa414, 0x1084,2,	0xa41f, 0x1081,10,	// 上月反向有功	//	0xa420, 0x108f,2,	0xa421, 0x108b,2,	0xa422, 0x108c,2,	0xa423, 0x108d,2,	0xa424, 0x108e,2,	0xa42f, 0x108b,10,	//*************************************	//最大xu量发生时间	// 正向有功	//	0xb010, 0x106a,4,	0xb011, 0x1066,4,	0xb012, 0x1067,4,	0xb013, 0x1068,4,	0xb014, 0x1069,4,	0xb01f, 0x1066,20,	// 反向有功	//	0xb020, 0x1074,4,	0xb021, 0x1070,4,	0xb022, 0x1071,4,	0xb023, 0x1072,4,	0xb024, 0x1073,4,	0xb02f, 0x1070,20,	// 上月正向有功	//	0xb410, 0x108a,4,	0xb411, 0x1086,4,	0xb412, 0x1087,4,	0xb413, 0x1088,4,	0xb414, 0x1089,4,	0xb41f, 0x1086,20,	// 上月反向有功	//	0xb420, 0x1094,4,	0xb421, 0x1090,4,	0xb422, 0x1091,4,	0xb423, 0x1092,4,	0xb424, 0x1093,4,	0xb42f, 0x1090,20,		//***********************************	//电压 //	0xb611, 0x10b3,2,	0xb612, 0x10b4,2,	0xb613, 0x10b5,2,	0xb61f, 0x10b3,6,	//电流 //	0xb621, 0x10b6,2,	0xb622, 0x10b7,2,	0xb623, 0x10b8,2,	0xb62f, 0x10b6,6,	//有功功率//	0xb630, 0x10b1,3,	0xb63f, 0x10b1,3,	//无功功率//	0xb640, 0x10b2,3,	0xb64f, 0x10b2,3,		//时间 //	0xc010, 0x2001,5,	0xc011, 0x2001,5	};#define VS_READ_TABLE_SIZE     (sizeof(VSReadTable)/sizeof(VSTableType))int  InitWSCom(INT8U uart,int nSpeed,int nDataBits,char Parity,int nStopBit){		int fd;				fd = 	OpenCom(uart);		if(fd > 0)		{				SetComOpt(fd,nSpeed,nDataBits,Parity,nStopBit);				return  fd;		}		else		{			printf("Open Com Error\n");			return E_COM_OTHER;		}}int SlaveWSReadData(MpComProperty *mpProperty, INT16U dataId, INT8U *pbuf, INT16U bufsize, INT16U *psize ){	INT16U iddatasize;	int i;	int a;	INT8U meterNo;	INT8U num;	INT8U buff[10];	INT8U buff1[5];	INT8U port  ;	INT8U recvBuff[WS_FRAME_SIZE];		port = mpProperty->nComPort;	*psize = 0;	a = mBcdToWord(((MeterAddrType *)mpProperty->addr)->m_ma);	if(a > 255 || a < 0)	{		return E_NO_SUCH_DATA;	}	else	{		meterNo = (INT8U) a;	}	if(IsVSReadId(dataId) == FALSE)	{//		iddatasize = LCGetIDDataSize(dataId);		if(iddatasize > 0)		{			memset(pbuf, 0xff, iddatasize);			*psize = iddatasize;			return SUCCESS;		}		else		{			return E_NO_SUCH_DATA;		}	}		if(dataId >= 0x9010 && dataId <= 0xc011)		{		a = mBinarySearch(dataId, (INT8U *)VSReadTable, sizeof(VSTableType),VS_READ_TABLE_SIZE);		if(a == -1)		{	//		iddatasize = LCGetIDDataSize(dataId);			if(iddatasize > 0)			{				memset(pbuf, 0xff, iddatasize);				*psize = iddatasize;				return SUCCESS;			}			else			{				return E_NO_SUCH_DATA;			}		}		if(WS_ReadDataRepeat(fd, VSReadTable[a].MeterStartAddress, VSReadTable[a].size, meterNo, recvBuff) <= 0)		{			return E_NO_SUCH_DATA;		}				if(dataId >= 0x9010 && dataId <= 0x916f)				//电量          //		{			num = VSReadTable[a].size/4;			if(num > 1)			{				mHexToCompressBcd( recvBuff, 4, 3, (pbuf+*psize), 4, 2); 				*psize += 4;								for(i=1;i<num;i++)				{					mHexToCompressBcd( recvBuff+4*(((i+2)%4)+1), 4, 3, (pbuf+*psize), 4, 2); 					*psize += 4;				}			}			else			{				mHexToCompressBcd( recvBuff, 4, 3, pbuf, 4, 2); 				*psize=4;			}		}		else if(dataId >= 0xa010 && dataId <= 0xb42f)			//需量        //		{			if((dataId&0xf000) == 0xb000)						//判断是最大需量,还是最大需量时间	         //			{				num = VSReadTable[a].size/4;				if(num > 1)				{					for(i=0; i<num; i++)					{						TimeToBcd(recvBuff+4*((i+4)%5), 4, buff);						buff1[0] = buff[3];						buff1[1] = buff[2];						buff1[2] = buff[1];						buff1[3] = buff[0];						memcpy(pbuf+*psize, buff1, 4);												*psize+=4;					}				}				else				{					TimeToBcd(recvBuff, 4, buff);					buff1[0] = buff[3];					buff1[1] = buff[2];					buff1[2] = buff[1];					buff1[3] = buff[0];					memcpy(pbuf+*psize, buff1, 4);					*psize=4;				}			}			else 			{				num=VSReadTable[a].size/2;				if(num>1)				{					for(i=0;i<num;i++)					{						mHexToCompressBcd( recvBuff+2*((i+4)%5), 2, 4, (pbuf+*psize), 3, 4);						*psize+=3;					}				}				else				{					mHexToCompressBcd( recvBuff, 2, 4, (pbuf+*psize), 3, 4);					*psize=3;				}			}		}		else if(dataId >= 0xb611 && dataId <=0xb61f) 	// 电压//		{			num = VSReadTable[a].size/2;			if(num>1)			{				for(i=0;i<num;i++)				{					mHexToCompressBcd( recvBuff+2*i, 2, 2, (pbuf+*psize), 2, 0);					*psize+=2;				}			}			else			{				mHexToCompressBcd( recvBuff, 2, 2, (pbuf+*psize), 2, 0);				*psize+=2;			}		}		else if(dataId >= 0xb621 && dataId <=0xb62f) 	//电流//		{			num = VSReadTable[a].size/2;			if(num>1)			{				for(i=0;i<num;i++)				{					mHexToCompressBcd( recvBuff+2*i, 2, 2, (pbuf+*psize), 2, 2);					*psize+=2;				}			}			else			{				mHexToCompressBcd( recvBuff, 2, 2, (pbuf+*psize), 2, 2);				*psize+=2;			}		}		else if(dataId == 0xb630 || dataId == 0xb63f)		{			mHexToCompressBcd( recvBuff, 3, 4, (pbuf+*psize), 3, 4);			*psize+=3;						if((dataId &0x000f)==0x000f)			{				memset(pbuf+*psize, 0xff, 3*3);				*psize += (3*3);			}		}		else if(dataId == 0xb640 || dataId == 0xb64f)		{			mHexToCompressBcd( recvBuff, 3, 4, (pbuf+*psize), 2, 2);// CXY 1-->4 20050602			*psize+=2;						if((dataId &0x000f)==0x000f)			{				memset(pbuf+*psize, 0xff, 2*3);				*psize += (2*3);			}		}		else if(dataId == 0xc010 || dataId == 0xc011)		{			if(dataId == 0xc010)			{				*(pbuf+0)=mGetWeek(recvBuff[0]+2000, recvBuff[1], recvBuff[2]);  //week				*(pbuf+1)=mByte2Bcd(recvBuff[2]);	//day				*(pbuf+2)=mByte2Bcd(recvBuff[1]);	//month				*(pbuf+3)=mByte2Bcd(recvBuff[0]);	//year				*psize = 4;			}			else			{				*pbuf=0;							//second				*(pbuf+1)=mByte2Bcd(recvBuff[4]);	//minute				*(pbuf+2)=mByte2Bcd(recvBuff[3]);	//hour				*psize = 3;			}		}		else 		{			return E_NO_SUCH_DATA;		}		return SUCCESS;	}	else if(dataId>=0xc331 && dataId<=0xc33f)	//   费率时段  //	{		return WS_ReadCostPeriod(port, dataId, meterNo, pbuf, psize);	}	else	{	//	iddatasize = LCGetIDDataSize(dataId);		if(iddatasize > 0)		{			memset(pbuf, 0xff, iddatasize);			*psize = iddatasize;			return SUCCESS;		}		else		{			return E_NO_SUCH_DATA;		}	}	return E_NO_SUCH_DATA;}int WS_ReadData(int fd, INT16U dataAddr, INT8U size, INT8U meterAddr, INT8U *pBuf){		INT8U buff[10];	WSRetFrameType	*pWSRetFrame;	WSUpFrameType *pWSUpFrame;	INT8U recvbuff[WS_FRAME_SIZE];  INT16U framesize;  int retvalue;//	*(INT16U *)buff = dataAddr;	buff[0] = (INT8U)(dataAddr&0xff);	buff[1] = (INT8U)((dataAddr>>8)&0xff);	buff[2] = size; WS_SendFrame(fd, meterAddr, WS_CMD_READ, buff, 3);retvalue = WS_ReceiveFrame(fd, recvbuff,WS_FRAME_SIZE,&framesize);	if(retvalue == SUCCESS &&  framesize > 0)	{				pWSRetFrame = (WSRetFrameType *)recvbuff;		if(pWSRetFrame->retch1 == 'O' && pWSRetFrame->retch2 == 'K')		{			if(framesize>sizeof(WSRetFrameType))			{				pWSUpFrame = (WSUpFrameType *)(recvbuff+sizeof(WSRetFrameType));				memcpy(pBuf, (INT8U *)(pWSUpFrame->data), pWSUpFrame->dataLen);				return pWSUpFrame->dataLen;;			}			else			{				return -1;			}		}		else if(pWSRetFrame->retch1 == 'B' && pWSRetFrame->retch2 == 'D')		{			return -1;		}		else		{			return 0;		}	}	return 0;}//===============================================================================// Function    : void WSWriteFrame(INT8U slaveNo, INT8U cmd, INT8U *pData, INT8U dataSize)// Parameter   ://              // Return      : // Description : write a frame//===============================================================================int  WS_SendFrame( int fd, INT8U addr, INT8U cmd, INT8U *pData, INT8U dataSize){	INT8U *ptr;	INT16U size;	INT8U sendbuff[WS_FRAME_SIZE];	size = 0;	ptr = sendbuff;	*(ptr++) = 0xfe;	*(ptr++) = 0xfe;	*(ptr++) = addr;	*(ptr++) = cmd;	size += 4;		memcpy(ptr, pData, dataSize);		size += dataSize;	ptr+=dataSize;	*(ptr++) = mCheckSumByte(sendbuff+2, dataSize + 2);	*ptr = WS_FRAME_END_CH;	size += 2;		return SlaveSendFrame(fd, sendbuff, size,SLAVEWS_SEND_OUT);}int WS_ReceiveFrame(int fd, INT8U *pbuf,INT16U bufsize, INT16U * psize){	int nGetBytes = 0,nTot = 0;  INT8U nRecvLen  = WS_FRAME_SIZE ;  int RecvFlag=0;   INT16U readsize = 0;	while(1)	{		SlaveRecvFrame(fd,&pbuf[nTot],nRecvLen,&readsize,SLAVEWS_RECV_OUT);				if(readsize == 0)		{			 usleep(100);			 RecvFlag++;       if(RecvFlag>MAX_TRY_RECV)       {        		return E_COM_RECV;       }       if(nTot > 0)       {#if SLAVE_DEBUG_EN > 0	        	printf("WS Recv is:\n");        	        	mPrintfHex(pbuf,nTot);#endif  					*psize = nTot;        	 return SUCCESS;       }			 continue;		}		 nTot+= nGetBytes;	}	return FAILED;	}//标准威胜协议能抄电量、需量、电压电流不能抄项限值		//BOOL IsVSReadId( INT16U Id) {	if((Id>=0x9010 && Id <= 0xb42f) || (Id >= 0xb611 && Id <= 0xb64f) || (Id == 0xc010 ||Id == 0xc011) ||(Id>=0xc331 && Id<=0xc33f))		return TRUE;	else		return FALSE;}BOOL  IsVSWriteId( INT16U Id ){	if(Id == 0xc010 ||Id == 0xc011)	 	return TRUE;	else		return FALSE;}int WS_ReadCostPeriod(INT8U port, INT16U LCId, INT8U VsAddr,  INT8U *pBuff, INT16U *pLength){	int i;	int a;	INT16U startAddr;	INT8U size;	int periodNum;	int periodNo;	INT8U hour;	INT8U minute;	INT8U CostNo;	INT8U recvBuff[WS_FRAME_SIZE];	*pLength = 0;	startAddr = 0x3100;	size = 4;	if(WS_ReadDataRepeat(port, startAddr, size, VsAddr, recvBuff)<=0)	{		return E_NO_SUCH_DATA;	}	periodNum = recvBuff[3];	if(periodNum > 8)	{		periodNum = 8;	}	startAddr = 0x3101;	size = 2;		if((LCId & 0x000f) != 0x000f)	{		periodNo = LCId-0xc331;				if(periodNo>=periodNum)		{			return E_NO_SUCH_DATA;		}		if(WS_ReadDataRepeat(port, startAddr+periodNo, size, VsAddr, recvBuff)<=0)		{			return E_NO_SUCH_DATA;		}		CostNo  = (recvBuff[0]>>4)+1;		*(((INT8U *)&a) +1)= recvBuff[0]&0x0f;		*((INT8U *)&a)= recvBuff[1];		hour = a/60;		minute = a%60;		*(pBuff+0)= CostNo;		*(pBuff+1) = mByte2Bcd(minute);		*(pBuff+2) = mByte2Bcd(hour);		*pLength = 3;	}	else	{		for(i=0; i<periodNum; i++)		{			if(WS_ReadDataRepeat(port, startAddr+i, size, VsAddr, recvBuff)<=0)			{				return E_NO_SUCH_DATA;			}			CostNo  = (recvBuff[0]>>4)+1;			*(((INT8U *)&a) +1)= recvBuff[0]&0x0f;			*((INT8U *)&a)= recvBuff[1];			hour = a/60;			minute = a%60;			*(pBuff+(*pLength)++)= CostNo;			*(pBuff+(*pLength)++) = mByte2Bcd(minute);			*(pBuff+(*pLength)++) = mByte2Bcd(hour);		}		memset(pBuff+*pLength, 0x00, 8-periodNum);		*pLength = 3*8;	}	return SUCCESS;	}int WS_ReadDataRepeat(int fd, INT16U dataAddr, INT8U size, INT8U meterAddr, INT8U * pBuf){	int i;	int len;		for(i=0; i<3; i++)	{		if((len = WS_ReadData(fd, dataAddr, size, meterAddr, pBuf)) > 0)		{			return len;		}	}	return 0;}void TimeToBcd(INT8U *pSrc, INT32U length, INT8U *pDest){	INT32U i;	for(i=0;i<length;i++)	{		*(pDest+i)=mByte2Bcd(*(pSrc+i));	}}

⌨️ 快捷键说明

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