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

📄 slavews.c

📁 电力行业的DL645采集程序,嵌入式Linux环境
💻 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    0x0d


const 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 + -