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