123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557 |
- // ProtocolPMC916.cpp: implementation of the CProtocolModbus class.
- //
- //////////////////////////////////////////////////////////////////////
- #include "stdafx.h"
- #include "ProtocolModbus.h"
- #include "winsock2.h"
- #include "stulz.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, 0 ) );
- }
- CProtocolModbus::~CProtocolModbus()
- {
- DeleteCriticalSection( &m_csReadFinished );
- DeleteCriticalSection( &m_csWrFinished );
- MTVERIFY( CloseHandle( m_hSemComm ) );
- }
- int CProtocolModbus::WorkMain(SETBASEPARAM SetBasePara, int nDataLen, int iCmdPos, int iCmdLen, char chMsg[10])
- {
- if(!m_pComm)
- return ERR_CODE_AIR_STULZ_COM_FAULT; // 串口通信故障
- int nRet;
- nRet = RequestStatus(SetBasePara);
- if( nRet != 0 )
- {
- return nRet; // 串口忙
- }
- nRet = ResponseStatus( nDataLen, iCmdPos, iCmdLen, chMsg);
- return nRet;
- }
- int CProtocolModbus:: WriteCommand(char DataBuffer[80], char ResDataBuffer[2])
- {
- int iResult = 0;
- if(!m_pComm)
- return ERR_CODE_AIR_STULZ_COM_FAULT;
- iResult = RequestWrStatus(DataBuffer);
- if (iResult == 0)
- return ResponseWrStatus(ResDataBuffer);
- else
- return iResult;
- }
- //nDataLen 数据的总长度,iCmdPos 命令位置,iCmdLen 变量数据长度,chMsg 变量数据
- int CProtocolModbus::ResponseStatus(int nDataLen, int iCmdPos, int iCmdLen, char chMsg[10])
- {
- RESPONSE_STRUCT structResponse;
- memset( &structResponse, 0, sizeof(RESPONSE_STRUCT) );
- if (nDataLen <= 0)
- {
- TRACE("变量长度小于等于0,为非法变量");
- return ERR_CODE_AIR_STULZ_COM_VARLEN;
- }
- int nLen = sizeof(RESPONSE_STRUCT) - sizeof(structResponse.StrRtnMsg) + nDataLen;
-
- char *pBuffer = new char[ nLen ];
- memset(pBuffer, 0, nLen);
- int nProcessLen = 0;
- int nReadLen = 0;
- nReadLen = ReadMessage((BYTE *)pBuffer, nLen);
- if( nReadLen <= 0)
- {
- // 串口没有读到数据
- TRACE("串口没有读到数据!\r\n");
- SetEvent( m_hSemComm );
- if( pBuffer != NULL)
- {
- delete[] pBuffer;
- pBuffer = NULL;
- }
- return ERR_CODE_AIR_STULZ_COM_READ_NO_DATA;
- }
- else if( nReadLen < nLen )
- {
- TRACE("长度没有收够,断续接收,止到收完为止!\r\n");
- #if DEBUG_PROTOCOL
- SetEvent( m_hSemComm );
- if( pBuffer )
- {
- delete[] pBuffer;
- pBuffer = NULL;
- }
- return ERR_CODE_AIR_STULZ_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_AIR_STULZ_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;
- }
- return ERR_CODE_AIR_STULZ_COM_FAULT;
- }
- #endif
- }
- else if( nReadLen > nLen )
- {
- // 完全代码,不一定能执行到
- TRACE("接收的长度超时所需的长度,认为是非法包,扔掉\r\n");
- SetEvent( m_hSemComm );
-
- if( pBuffer != NULL)
- {
- delete[] pBuffer;
- pBuffer = NULL;
- }
- return ERR_CODE_AIR_STULZ_COM_READ_LEN_OVER;
- }
- else if( nReadLen == nLen ) // 长度刚好
- {
- unsigned char chRegNum = pBuffer[2];
- // 判断数据长度
- if (chRegNum == (unsigned char)nDataLen) goto NormalProcess;
-
- if( chRegNum > (unsigned char)nDataLen)
- {
- TRACE("请求寄存器个数超时所需的长度,认为是非法包,收完扔掉\r\n");
- #if DEBUG_PROTOCOL
- SetEvent( m_hSemComm );
- if( pBuffer )
- {
- delete[] pBuffer;
- pBuffer = NULL;
- }
- return ERR_CODE_AIR_STULZ_COM_READ_LEN_OVER;
- #else
- nProcessLen += nReadLen;
- nReadLen = ReadMessage( (BYTE *)(pBuffer + nProcessLen), chRegNum - nDataLen);
- SetEvent( m_hSemComm );
- if( pBuffer != NULL)
- {
- delete[] pBuffer;
- pBuffer = NULL;
- }
- return ERR_CODE_AIR_STULZ_COM_READ_LEN_OVER;
- #endif
- }
- else//小于
- {
- TRACE("读到数据长度小于需要的数据长度!\r\n");
- SetEvent( m_hSemComm );
-
- if( pBuffer != NULL)
- {
- delete[] pBuffer;
- pBuffer = NULL;
- }
- return ERR_CODE_AIR_STULZ_COM_READ_LEN_OVER;
- }
- }
- NormalProcess:
- // 判断校验
- int iCrc = GetCheckSum((byte*) pBuffer, nLen - 2);
- BYTE high = iCrc>>8&0xff;
- BYTE low = iCrc&0xff;
- if( !( ((byte)pBuffer[nLen - 2] == low) && ((byte)pBuffer[nLen - 1] ==high) ) )
- {
- TRACE("crc 校验失败!\r\n");
- SetEvent( m_hSemComm );
-
- if( pBuffer != NULL)
- {
- delete[] pBuffer;
- pBuffer = NULL;
- }
- return ERR_CODE_AIR_STULZ_COM_LRC_LOST;
- }
- EnterCriticalSection( &m_csWrFinished );
- memcpy( &m_structResponse.StatusStruct, pBuffer, sizeof(STATUS_STRUCT) );
- int nIndex = 0;
- for( int i = iCmdPos; i < (iCmdPos + iCmdLen); i++ )
- {
- int nTmp = sizeof(STATUS_STRUCT) + i;
- chMsg[nIndex] = pBuffer[sizeof(STATUS_STRUCT) + i];
- nIndex++;
- }
- LeaveCriticalSection(&m_csWrFinished);
- // 设置串口等待事件为有信号
- SetEvent( m_hSemComm );
-
- if( pBuffer != NULL)
- {
- delete[] pBuffer;
- pBuffer = NULL;
- }
- return 0;
- }
- int CProtocolModbus::RequestStatus(SETBASEPARAM SetBasePara)
- {
- REQUESTPARAM RequestPara;
- int iLen = sizeof(REQUESTPARAM);
-
- #if 0
- if (SetBasePara.nStartAddr==0)
- iLen -=sizeof(RequestPara .StartAddr);
- #endif
- if (SetBasePara.FuncCode==1 || //长状态请求1
- SetBasePara.FuncCode==33 || //长状态请求2
- SetBasePara.FuncCode==9 || //控制器状态2
- SetBasePara.FuncCode==10 ||//控制器ID
- SetBasePara.FuncCode==11 ||//单元配置
- SetBasePara.FuncCode==12)//c5000增加项
- {
- iLen -= sizeof(RequestPara.StartAddr);
- }
- char *pData = new char[iLen];
- memset( pData, 0, iLen );
- memset( &RequestPara, 0, iLen );
- RequestPara.AddrCode = SetBasePara.nAddr; //地址码
- RequestPara.FuncCode = SetBasePara.FuncCode; //功能码
- RequestPara.StartAddr = SetBasePara.nStartAddr; //起始地址
- int iTmpLen = sizeof(RequestPara.AddrCode) + sizeof(RequestPara.FuncCode);// + sizeof(RequestPara.Number);
- memcpy(pData, &RequestPara, iTmpLen);
-
- if (SetBasePara.FuncCode==1 || //长状态请求1
- SetBasePara.FuncCode==33 || //长状态请求2
- SetBasePara.FuncCode==9 || //控制器状态2
- SetBasePara.FuncCode==10 ||//控制器ID
- SetBasePara.FuncCode==11 ||//单元配置
- SetBasePara.FuncCode==12)//c5000增加项
- {
- RequestPara.Number = 2; //下面字节数
- memcpy( pData + iTmpLen, &RequestPara.Number, sizeof(RequestPara.Number) );
- iTmpLen += sizeof(RequestPara.Number);
- }
- else
- {
- memcpy(pData + iTmpLen, &RequestPara.StartAddr, sizeof(RequestPara .StartAddr));
- iTmpLen +=sizeof(RequestPara .StartAddr);
- RequestPara.Number = 3; //下面字节数
- memcpy(pData + iTmpLen, &RequestPara.Number, sizeof(RequestPara.Number) );
- iTmpLen += sizeof(RequestPara.Number);
- }
- SHORT iCheck = GetCheckSum( (BYTE*)pData, iTmpLen);
- BYTE high = iCheck>>8&0xff;
- BYTE low = iCheck&0xff;
- #if 1
- RequestPara.Crc[0] = low;
- RequestPara.Crc[1] = high;
- #else
- RequestPara.Crc[0] = high;
- RequestPara.Crc[1] = low;
- #endif
- memcpy(pData + iTmpLen, RequestPara.Crc, sizeof(RequestPara.Crc));
- if( WaitForSingleObject( m_hSemComm, 0 ) == WAIT_OBJECT_0 ) // 有信号才写串口
- {
- ResetEvent( m_hSemComm );
- int nResult = WriteMessage( (BYTE *)pData, iLen );
-
- if( nResult == iLen )
- {
- }
- else
- {
- delete []pData;
- SetEvent( m_hSemComm );
- return EER_CODE_AIR_STULZ_COM_WRITE_DATA;
- }
- }
- else
- {
- delete []pData;
- return ERR_CODE_AIR_STULZ_COM_BUSY;
- }
- delete[]pData;
- return 0;
- }
- int CProtocolModbus::RequestWrStatus(char DataBuffer[80])//请求写数据
- {
- char tmpData[4] = {0};
- memcpy(tmpData, DataBuffer, sizeof(tmpData));
- int iCheck = GetCheckSum( (BYTE*)tmpData, sizeof(tmpData));
- BYTE high = iCheck>>8&0xff;
- BYTE low = iCheck&0xff;
- DataBuffer[4] = low;
- DataBuffer[5] = high;
- if( WaitForSingleObject( m_hSemComm, 0 ) == WAIT_OBJECT_0 ) // 有信号才写串口
- {
- ResetEvent( m_hSemComm );
- int iResult = WriteMessage((unsigned char *)DataBuffer, sizeof(tmpData) + 2);
- if (iResult == ( sizeof(tmpData) + 2))
- return 0;
- else
- {
- SetEvent( m_hSemComm );
- return EER_CODE_AIR_STULZ_COM_WRITE_DATA;
- }
- }
- else
- {
- return EER_CODE_AIR_STULZ_COM_WRITE_DATA;
- }
- }
- int CProtocolModbus::ResponseWrStatus(char ResDataBuffer[2])
- {
- char chBuffer[6] = {0};
- int iProcessLen = 0;
- int iLen = sizeof(chBuffer);
- int iReadLen = ReadMessage((BYTE *)chBuffer, iLen);
- if( iReadLen <= 0) // 串口没有读到数据
- {
- SetEvent( m_hSemComm );
- return ERR_CODE_AIR_STULZ_COM_READ_NO_DATA;
- }
- else if(iReadLen< iLen)
- {
- TRACE("长度没有收够,断续接收,直到收完为止!\r\n");
- iProcessLen += iReadLen;
- iReadLen = ReadMessage( (BYTE *)(chBuffer + iProcessLen), iLen - iProcessLen );
- while( iReadLen != iLen - iProcessLen )
- {
- if( iReadLen == 0 )
- {
- SetEvent( m_hSemComm );
-
- return ERR_CODE_AIR_STULZ_COM_READ_NO_DATA;// 还是没有收到数据,直接返回
- }
- iProcessLen += iReadLen;
- iReadLen = ReadMessage( (BYTE *)(chBuffer + iProcessLen), iLen - iProcessLen);
- }
- if( iReadLen == iLen )
- {
- SetEvent( m_hSemComm );
- return ERR_CODE_AIR_STULZ_COM_FAULT;
- }
- }
- else if( iReadLen > iLen )//实际读到包长度大于要求包的长度
- {
- // 完全代码,不一定能执行到
- TRACE("接收的长度超时所需的长度,认为是非法包,扔掉\r\n");
- SetEvent( m_hSemComm );
- return ERR_CODE_AIR_STULZ_COM_READ_LEN_OVER;
- }
- else if (iReadLen == iLen)//读到的包长度相等
- {
- // 判断寄存器的个数正确吗?
- if (chBuffer[1] == 7 && chBuffer[2] == 3)
- {
- goto NormalProcess;
- }
- else
- {
- SetEvent( m_hSemComm );
- return ERR_CODE_AIR_STULZ_COM_READ_LEN_OVER;
- }
- }
- NormalProcess:
-
- char tmpData[4] = {0};
- memcpy(tmpData, chBuffer, sizeof(tmpData));
- int iCheck = GetCheckSum( (BYTE*)tmpData, sizeof(tmpData));
- BYTE high = iCheck>>8&0xff;
- BYTE low = iCheck&0xff;
- //DataBuffer[4] = low;
- //DataBuffer[5] = high;
- if( !( chBuffer[4] == low && chBuffer[5] == high ) )
- {
- TRACE("应答数据校验失败!\r\n");
- SetEvent( m_hSemComm );
- return ERR_CODE_AIR_STULZ_COM_LRC_LOST;
- }
- ResDataBuffer[0] = chBuffer[3];
- // 设置串口等待事件为有信号
- SetEvent( m_hSemComm );
- return 0;
- }
- WORD CProtocolModbus::GetCheckSum(BYTE *pBuf, int len)
- {
- WORD iSum = 0;
- WORD iCompliment;
- unsigned char chCompliment[2] = {0};
- for(int i=0; i<len; i++)//求和
- iSum += pBuf[i];
- #if 0
- if( iSum < 0 )
- {
- WORD iCompliment = iSum ;
- iCompliment = ~iCompliment;//取反
- iCompliment++;
- }
- else
- {
- iCompliment = iSum;
- }
- #else
- iCompliment = iSum ;
- iCompliment = ~iCompliment;//取反
- iCompliment++;
- #endif
- return iCompliment;
- }
- BOOL CProtocolModbus::InitParam(PPORTPARAM pPortParam, CCommAsyn *pComm)
- {
- int addr=pPortParam->StartAddr;
- m_pComm=pComm;
- return TRUE;
- }
- 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;
- }
|