📄 slaveedmi.c
字号:
#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 + -