#include "stdafx.h" #include "rtuprocess.h" #include "Global.h" #include "struct.h" #include "NoticeQueue.h" #include "SysLib.h" HANDLE g_RTURequestThread = NULL; HANDLE g_RTUResponseThread = NULL; DWORD g_dwRtuVariantTick = 0; CRITICAL_SECTION g_csRtuReadOneData; //rtu动态库输出函数 HINSTANCE g_hRTULibModule = NULL; RTU_DLLInitCom pRTU_DLLInitCom = NULL; RTU_DLLInit pRTU_DLLInit = NULL; RTU_DLLUnInit pRTU_DLLUnInit = NULL; RTU_DLLWrite pRTU_DLLWrite = NULL; RTU_DLLRequestWrStatusData pRTU_DLLRequestWrStatusData = NULL; int RtuResponseValue(); int RtuCommandSend(); void UnInitRtuDll(); BOOL LoadRtuDll(CString strpath) { char strFile[256] = {0}; g_hRTULibModule = NULL; sprintf(strFile, "%s\\dll\\modbusrtu.dll", strpath); InitializeCriticalSection( &g_csRtuReadOneData ); g_hRTULibModule = AfxLoadLibrary(strFile); //RTU 动态库初始化 if (NULL != g_hRTULibModule) { pRTU_DLLInitCom =( RTU_DLLInitCom)::GetProcAddress(g_hRTULibModule, "RTU_DLLInitCom"); pRTU_DLLInit = (RTU_DLLInit)::GetProcAddress(g_hRTULibModule, "RTU_DLLInit"); pRTU_DLLUnInit = (RTU_DLLUnInit)::GetProcAddress(g_hRTULibModule, "RTU_DLLUnInit"); pRTU_DLLWrite = (RTU_DLLWrite)::GetProcAddress(g_hRTULibModule, "RTU_DLLWrite"); pRTU_DLLRequestWrStatusData = (RTU_DLLRequestWrStatusData)::GetProcAddress(g_hRTULibModule, "RTU_DLLRequestWrStatusData"); return TRUE; } else { return FALSE; } } BOOL InitRtuComm(int iAddr, int iPort, int iBaudrate, int iDataBit, int iStopBit, int iParity, int iIntervals) { if( NULL != pRTU_DLLInitCom ) { //LOG4C((LOG_NOTICE, "Enter pRTU_DLLInitCom")); if (pRTU_DLLInitCom(iAddr,iPort, iBaudrate, iDataBit, iStopBit, iParity, iIntervals))//初始化串口 return TRUE; else return FALSE; } else { LOG4C((LOG_NOTICE, "pRTU_DLLInitCom is null!")); return FALSE; } } //用于只发送一次读命令特殊变量的请求 int RtuRequestSpecData(SETBASEPARAM SetBasePara, int nDataLen, int nPort, int nDevAddr, char chDevUid[20], int iVarID, int iSpecialFlag) { char chMsg[80] = {0}; int nRet = pRTU_DLLInit(nPort, nDevAddr, SetBasePara, nDataLen, chMsg); if ( nRet == 0) { //TRACE("Enter AscSingleResponseSpecialVarData\r\n"); nRet = RtuSingleResponseSpecialVarData( chDevUid, iVarID, iSpecialFlag, chMsg); //TRACE("Leave AscSingleResponseSpecialVarData\r\n"); } else { //TRACE("Rtu设备请求失败,变量ID=%d\r\n", iVarID); } //TRACE("Rtu设备请求成功\r\n"); return nRet; } int RtuSingleResponseSpecialVarData(char chDevUid[20], int iVarID, int iSpecialFlag, char chMsg[80]) { int nDeviceIndex = -1, nVarIndex = -1; BOOL bFind = FindVar(chDevUid, iVarID, nDeviceIndex, nVarIndex); if( bFind == FALSE ) return -1; CDevice *pDev = g_pDevicesManager->m_Devices[nDeviceIndex]; CBaseVar *pBaseVar = pDev->m_Vars[nVarIndex]; EnterCriticalSection( &g_csRtuReadOneData ); pDev->m_dwOnlineTick = GetTickCount(); LeaveCriticalSection( &g_csRtuReadOneData ); int nValue = 0; CString strMemos, strWarnContent; double fCoef = pBaseVar->m_dbCoefficient; if (iSpecialFlag == 10004) { short int wdValue; memcpy(&wdValue, chMsg, sizeof(short int)); nValue = ntohs(wdValue); //pBaseVar->m_dbData = (double)(nValue * fCoef); if( pBaseVar->m_nMaxValues != 0 || pBaseVar->m_nMinValues != 0 || pBaseVar->m_nMaxConvtRate != 0 || pBaseVar->m_nMinConvtRate != 0 ) { double fScale = 1.0; if( pBaseVar->m_nMaxValues - pBaseVar->m_nMinValues > 0 ) { fScale = (double)(pBaseVar->m_nMaxConvtRate - pBaseVar->m_nMinConvtRate) / (double)(pBaseVar->m_nMaxValues - pBaseVar->m_nMinValues); } if( nValue < 0.0 ) { pBaseVar->m_dbData = 0.0; } else { pBaseVar->m_dbData = nValue * fCoef * fScale; } } else { if( nValue < 0.0 ) { pBaseVar->m_dbData = 0.0; } else { pBaseVar->m_dbData = (double)(nValue * fCoef); } } if( pBaseVar->m_nRearm != 0 ) { pBaseVar->m_dbData = pBaseVar->m_dbData + pBaseVar->m_nRearm; } } if (iSpecialFlag == 10005) { short int wdValue; memcpy(&wdValue, chMsg+2, sizeof(short int)); nValue = ntohs(wdValue); if( pBaseVar->m_nMaxValues != 0 || pBaseVar->m_nMinValues != 0 || pBaseVar->m_nMaxConvtRate != 0 || pBaseVar->m_nMinConvtRate != 0 ) { double fScale = 1.0; if( pBaseVar->m_nMaxValues - pBaseVar->m_nMinValues > 0 ) { fScale = (double)(pBaseVar->m_nMaxConvtRate - pBaseVar->m_nMinConvtRate) / (double)(pBaseVar->m_nMaxValues - pBaseVar->m_nMinValues); } if( nValue < 0.0 ) { pBaseVar->m_dbData = 0.0; } else { pBaseVar->m_dbData = nValue * fCoef * fScale; } } else { if( nValue < 0.0 ) { pBaseVar->m_dbData = 0.0; } else { pBaseVar->m_dbData = (double)(nValue * fCoef); } } if( pBaseVar->m_nRearm != 0 ) { pBaseVar->m_dbData = pBaseVar->m_dbData + pBaseVar->m_nRearm; } } if( 10006 == iSpecialFlag ) { short int wdValue = 0; short int whValue = 0, wlValue = 0; memcpy(&wdValue, chMsg, sizeof(short int)); whValue = ntohs(wdValue); memcpy(&wdValue, chMsg+2, sizeof(short int)); wlValue = ntohs(wdValue); //pBaseVar->m_dbData = (double)( (wlValue * 10000 + whValue) * fCoef); //if( pBaseVar->m_nRearm != 0 ) //{ // pBaseVar->m_dbData = pBaseVar->m_dbData + pBaseVar->m_nRearm; //} if( pBaseVar->m_nMaxValues != 0 || pBaseVar->m_nMinValues != 0 || pBaseVar->m_nMaxConvtRate != 0 || pBaseVar->m_nMinConvtRate != 0 ) { double fScale = 1.0; if( pBaseVar->m_nMaxValues - pBaseVar->m_nMinValues > 0 ) { fScale = (double)(pBaseVar->m_nMaxConvtRate - pBaseVar->m_nMinConvtRate) / (double)(pBaseVar->m_nMaxValues - pBaseVar->m_nMinValues); } if( nValue < 0.0 ) { pBaseVar->m_dbData = 0.0; } else { pBaseVar->m_dbData = (wlValue * 10000 + whValue) * fCoef * fScale; } } else { if( nValue < 0.0 ) { pBaseVar->m_dbData = 0.0; } else { pBaseVar->m_dbData = (double)((wlValue * 10000 + whValue) * fCoef); } } if( pBaseVar->m_nRearm != 0 ) { pBaseVar->m_dbData = pBaseVar->m_dbData + pBaseVar->m_nRearm; } } EnterCriticalSection(&g_csRtuReadOneData); pDev->m_dwOnlineTick = GetTickCount(); LeaveCriticalSection(&g_csRtuReadOneData); return 0; } int RtuSingleResponseData(char chDevUid[20], int iVarID, char chMsg[80]) { int nDeviceIndex = -1, nVarIndex = -1; BOOL bFind = FindVar(chDevUid, iVarID, nDeviceIndex, nVarIndex); if( bFind == FALSE ) { return -1; } CDevice *pDev = g_pDevicesManager->m_Devices[nDeviceIndex]; CBaseVar *pBaseVar = pDev->m_Vars[nVarIndex]; EnterCriticalSection(&g_csRtuReadOneData); pDev->m_dwOnlineTick = GetTickCount(); LeaveCriticalSection(&g_csRtuReadOneData); int nVarItemID = pBaseVar->m_nVarItemID; int nDataLen = pBaseVar->m_iDataLen; int nValue; DWORD wdValue; double fCoef = pBaseVar->m_dbCoefficient; if( nVarItemID > 0 )//BIT位变量 { int nStartBit = pBaseVar->m_nStartBit; int nEndBit = pBaseVar->m_nEndBit; int nStartReg, nEndReg; if( nEndBit - nStartBit < 7 ) // 一般告警状态会这样子定义,Modbus Ascii码暂时没有碰到,没有经过调试,待测试 { if( nDataLen == 1 ) { char chBuffer[8] = {0}; memset(chBuffer, 0, sizeof(chBuffer)); BYTE byValue = chMsg[0]; DigitToBinary(byValue, chBuffer, 8) ; CString strTemp; switch( nEndBit - nStartBit ) { case 0: strTemp.Format("%c", chBuffer[nStartBit]); nValue = atoi(strTemp); break; case 1: strTemp.Format("%c%c", chBuffer[nStartBit], chBuffer[nStartBit + 1]); nValue = AsciiToBYTE(strTemp[0]) * 2 + AsciiToBYTE(strTemp[1]); break; case 2: strTemp.Format("%c%c%c", chBuffer[nStartBit], chBuffer[nStartBit + 1], chBuffer[nStartBit + 2]); nValue = AsciiToBYTE(strTemp[0]) * 4 + AsciiToBYTE(strTemp[1]) * 2 + AsciiToBYTE(strTemp[2]); break; case 3: strTemp.Format("%c%c%c%c", chBuffer[nStartBit], chBuffer[nStartBit + 1], chBuffer[nStartBit + 2], chBuffer[nStartBit +3]); nValue = AsciiToBYTE(strTemp[0]) * 8 + AsciiToBYTE(strTemp[1]) * 4 + AsciiToBYTE(strTemp[2]) * 2 + AsciiToBYTE(strTemp[0]); break; case 4: strTemp.Format("%c%c%c%c%c", chBuffer[nStartBit], chBuffer[nStartBit + 1], chBuffer[nStartBit + 2], chBuffer[nStartBit + 3], chBuffer[nStartBit + 4]); break; case 5: strTemp.Format("%c%c%c%c%c%c", chBuffer[nStartBit], chBuffer[nStartBit + 1], chBuffer[nStartBit + 2], chBuffer[nStartBit + 3], chBuffer[nStartBit + 4], chBuffer[nStartBit + 5]); break; case 6: strTemp.Format("%c%c%c%c%c%c%c", chBuffer[nStartBit], chBuffer[nStartBit + 1], chBuffer[nStartBit + 2], chBuffer[nStartBit + 3], chBuffer[nStartBit + 4], chBuffer[nStartBit + 5], chBuffer[nStartBit + 6]); break; } //nValue = atoi(strTemp); //strTemp.Format("%d", } else if( nDataLen == 2 ) { char chBuffer[16] = {0}; //chMsg[0] = 0x00; //chMsg[2] = 0x00; //chMsg[2] = 0x0E; //chMsg[3] = 0x0F; //WORD wValue = ( ( (AsciiToBYTE(chMsg[0]) << 4) | ( AsciiToBYTE(chMsg[1]) & 0x00FF ) ) << 8 ) | // ( ( (AsciiToBYTE(chMsg[2]) << 4) | ( AsciiToBYTE(chMsg[3]) & 0x00FF ) ) & 0x0000FFFF ); WORD wValue; memcpy(&wValue, chMsg, sizeof(WORD)); wValue = ntohs(wValue); DigitToBinary(wValue, chBuffer, 16) ; CString strTemp; switch( nEndBit - nStartBit ) { case 0: strTemp.Format("%c", chBuffer[nStartBit]); nValue = atoi(strTemp); break; case 1: strTemp.Format("%c%c", chBuffer[nStartBit], chBuffer[nStartBit + 1]); nValue = AsciiToBYTE(strTemp[0]) * 2 + AsciiToBYTE(strTemp[1]); break; case 2: strTemp.Format("%c%c%c", chBuffer[nStartBit], chBuffer[nStartBit + 1], chBuffer[nStartBit + 2]); nValue = AsciiToBYTE(strTemp[0]) * 4 + AsciiToBYTE(strTemp[1]) * 2 + AsciiToBYTE(strTemp[2]); break; case 3: strTemp.Format("%c%c%c%c", chBuffer[nStartBit], chBuffer[nStartBit + 1], chBuffer[nStartBit + 2], chBuffer[nStartBit +3]); nValue = AsciiToBYTE(strTemp[0]) * 8 + AsciiToBYTE(strTemp[1]) * 4 + AsciiToBYTE(strTemp[2]) * 2 + AsciiToBYTE(strTemp[0]); break; case 4: strTemp.Format("%c%c%c%c%c", chBuffer[nStartBit], chBuffer[nStartBit + 1], chBuffer[nStartBit + 2], chBuffer[nStartBit + 3], chBuffer[nStartBit + 4]); break; case 5: strTemp.Format("%c%c%c%c%c%c", chBuffer[nStartBit], chBuffer[nStartBit + 1], chBuffer[nStartBit + 2], chBuffer[nStartBit + 3], chBuffer[nStartBit + 4], chBuffer[nStartBit + 5]); break; case 6: strTemp.Format("%c%c%c%c%c%c%c", chBuffer[nStartBit], chBuffer[nStartBit + 1], chBuffer[nStartBit + 2], chBuffer[nStartBit + 3], chBuffer[nStartBit + 4], chBuffer[nStartBit + 5], chBuffer[nStartBit + 6]); break; } } } // 特殊变量处理(例如,一个命令返回两个变量的情况) else if( nEndBit - nStartBit == 7 ) // 1个字节的情况 { nStartReg = (int)nStartBit / 8; nEndReg = (int)(nEndBit + 1) / 8; nValue = chMsg[nStartReg]; } else if( nEndBit - nStartBit == 15 ) // 2个字节的情况 { nStartReg = (int)nStartBit / 8; nEndReg = (int)(nEndBit + 1) / 8; memcpy(&wdValue, chMsg, sizeof(WORD)); nValue = ntohs((WORD)wdValue); } EnterCriticalSection( &g_csRtuReadOneData ); pBaseVar->m_dbData = (double)(nValue * fCoef); if( pBaseVar->m_nRearm != 0 ) { pBaseVar->m_dbData = pBaseVar->m_dbData + pBaseVar->m_nRearm; } LeaveCriticalSection( &g_csRtuReadOneData ); //LOG4C((LOG_NOTICE, "desc = %s, value = %d", pBaseVar->m_strDesc, (int)pBaseVar->m_dbData)); } else { // 联合类型变量做特殊处理 if( pBaseVar->m_nVarTypeID >= UNION_TYPE_MIN_ID && pBaseVar->m_nVarTypeID <= UNION_TYPE_MAX_ID ) { if( nDataLen == 2 ) { //int类型 union __UNION_VAR_INT{ char ch[2]; int value; }unionVarInt; unionVarInt.ch[0] = chMsg[1]; unionVarInt.ch[1] = chMsg[0]; EnterCriticalSection( &g_csRtuReadOneData ); pBaseVar->m_dbData = (double)(unionVarInt.value * fCoef); if( pBaseVar->m_nRearm != 0 ) { pBaseVar->m_dbData = pBaseVar->m_dbData + pBaseVar->m_nRearm; } LeaveCriticalSection( &g_csRtuReadOneData ); //TRACE2("联合类型变量ID%d, 值=%d\r\n", iVarID, unionVarInt.value); } else if( nDataLen == 4 ) { //float类型 union __UNION_VAR_FLOAT{ char ch[4]; float value; }unionVarFloat; unionVarFloat.ch[0] = chMsg[3]; unionVarFloat.ch[1] = chMsg[2]; unionVarFloat.ch[2] = chMsg[1]; unionVarFloat.ch[3] = chMsg[0]; EnterCriticalSection( &g_csRtuReadOneData ); if( unionVarFloat.value < 0.0 ) { pBaseVar->m_dbData = 0.0; } else { pBaseVar->m_dbData = (double)(unionVarFloat.value * fCoef); } if( pBaseVar->m_nRearm != 0 ) { pBaseVar->m_dbData = pBaseVar->m_dbData + pBaseVar->m_nRearm; } LeaveCriticalSection( &g_csRtuReadOneData ); //TRACE2("联合类型变量ID%d, 值=%.1f\r\n", iVarID, unionVarFloat.value); } else if( nDataLen == 8 ) { //double类型 union __UNION_VAR_DOUBLE{ char ch[8]; double value; }unionVarDouble; unionVarDouble.ch[0] = chMsg[7]; unionVarDouble.ch[1] = chMsg[6]; unionVarDouble.ch[2] = chMsg[5]; unionVarDouble.ch[3] = chMsg[4]; unionVarDouble.ch[4] = chMsg[3]; unionVarDouble.ch[5] = chMsg[2]; unionVarDouble.ch[6] = chMsg[1]; unionVarDouble.ch[7] = chMsg[0]; EnterCriticalSection( &g_csRtuReadOneData ); pBaseVar->m_dbData = (double)(unionVarDouble.value * fCoef); if( pBaseVar->m_nRearm != 0 ) { pBaseVar->m_dbData = pBaseVar->m_dbData + pBaseVar->m_nRearm; } LeaveCriticalSection( &g_csRtuReadOneData ); //TRACE2("联合类型变量ID%d, 值=%.1f\r\n", iVarID, unionVarDouble.value); } } else { switch( nDataLen ) { case 1: nValue = chMsg[0]; break; case 2: short int wdValue; memcpy(&wdValue, chMsg, sizeof(short int)); nValue = ntohs(wdValue); break; case 3: // 一般为字符串类型,不作处理 break; case 4: // 保留,暂时不知道什么处理 break; case 5: // 一般为字符串类型,不作处理 break; case 6: // 一般为字符串类型,不作处理 break; case 7: // 一般为字符串类型,不作处理 break; case 8: // 保留,暂时没有用到 break; } EnterCriticalSection( &g_csRtuReadOneData ); if( pBaseVar->m_nMaxValues != 0 || pBaseVar->m_nMinValues != 0 || pBaseVar->m_nMaxConvtRate != 0 || pBaseVar->m_nMinConvtRate != 0 ) { double fScale = 1.0; if( pBaseVar->m_nMaxValues - pBaseVar->m_nMinValues > 0 ) { fScale = (double)(pBaseVar->m_nMaxConvtRate - pBaseVar->m_nMinConvtRate) / (double)(pBaseVar->m_nMaxValues - pBaseVar->m_nMinValues); } if( nValue < 0.0 ) { pBaseVar->m_dbData = 0.0; } else { pBaseVar->m_dbData = nValue * fCoef * fScale; } } else { if( nValue < 0.0 ) { pBaseVar->m_dbData = 0.0; } else { pBaseVar->m_dbData = (double)(nValue * fCoef); } } if( pBaseVar->m_nRearm != 0 ) { pBaseVar->m_dbData = pBaseVar->m_dbData + pBaseVar->m_nRearm; } //LOG4C((LOG_NOTICE, "desc = %s, value = %d", pBaseVar->m_strDesc, (int)pBaseVar->m_dbData)); //g_RtuReadOneData.dbData = (double)(nValue * fCoef); LeaveCriticalSection( &g_csRtuReadOneData ); } } EnterCriticalSection(&g_csRtuReadOneData); pDev->m_dwOnlineTick = GetTickCount(); LeaveCriticalSection(&g_csRtuReadOneData); return 0; } void UnInitRtuDll() { if (g_hRTULibModule != NULL && ( NULL != pRTU_DLLUnInit )) { pRTU_DLLUnInit(); } DeleteCriticalSection( &g_csRtuReadOneData ); if (g_hRTULibModule!= NULL) { AfxFreeLibrary(g_hRTULibModule); g_hRTULibModule = NULL; } } int RtuRequestWrData(char chDevUid[20], int iVarID, double data)//用于请求写命令操作 { SETBASEPARAM SetBasePara; memset( &SetBasePara, 0, sizeof(SETBASEPARAM) ); int nDeviceIndex = -1, nVarIndex = -1; BOOL bFind = FindVar(chDevUid, iVarID, nDeviceIndex, nVarIndex); if( bFind == FALSE ) return -1; CDevice *pDev = g_pDevicesManager->m_Devices[nDeviceIndex]; CBaseVar *pBaseVar = pDev->m_Vars[nVarIndex]; SetBasePara.nAddr = pDev->m_iDevideaddr; SetBasePara.nRegNum = pBaseVar->m_iRegisterNum; SetBasePara.nStartAddr = pBaseVar->m_nRegStartAddr; SetBasePara.FuncCode = pBaseVar->m_iFuncID; if (pRTU_DLLWrite(pDev->m_iPort, pDev->m_iDevideaddr, SetBasePara, data, pBaseVar->m_iDataLen) == 0) return 0; else return -1; } double RtuSingleResponseWriteData(char chDevUid[20], int iVarID) { return 0; }