123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424 |
- // ProtocolPMC916.cpp: implementation of the CProtocolModbus class.
- //
- //////////////////////////////////////////////////////////////////////
- #include "stdafx.h"
- #include "ProtocolModbus.h"
- #include "winsock2.h"
- #include "icpdas.h"
- #ifdef _DEBUG
- #undef THIS_FILE
- static char THIS_FILE[]=__FILE__;
- #define new DEBUG_NEW
- #endif
- //////////////////////////////////////////////////////////////////////
- // Construction/Destruction
- //////////////////////////////////////////////////////////////////////
- CProtocolModbus::CProtocolModbus() : CProtocol()
- {
- InitializeCriticalSection( &m_csReadFinished );
- InitializeCriticalSection( &m_csWrFinished );
- MTVERIFY( m_hSemComm = CreateEvent( NULL, TRUE, TRUE, "DLL_IcpdasComm" ) );
- }
- CProtocolModbus::~CProtocolModbus()
- {
- DeleteCriticalSection( &m_csReadFinished );
- DeleteCriticalSection( &m_csWrFinished );
- MTVERIFY( CloseHandle( m_hSemComm ) );
- }
- int CProtocolModbus::WorkMain(
- int nAddr, //设备地址
- BYTE Start,//起始位
- BYTE StartAddr[2],//起始地址
- int nRegNum,//读取的寄存器个数
- BYTE FuncCode[2],
- int nDataLen,
- BYTE byWithAddrFlag,
- char chMsg[80])
- {
- if(!m_pComm)
- return ERR_CODE_ICPDAS_COM_FAULT; // 串口通信故障
- int nRet;
- nRet = RequestStatus(
- nAddr,
- Start,
- StartAddr,
- nRegNum,
- FuncCode);
- if( nRet != 0 )
- {
- return nRet; // 串口忙
- }
- nRet = ResponseStatus(nDataLen, byWithAddrFlag, chMsg);
- return nRet;
- }
- int CProtocolModbus::ResponseStatus(int nDataLen, BYTE byWithAddrFlag, char chMsg[80])
- {
- int nLen = 0;
- int nProcessLen = 0;
- int nReadLen = 0;
- RESPONSE_STRUCT structResponse;
- memset( &structResponse, 0, sizeof(RESPONSE_STRUCT) );
- if (nDataLen <= 0)
- {
- TRACE("变量长度小于等于0,为非法变量");
- return ERR_CODE_ICPDAS_COM_VARLEN;
- }
- if (byWithAddrFlag == '1')
- nLen = sizeof(RESPONSE_STRUCT) - sizeof(structResponse.StrRtnMsg) -
- sizeof(structResponse.StatusStruct.RtnByteNum) + nDataLen;
- else if (byWithAddrFlag == '0')
- nLen = sizeof(RESPONSE_STRUCT) - sizeof(structResponse.StrRtnMsg) -
- sizeof(structResponse.StatusStruct.RtnByteNum) -
- sizeof(structResponse.StatusStruct.AddrCode) + nDataLen;
- char *pBuffer = new char[ nLen ];
- memset(pBuffer, 0, nLen);
- nReadLen = ReadMessage((BYTE *)pBuffer, nLen);
- if( nReadLen <= 0)
- {
- // 串口没有读到数据
- TRACE("串口没有读到数据!\r\n");
- SetEvent( m_hSemComm );
- if( pBuffer != NULL)
- {
- delete[] pBuffer;
- pBuffer = NULL;
- }
- return ERR_CODE_ICPDAS_COM_READ_NO_DATA;
- }
- else if( nReadLen < nLen )
- {
- if (pBuffer[0] == '?')//无效应答包
- {
- delete[] pBuffer;
- pBuffer = NULL;
- return ERR_CODE_ICPDAS_COM_INVALIDRES;
- }
- TRACE("长度没有收够,断续接收,止到收完为止!\r\n");
- #if DEBUG_PROTOCOL
- SetEvent( m_hSemComm );
- if( pBuffer )
- {
- delete[] pBuffer;
- pBuffer = NULL;
- }
- return ERR_CODE_ICPDAS_COM_FAULT;
- #else
- nProcessLen += nReadLen;
- nReadLen = ReadMessage( (BYTE *)(pBuffer + nProcessLen), nLen - nProcessLen );
- while( nReadLen != nLen - nProcessLen )
- {
- if( nReadLen == 0 )
- {
- SetEvent( m_hSemComm );
- if( pBuffer )
- {
- delete[] pBuffer;
- pBuffer = NULL;
- }
- return ERR_CODE_ICPDAS_COM_READ_NO_DATA; // 还是没有收到数据,直接返回
- }
- nProcessLen += nReadLen;
- nReadLen = ReadMessage( (BYTE *)(pBuffer + nProcessLen), nLen - nProcessLen);
- }
- if( nReadLen == nLen )
- {
- //goto NormalProcess;
- if( pBuffer != NULL)
- {
- delete[] pBuffer;
- pBuffer = NULL;
- }
- SetEvent( m_hSemComm );
- return ERR_CODE_ICPDAS_COM_FAULT;
- }
- #endif
- }
- else if( nReadLen > nLen )
- {
- // 完全代码,不一定能执行到
- TRACE("接收的长度超时所需的长度,认为是非法包,扔掉\r\n");
- SetEvent( m_hSemComm );
-
- if( pBuffer != NULL)
- {
- delete[] pBuffer;
- pBuffer = NULL;
- }
- return ERR_CODE_ICPDAS_COM_READ_LEN_OVER;
- }
- else if(nReadLen == nLen)
- {
- if (pBuffer[0] == '?')//无效应答包
- {
- delete[] pBuffer;
- pBuffer = NULL;
- SetEvent( m_hSemComm );
- return ERR_CODE_ICPDAS_COM_INVALIDRES;
- }
- }
- // 判断校验
- EnterCriticalSection( &m_csWrFinished );
-
- int nCrease = 0;
- memset(&m_structResponse, 0,sizeof(RESPONSE_STRUCT));
- nCrease = sizeof(m_structResponse.StatusStruct.Start);
- memcpy( &m_structResponse.StatusStruct.Start, pBuffer, nCrease );
-
- if (byWithAddrFlag == '1')
- {
- memcpy( &m_structResponse.StatusStruct.AddrCode, pBuffer +
- nLen,
- sizeof(m_structResponse.StatusStruct.AddrCode) );
- nCrease += sizeof(m_structResponse.StatusStruct.AddrCode);
- }
-
- for( int i = 0; i < nDataLen; i++ )
- {
- chMsg[i] = pBuffer[nCrease + i];
- //m_structResponse.StrRtnMsg[i] = pBuffer[nCrease + i];
- }
- m_structResponse.StatusStruct.RtnByteNum = nDataLen;
- LeaveCriticalSection(&m_csWrFinished);
- // 设置串口等待事件为有信号
- SetEvent( m_hSemComm );
-
- if( pBuffer != NULL)
- {
- delete[] pBuffer;
- pBuffer = NULL;
- }
- return 0;
- }
- int CProtocolModbus::RequestStatus(
- int nAddr, //设备地址
- BYTE Start, //起始位
- BYTE StartAddr[2], //起始地址
- int nRegNum, //读取的寄存器个数
- BYTE FuncCode[2]) //功能码
- {
- int ivarid = 55;
- // CProtocol* protocol;
- int iLen = sizeof(REQUESTPARAM);
- char *pBuf = new char[iLen];
- int iSendLen = 0;
- REQUESTPARAM RequestPara;
- memset(&RequestPara, 0, iLen);
-
- RequestPara.Start = Start;
- memcpy(RequestPara.StartAddr, StartAddr, sizeof(RequestPara.StartAddr));
- memcpy(RequestPara.FuncCode, FuncCode, sizeof(RequestPara.FuncCode));
- RequestPara.END = 0x0D;
- memcpy(pBuf, &RequestPara.Start, sizeof(RequestPara.Start));
- iSendLen = iSendLen + sizeof(RequestPara.Start);
- BYTE szAddr[2] = {0};
- szAddr[0] = ByteToAscii((nAddr >> 4) & 0x0f);
- szAddr[1] = ByteToAscii(nAddr & 0x0f);
- memcpy(pBuf + iSendLen, szAddr, sizeof(szAddr));
- iSendLen = iSendLen + sizeof(szAddr);
- if (RequestPara.FuncCode[0] == 'L')
- {
- memcpy(pBuf + iSendLen, RequestPara.FuncCode, sizeof(RequestPara.FuncCode));
- iSendLen = iSendLen + sizeof(RequestPara.FuncCode);
- }
- else if (RequestPara.FuncCode[0] == '-' && RequestPara.FuncCode[1] == '1')
- {
- ;
- }
- else
- {
- memcpy(pBuf + iSendLen, RequestPara.FuncCode + 1, sizeof(RequestPara.FuncCode) - 1);
- iSendLen = iSendLen + sizeof(RequestPara.FuncCode) - 1;
- }
- memcpy(pBuf + iSendLen, &RequestPara.END, sizeof(RequestPara.END));
- iSendLen = iSendLen + sizeof(RequestPara.END);
- if( WaitForSingleObject( m_hSemComm, 0 ) == WAIT_OBJECT_0 ) // 有信号才写串口
- {
- ResetEvent( m_hSemComm );
- int nResult = WriteMessage((unsigned char *)pBuf, iSendLen);
- if( nResult == iSendLen )
- {
- }
- else
- {
- delete []pBuf;
- SetEvent( m_hSemComm );
- return EER_CODE_ICPDAS_COM_WRITE_DATA;
- }
- }
- else
- {
- delete []pBuf;
- return ERR_CODE_ICPDAS_COM_BUSY;
- }
- delete []pBuf;
- return 0;
- }
- BOOL CProtocolModbus::InitParam(PPORTPARAM pPortParam, CCommAsyn *pComm)
- {
- int addr=pPortParam->StartAddr;
- m_pComm=pComm;
- return TRUE;
- }
- int CProtocolModbus:: WriteCommand(char DataBuffer[80], int nDataLen)
- {
- int iResult = 0;
- if(!m_pComm)
- return ERR_CODE_ICPDAS_COM_FAULT;
- iResult = RequestWrStatus(DataBuffer, nDataLen);
- if (iResult == 0)
- return ResponseWrStatus(DataBuffer, nDataLen);
- else
- return iResult;
- }
- int CProtocolModbus::RequestWrStatus( char DataBuffer[80], int nDataLen)//请求写数据
- {
- if( WaitForSingleObject( m_hSemComm, 0 ) == WAIT_OBJECT_0 ) // 有信号才写串口
- {
- ResetEvent( m_hSemComm );
- int iResult = WriteMessage((unsigned char *)DataBuffer, nDataLen);
- if (iResult == nDataLen)
- {
- return 0;
- }
- else
- {
- SetEvent( m_hSemComm );
- return EER_CODE_ICPDAS_COM_WRITE_DATA;
- }
- }
- else
- {
- return EER_CODE_ICPDAS_COM_WRITE_DATA;
- }
- }
- int CProtocolModbus::ResponseWrStatus( char DataBuffer[80], int nDataLen)
- {
- char chBuf = 0;
- int iReadLen = ReadMessage((BYTE *)&chBuf, sizeof(chBuf));
- if( iReadLen <= 0) // 串口没有读到数据
- {
- SetEvent( m_hSemComm );
- return ERR_CODE_ICPDAS_COM_READ_NO_DATA;
- }
- SetEvent( m_hSemComm );
- if (chBuf == '>')
- {
- return 0;
- }
- else
- {
- return ERR_CODE_ICPDAS_COM_INVALIDRES;
- }
- }
- void strReverse( char *str )
- {
- int l = strlen(str);
- for( int i = 0; i < l; i++ )
- {
- for(int i = 0; i < l; i++)
- {
- if( str[i] >= 'A' && str[i] <= 'Z' )
- {
- str[i] += 32;
- }
- else if(str[i] >= 'a' && str[i] <= 'z')
- {
- str[i] -= 32;
- }
- }
- }
- }
- char lowercase2uppercase(BYTE btSrc)
- {
- if( btSrc >= 'a' && btSrc <= 'z' )
- {
- return btSrc - 'a' + 'A';
- }
- return btSrc;
- }
- char ByteToAscii(BYTE btSrc)
- {
- char chDest;
- if( btSrc < 10 )
- {
- chDest = (char)(btSrc % 10 + '0');
- chDest = lowercase2uppercase(chDest);
- return chDest;
- }
- else
- {
- chDest = ByteToAscii( btSrc / 10 ) + (char)( btSrc % 10 + '0' );
- chDest = lowercase2uppercase(chDest);
- return chDest;
- }
- }
- WORD AsciiToBYTE(BYTE btSrc)
- {
- WORD chDest = (WORD)btSrc;
- if ((btSrc >= 'A')&&(btSrc <= 'F'))
- {
- chDest = chDest - 'A' + 10;
- }
- else if ((btSrc >= 'a')&&(btSrc <= 'f'))
- {
- chDest = chDest - 'a' + 10;
- }
- else if ((btSrc >= '0')&&(btSrc <= '9'))
- {
- chDest -= '0';
- }
- return chDest;
- }
|