📄 slavews.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 + -