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

📄 slaveedmi.c

📁 电力行业的DL645采集程序,嵌入式Linux环境
💻 C
📖 第 1 页 / 共 3 页
字号:

#define ARM_SLAVEEDMI_GLOBALS
#include "cfg_ISlave.h"
const INT8U EdmiDefaultUserName[] = "EDMI";


const EdmiTableType EdmiIdTable[]=
{
		{ 0x9010, 0x0169, 1},	//正向有功总电量//
		{ 0x9011, 0x0163, 1},	//费率1正向有功电量//
		{ 0x9012, 0x0160, 1},	//费率2正向有功电量//
		{ 0x9013, 0x0161, 1},	//费率3正向有功电量//
		{ 0x9014, 0x0162, 1},	//费率4正向有功电量//
		{ 0x901f, 0x0160, 4},	//费率1-4正向有功电量//
		
		{ 0x9020, 0x0069, 1},	//反向有功总电量//
		{ 0x9021, 0x0063, 1},	//费率1反向有功电量//
		{ 0x9022, 0x0060, 1},	//费率2反向有功电量//
		{ 0x9023, 0x0061, 1},	//费率3反向有功电量//
		{ 0x9024, 0x0062, 1},	//费率4反向有功电量//
		{ 0x902f, 0x0060, 4},	//费率1-4反向有功电量//

		
		{ 0x9110, 0x0369, 1},	//正向无功总电量//
		{ 0x9111, 0x0363, 1},	//费率1正向无功总电量//
		{ 0x9112, 0x0360, 1},	//费率2正向无功总电量//
		{ 0x9113, 0x0361, 1},	//费率3正向无功总电量//
		{ 0x9114, 0x0362, 1},	//费率4正向无功总电量//
		{ 0x911f, 0x0360, 4},	//费率1-4正向无功峰电量//

		{ 0x9120, 0x0269, 1},	//反向无功总电量//
		{ 0x9121, 0x0263, 1},	//费率1//
		{ 0x9122, 0x0260, 1},	//费率2//
		{ 0x9123, 0x0261, 1},	//费率3//
		{ 0x9124, 0x0262, 1},	//费率4//
		{ 0x912f, 0x0260, 4},	//费率1-4//

		
		{ 0x9130, 0x0669, 1},	//一象限无功总电能//
		{ 0x9131, 0x0663, 1},	//一象限费率1无功电能//
		{ 0x9132, 0x0660, 1},	//一象限费率2无功电能//
		{ 0x9133, 0x0661, 1},	//一象限费率3无功电能//
		{ 0x9134, 0x0662, 1},	//一象限费率4无功电能
		{ 0x913f, 0x0660, 4},	//费率1-4//

		{ 0x9140, 0x0969, 1},	//四象限无功总电能//
		{ 0x9141, 0x0963, 1},	//四象限费率1无功电能//
		{ 0x9142, 0x0960, 1},	//四象限费率2无功电能//
		{ 0x9143, 0x0961, 1},	//四象限费率3无功电能//
		{ 0x9144, 0x0962, 1},	//四象限费率4无功电能//
		{ 0x914f, 0x0960, 4},	//费率1-4//


		{ 0x9150, 0x0769, 1},	//二象限无功总电能//
		{ 0x9151, 0x0763, 1},	//二象限费率1无功电能//
		{ 0x9152, 0x0760, 1},	//二象限费率2无功电能//
		{ 0x9153, 0x0761, 1},	//二象限费率3无功电能//
		{ 0x9154, 0x0762, 1},	//二象限费率4无功电能//
		{ 0x915f, 0x0760, 4},	//费率1-4//
		
		{ 0x9160, 0x0869, 1},	//三象限无功总电能//
		{ 0x9161, 0x0863, 1},	//三象限费率1无功电能//
		{ 0x9162, 0x0860, 1},	//三象限费率2无功电能//
		{ 0x9163, 0x0861, 1},	//三象限费率3无功电能//
		{ 0x9164, 0x0862, 1},	//三象限费率4无功电能//
		{ 0x916f, 0x0860, 4},	//费率1-4//
		

		{ 0xa010, 0x1109, 1},	//正向有功总需量//
		{ 0xa011, 0x1103, 1},	//正向费率1有功总需量//
		{ 0xa012, 0x1100, 1},	//正向费率2有功总需量//
		{ 0xa013, 0x1101, 1},	//正向费率3有功总需量//
		{ 0xa014, 0x1102, 1},	//正向费率4有功总需量//
		{ 0xa01f, 0x1100, 4},	//费率1-4//

		{ 0xa020, 0x1009, 1},	//反向有功总需量//
		{ 0xa021, 0x1003, 1},	//反向费率1有功总需量//int ReadEdmiMeterDateTime(MpComProperty *mpProperty, INT16U LCId, INT8U *pBuff, INT16U *pLength)
		{ 0xa022, 0x1000, 1},	//反向费率2有功总需量//
		{ 0xa023, 0x1001, 1},	//反向费率3有功总需量//
		{ 0xa024, 0x1002, 1},	//反向费率4有功总需量//
		{ 0xa02f, 0x1000, 4},	//费率1-4//
		
		{ 0xb010, 0x8109, 1},	//正向有功总需量产生时间//
		{ 0xb011, 0x8103, 1},	//正向费率1有功总需量产生时间//
		{ 0xb012, 0x8100, 1},	//正向费率2有功总需量产生时间//
		{ 0xb013, 0x8101, 1},	//正向费率3有功总需量产生时间//
		{ 0xb014, 0x8102, 1},	//正向费率4有功总需量产生时间//
		{ 0xb01f, 0x8100, 4},	//费率1-4//
		
		
		{ 0xb020, 0x8009, 1},	//反向有功总需量产生时间//
		{ 0xb021, 0x8003, 1},	//反向费率1有功总需量产生时间//
		{ 0xb022, 0x8000, 1},	//反向费率2有功总需量产生时间//
		{ 0xb023, 0x8001, 1},	//反向费率3有功总需量产生时间//
		{ 0xb024, 0x8002, 1},	//反向费率4有功总需量产生时间//
		{ 0xb02f, 0x8000, 4},	//费率1-4//

		{ 0xb611, 0xe000, 1},	//实时电压A//
		{ 0xb612, 0xe001, 1},	//实时电压B//
		{ 0xb613, 0xe002, 1},	//实时电压C//
		{ 0xb61f, 0xe000, 3},	//实时电压A,B,C//
		
		{ 0xb621, 0xe010, 1},	//实时电流A//
		{ 0xb622, 0xe011, 1},	//实时电流C//
		{ 0xb623, 0xe012, 1},	//实时电流B//
		{ 0xb62f, 0xe010, 3},	//实时电流A,B,C//
		
		{ 0xb630, 0xe033, 1},	//实时有功总功率//
		{ 0xb631, 0xe030, 1},	//实时有功功率A//
		{ 0xb632, 0xe031, 1},	//实时有功功率B//
		{ 0xb633, 0xe032, 1},	//实时有功功率C//
		{ 0xb63f, 0xe030, 4},	

		{ 0xb640, 0xe043, 1},	//实时无功总功率//
		{ 0xb641, 0xe040, 1},	//实时无功功率A//
		{ 0xb642, 0xe041, 1},	//实时无功功率B//
		{ 0xb643, 0xe042, 1},	//实时无功功率C//
		{ 0xb64f, 0xe040, 4},	
		
		{ 0xb650, 0xe026, 1}	//实时总功率因数//
};
int EdmiReadInstantaneousData(MpComProperty *mpProperty,INT16U LCId, INT8U *pBuff, INT16U *pLength);
int EDMILogout(MpComProperty *mpProperty);
int EdmiReadEnergy(MpComProperty *mpProperty, INT16U LCId, INT8U *pBuff,INT16U bufsize,		INT16U  *psize);
int IsSlaveEdmiId(INT16U id);
int ReadEDMIRegData(MpComProperty *mpProperty,INT8U cmd,INT8U *pCmdData,int CmdDataLen, INT8U *pDataBuff);
void EDMIReadFrame(INT8U *pBuf, INT16U *pFrameSize);
int EDMISendFrame(INT32U dst, INT32U src, INT16U sn, INT8U cmd, INT8U *pcmddata, INT16U cmdsize);
int IsFunctionByte(INT8U c);
int FilterEDMIFrame(INT32U dst, INT32U src, INT16U sn, INT8U *pBuf, int len);
int GetEDMICmdRespondData(INT32U dst, INT32U src, INT16U sn, INT8U *pRespond);
void InitEdmiSn(void);

int ReadEDMIData(INT32U Addr,MpComProperty *mpProperty , INT8U *pDataBuff);


double ByteOrder_d(double arg);
int IsEdmiWriteId( INT16U LCId);
int IsEdmiReadId( INT16U LCId);
INT16U ByteOrder_i(INT16U arg);
void UpdateEdmiSn(void);
void  MaskEDMIAddr(MeterAddrType *pMeterAddr, INT32U *pEdmiAddr);
int EDMI_RecvFrame(int fd, INT8U *pbuf, INT16U bufsize, INT16U * psize);
int EdmiReadDemandOneIdData(MpComProperty *mpProperty, INT16U LCId, INT8U *pBuff, INT16U *pLength);
int EdmiReadInstantaneousOneIdData(MpComProperty *mpProperty, INT16U LCId, INT8U *pBuff, INT16U *pLength);
int ReadEdmiMeterDateTime(MpComProperty *mpProperty, INT16U LCId, INT8U *pBuff, INT16U *pLength);

int fd;
INT16U  gEdmiSn;
int  InitEdmiCom(INT8U uart,int nSpeed,int nDataBits,char Parity,int nStopBit)
{
		fd = 	OpenCom(uart);
		if(fd > 0)
		{
				SetComOpt(fd,nSpeed,nDataBits,Parity,nStopBit);
				return  fd;
		}
		else
		{
			printf("Open Com Error\n");
			return E_COM_OTHER;
		}
}

INT32U ByteOrder_l(INT32U arg)
{
	union {
		INT32U w;
		char c[4];
	}u;
	char t;

	u.w = arg;
	
	t = u.c[0];
	u.c[0] = u.c[3];
	t = u.c[1];
	u.c[1] = u.c[2];
	u.c[2] = t;

	return u.w;
}


double ByteOrder_d(double arg)
{
	union{
		double d_data;
		char c[8];
	}u;

	char t;
	int i;

	u.d_data = arg;
	for(i=0; i<4; i++)
	{
		t = u.c[i];
		u.c[i]=u.c[7-i];
		u.c[7-i]=t;
	}
	return u.d_data;
return  0;
}

INT16U ByteOrder_i(INT16U arg)
{
	union {
		INT16U w;
		char c[2];
	}u;
	char t;

	u.w = arg;
	
	t = u.c[0];
	u.c[0] = u.c[1];
	u.c[1] = t;
	
	return u.w;
}

/*****************************************************************************************
函数名称:      void SlaveEDMIRxStateInit(void)
功能说明:      EDMI协议电表接收数据包状态初始化
输入参数:      
输出参数:      
其它说明:      
*****************************************************************************************/
void SlaveEDMIRxStateInit(void)
{ 
	gSlaveEDMIRxState.state = SLAVEEDMI_RX_NULL;
	gSlaveEDMIRxState.offset = 0;
	gSlaveEDMIRxState.size = 1;
	gSlaveEDMIRxState.dleflag = 0;
}


//===============================================================================
// Function    : void SlaveWriteFrame_645(INT8U *addr, INT8U ctrlCode, INT8U *pData, INT8U dataSize)
// Parameter   :
//              
// Return      : 
// Description : write a frame
//===============================================================================
int EDMISendFrame(INT32U dst, INT32U src, INT16U sn, INT8U cmd, INT8U *pcmddata, INT16U cmdsize)
{
	INT8U *ptr, i;
	INT16U size;
	INT8U buff[4];
	INT8U HeadBuff[20];
	INT16U crc;
	INT16U length;
	INT8U gEDMISendBuff[METER_FRAME_SIZE];

	length=0;
	crc=0;

	ptr = gEDMISendBuff;
	
	gEDMISendBuff[length++] = EDMI_STX;
	crc = mUpdCrc(crc, gEDMISendBuff[0]);
	gEDMISendBuff[length++] = EDMI_EXP_CH;
	crc = mUpdCrc(crc, gEDMISendBuff[1]);
 
	ptr = HeadBuff;
	size = 0;
	
	*(INT32U *)ptr = ByteOrder_l(dst);
	ptr += 4;
	size += 4;

	*(INT32U *)ptr = ByteOrder_l(src);
	ptr += 4;
	size += 4;

	*(INT16U *)ptr = ByteOrder_i(sn);
	ptr += 2;
	size += 2;
    
	*(ptr++) = cmd;
	size++;

	for(i=0; i<size; i++)
	{
		if(IsFunctionByte(HeadBuff[i])==TRUE)
		{
			gEDMISendBuff[length++] = EDMI_DLE;
			gEDMISendBuff[length++] = HeadBuff[i]|0x40;
		}
		else
		{
			gEDMISendBuff[length++] = HeadBuff[i];
		}
		crc = mUpdCrc(crc, HeadBuff[i]);
			
	}
	
	for(i=0; i<cmdsize; i++)
	{
		if(IsFunctionByte(*(pcmddata+i))==TRUE)
		{
			gEDMISendBuff[length++] = EDMI_DLE;
			gEDMISendBuff[length++] = *(pcmddata+i)|0x40;
		}
		else
		{
			gEDMISendBuff[length++] = *(pcmddata+i);
		}
		crc = mUpdCrc(crc,  *(pcmddata+i));
	}

	buff[0]=*(((INT8U *)&crc)+1);
	buff[1]=*((INT8U *)&crc);

	for(i=0; i<2; i++)
	{
		if(IsFunctionByte(*(buff+i))==TRUE)
		{
			gEDMISendBuff[length++] = EDMI_DLE;
			gEDMISendBuff[length++] = *(buff+i)|0x40;
			
		}
		else
		{
			gEDMISendBuff[length++] = *(buff+i);
		}
		//crc = UpdCrc(crc,  *(buff+i));
	}
	
	gEDMISendBuff[length++] = EDMI_ETX;
#ifdef DEBUG_PRINT
		printf("\nEdmi send to Meter: \n");
		if(length > 0)
		printHex(gEDMISendBuff, length);
#endif

	//send com buff
  return SlaveSendFrame(fd, gEDMISendBuff, length,300);
}

int IsFunctionByte(INT8U c)
{
	if(c==EDMI_STX||c==EDMI_ETX||c==EDMI_XON||c==EDMI_XOFF||c==EDMI_DLE)
	{
		
		return TRUE;
	}
	else
	{
		return FALSE;
	}
}
int FilterEDMIFrame(INT32U dst, INT32U src, INT16U sn, INT8U *pBuf, int len)
{
	INT16U crc;
	
	EDMICmdExpRespondType *pEdmiRespond;

	pEdmiRespond=(EDMICmdExpRespondType *)pBuf;
	

	if( pEdmiRespond->dst != ByteOrder_l(dst) || pEdmiRespond->src != ByteOrder_l(src) || pEdmiRespond->sn !=ByteOrder_i(sn)) 
		return FALSE;
	crc=0;
	crc = mGetCRCTT(pBuf, len-3, crc);
//printf("crc=%x\n", crc);
	if((crc>>8) != *(pBuf+len-3) ||(crc&0x00ff) != *(pBuf+len-2))
	{
		return FALSE;
	}
	
	return TRUE;
}


int EDMI_RecvFrame(int fd, INT8U *pbuf, INT16U bufsize, INT16U * psize)
{
	INT8U retvalue ;
	INT16U size;
	
	*psize = 0;
	while(1)
	{
		retvalue = SlaveRecvFrame(fd, gSlaveEDMIRxData + gSlaveEDMIRxState.offset, gSlaveEDMIRxState.size, &size,3);
		if(retvalue == SUCCESS)
		{
			if(size > 0)
			{
				gSlaveEDMIRxState.offset += size;
				gSlaveEDMIRxState.size -= size;
				if(gSlaveEDMIRxState.size == 0)
				{
					switch(gSlaveEDMIRxState.state)
					{
						case SLAVEEDMI_RX_NULL:
							if(gSlaveEDMIRxData[gSlaveEDMIRxState.offset - 1] == EDMI_STX)
							{
								gSlaveEDMIRxState.state = SLAVEEDMI_RX_DATA;
								gSlaveEDMIRxState.size = 1;
							}
							else
							{
								SlaveEDMIRxStateInit();
							}

							break;
						case SLAVEEDMI_RX_DATA:
							if(gSlaveEDMIRxState.offset > EDMI_FRAME_SIZE)
							{
								SlaveEDMIRxStateInit();
								return E_BUFF_FULL;
							}
							else
							{
								if(gSlaveEDMIRxData[gSlaveEDMIRxState.offset - 1] == EDMI_ETX)
								{
									memcpy(pbuf, gSlaveEDMIRxData, gSlaveEDMIRxState.offset);
									SlaveEDMIRxStateInit();
									*psize = gSlave645RxState.offset;
									return SUCCESS;
								}
								else if(gSlaveEDMIRxData[gSlaveEDMIRxState.offset - 1] == EDMI_DLE)
								{
									gSlaveEDMIRxState.dleflag = 1;
									gSlaveEDMIRxState.offset --;
								}
								else if(gSlaveEDMIRxState.dleflag == 1)
								{
									gSlaveEDMIRxState.dleflag = 0;
									gSlaveEDMIRxData[gSlaveEDMIRxState.offset - 1] &= EDMI_DLE_MASK;
								}
								gSlaveEDMIRxState.size = 1;
							}
							break;
						default:
							SlaveEDMIRxStateInit();
							break;
					}
				}
			}
			else
			{
				break;
			}
		}
		else
		{
			break;
		}
	}
	return retvalue;
}
int  GetEDMICmdRespondData(INT32U dst, INT32U src, INT16U sn, INT8U *pRespond)
{
	EDMICmdExpRespondType *pRespondFrame;
	INT16U frameSize;
	int size;
	INT8U retvalue;
	long dtime;
	INT32U timeout;
	INT8U recvBuff[EDMI_FRAME_SIZE];
	time_t curTime;
	time_t startTime;
	
	SlaveEDMIRxStateInit();

	timeout = SLAVE645_WAIT_OUT*2;

	time(&startTime);
	time(&curTime);
	//difftime 返回精确到秒
	while((dtime = difftime(curTime,startTime)) <  timeout) 
	{
		time(&curTime);
		frameSize = 0;
		retvalue = EDMI_RecvFrame(fd,recvBuff, EDMI_FRAME_SIZE,&frameSize);
		if(retvalue == SUCCESS)
		{	
			if(frameSize > 0)
			{
#if SLAVE_DEBUG_EN > 0
				printf("recvBuff %d:\n", frameSize);
				mPrintfHex(recvBuff, frameSize);
#endif				
				if(FilterEDMIFrame(dst, src, sn, recvBuff, frameSize) == TRUE)
				{
#if SLAVE_DEBUG_EN > 0

⌨️ 快捷键说明

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