📄 cmbrtu.cpp
字号:
// CMBRTU.cpp : Implementation of CCMBRTU
#include "stdafx.h"
#include "MBRTU.h"
#include "CMBRTU.h"
#include "Crc.h"
/////////////////////////////////////////////////////////////////////////////
// CCMBRTU
STDMETHODIMP CCMBRTU::OpenCom(BSTR bstrComParam)
{
// TODO: Add your implementation code here
int iLen = wcslen(bstrComParam) * 2 + 1;
cParam = (char *)new BYTE[iLen];
memset(cParam, 0, iLen);
cReceive = (char *)new BYTE[2048];
memset(cReceive, 0, 2048);
cWrite = (char *)new BYTE[2048];
memset(cWrite, 0, 2048);
WideCharToMultiByte( \
CP_ACP, \
0, \
bstrComParam, \
-1, \
cParam, \
iLen, \
NULL, \
NULL);
DCB dcb;
char cCom[5];
memset(cCom, 0, 5);
memcpy(cCom, cParam, 4);
hCom = CreateFile(cCom,
GENERIC_READ | GENERIC_WRITE,
0, // comm devices must be opened w/exclusive-access
NULL, // no security attributes
OPEN_EXISTING, // comm devices must use OPEN_EXISTING
FILE_ATTRIBUTE_NORMAL, // not overlapped I/O
NULL // hTemplate must be NULL for comm devices
);
if (hCom == INVALID_HANDLE_VALUE)
{
return S_FALSE;
}
// Omit the call to SetupComm to use the default queue sizes.
// Get the current configuration.
if (!SetupComm(hCom, (DWORD)2048, (DWORD)2048))
{
CloseHandle(hCom);
return S_FALSE;
}
if (!GetCommState(hCom, &dcb))
{
CloseHandle(hCom);
return S_FALSE;
}
if (!BuildCommDCB(cParam,&dcb))
{
CloseHandle(hCom);
return S_FALSE;
}
//由于是BuildCommDCB的bug才要加上下面的代码, bug是fParity = 0
if(dcb.Parity == ODDPARITY || dcb.Parity == EVENPARITY)
dcb.fParity = 1;
//dcb.fDtrControl = DTR_CONTROL_ENABLE;
//dcb.fRtsControl = RTS_CONTROL_DISABLE;
SetCommState(hCom, &dcb);
if (!PurgeComm(hCom, PURGE_TXABORT | PURGE_RXABORT | PURGE_TXCLEAR | PURGE_RXCLEAR))
{
CloseHandle(hCom);
return S_FALSE;
}
//COMMTIMEOUTS co;
//GetCommTimeouts(hCom, &co);
//co.ReadIntervalTimeout = 0xFFFFFFFF;
//co.ReadTotalTimeoutConstant = 5000;
//co.ReadTotalTimeoutMultiplier = 0;
//co.WriteTotalTimeoutConstant = 5000;
//co.WriteTotalTimeoutMultiplier = 0;
//SetCommTimeouts(hCom, &co);
bConnect = TRUE;
return S_OK;
}
STDMETHODIMP CCMBRTU::CloseCom()
{
// TODO: Add your implementation code here
if(bConnect)
{
CloseHandle(hCom);
if (cParam)
{
delete cParam;
cParam = NULL;
}
if (cReceive)
{
delete cReceive;
cReceive = NULL;
}
if (cWrite)
{
delete cWrite;
cWrite = NULL;
}
}
return S_OK;
}
STDMETHODIMP CCMBRTU::ReadRegister(int iStation, int iStartAddr, int iLen, int *pRetLen)
{
// TODO: Add your implementation code here
BYTE cReadCmd[8];
memset(cReadCmd, 0, 8);
cReadCmd[0] = iStation;
cReadCmd[1] = 3;
cReadCmd[2] = iStartAddr / 256;
cReadCmd[3] = iStartAddr % 256;
cReadCmd[4] = iLen / 256;
cReadCmd[5] = iLen % 256;
CCrc crc;
crc.CRC16((unsigned char *)cReadCmd, 6, cReadCmd[6], cReadCmd[7]);
DWORD dwTotal = iLen * 2 + 5;
DWORD dwEvent;
//dwEvent = EV_TXEMPTY;
SetCommMask(hCom, EV_TXEMPTY);
DWORD dwTick = GetTickCount();
DWORD dwWrite = 0;
DWORD dwRead = 0;
DWORD dwTemp = 0;
if (WriteFile(hCom, cReadCmd, 8, &dwWrite, NULL))
{
WaitCommEvent(hCom, &dwEvent, NULL);
memset(cReceive, 0, 2048);
while(TRUE)
{
if(dwWrite == 8)
{
//dwError = 0;
ClearCommError(hCom,&dwError,&cs);
if((!cs.cbInQue && dwTemp == dwTotal ) || (GetTickCount() > dwTick + 5000))
break;
dwRead = 0;
ReadFile(hCom, cReceive + dwTemp, cs.cbInQue, &dwRead, NULL);
dwTemp += dwRead;
}
}
}
if (dwTemp != dwTotal)
return S_FALSE;
if (cReceive[2] != iLen * 2)
return S_FALSE;
memcpy(cReceive, cReceive + 3, iLen * 2);
*pRetLen = iLen * 2;
return S_OK;
}
STDMETHODIMP CCMBRTU::GetRetVal(int iIndex, BYTE *pByte)
{
// TODO: Add your implementation code here
*pByte = cReceive[iIndex];
return S_OK;
}
STDMETHODIMP CCMBRTU::GetRetVal_Cimplicity(int iIndex, int *piVal)
{
// TODO: Add your implementation code here
*piVal = cReceive[iIndex];
return S_OK;
}
STDMETHODIMP CCMBRTU::WriteRegister(int iSation, int iStartAddr, int iLen)
{
// TODO: Add your implementation code here
BYTE cWriteCmd[2048];
memset(cWriteCmd, 0, 2048);
int iLength = iLen * 2;
cWriteCmd[0] = iSation;
cWriteCmd[1] = 16;
cWriteCmd[2] = iStartAddr / 256;
cWriteCmd[3] = iStartAddr % 256;
cWriteCmd[4] = 0;
cWriteCmd[5] = iLen;
cWriteCmd[6] = iLength;
for(int i = 0; i < iLength; i++)
{
cWriteCmd[i + 7] = cWrite[i];
}
CCrc crc;
crc.CRC16((unsigned char *)cWriteCmd, 7 + iLength, cWriteCmd[7 + iLength], cWriteCmd[7 + iLength + 1]);
DWORD dwTotal = 8;
DWORD dwEvent;
//dwEvent = EV_TXEMPTY;
SetCommMask(hCom, EV_TXEMPTY);
DWORD dwTick = GetTickCount();
DWORD dwWrite = 0;
DWORD dwRead = 0;
DWORD dwTemp = 0;
DWORD dwWriteLen = 7 + iLength + 2;
if (WriteFile(hCom, cWriteCmd, dwWriteLen, &dwWrite, NULL))
{
WaitCommEvent(hCom, &dwEvent, NULL);
memset(cReceive, 0, 2048);
while(TRUE)
{
if(dwWrite == dwWriteLen)
{
//dwError = 0;
ClearCommError(hCom,&dwError,&cs);
if((!cs.cbInQue && dwTemp == dwTotal ) || (GetTickCount() > dwTick + 5000))
break;
dwRead = 0;
ReadFile(hCom, cReceive + dwTemp, cs.cbInQue, &dwRead, NULL);
dwTemp += dwRead;
}
}
}
if (dwTemp != dwTotal)
return S_FALSE;
if (cReceive[1] != 16)
return S_FALSE;
return S_OK;
}
STDMETHODIMP CCMBRTU::SetRegVal(int iIndex, BYTE byteVal)
{
// TODO: Add your implementation code here
cWrite[iIndex] = byteVal;
return S_OK;
}
STDMETHODIMP CCMBRTU::TwoByteToShort(BYTE byteHi, BYTE byteLo, short *psVal)
{
// TODO: Add your implementation code here
BYTE byteTemp[2];
memset(byteTemp, 0, 2);
byteTemp[0] = byteLo;
byteTemp[1] = byteHi;
memcpy(psVal, byteTemp, 2);
return S_OK;
}
STDMETHODIMP CCMBRTU::ShortToTwoByte(short sVal, BYTE *pbyteHi, BYTE *pbyteLo)
{
// TODO: Add your implementation code here
BYTE byteVal[2];
memcpy(byteVal, &sVal, 2);
*pbyteLo = byteVal[0];
*pbyteHi = byteVal[1];
return S_OK;
}
STDMETHODIMP CCMBRTU::ReadCoils(int iStation, int iStartAddr, int iQuantity, int *pRetLen)
{
// TODO: Add your implementation code here
BYTE cReadCmd[8];
memset(cReadCmd, 0, 8);
cReadCmd[0] = iStation;
cReadCmd[1] = 1;
cReadCmd[2] = iStartAddr / 256;
cReadCmd[3] = iStartAddr % 256;
cReadCmd[4] = iQuantity / 256;
cReadCmd[5] = iQuantity % 256;
CCrc crc;
crc.CRC16((unsigned char *)cReadCmd, 6, cReadCmd[6], cReadCmd[7]);
int iLen = 0;
iLen = iQuantity / 8;
if (iQuantity % 8)
iLen++;
DWORD dwTotal = iLen + 5;
DWORD dwEvent;
SetCommMask(hCom, EV_TXEMPTY);
DWORD dwTick = GetTickCount();
DWORD dwWrite = 0;
DWORD dwRead = 0;
DWORD dwTemp = 0;
if (WriteFile(hCom, cReadCmd, 8, &dwWrite, NULL))
{
WaitCommEvent(hCom, &dwEvent, NULL);
memset(cReceive, 0, 2048);
while(TRUE)
{
if(dwWrite == 8)
{
ClearCommError(hCom,&dwError,&cs);
if((!cs.cbInQue && dwTemp == dwTotal ) || (GetTickCount() > dwTick + 5000))
break;
dwRead = 0;
ReadFile(hCom, cReceive + dwTemp, cs.cbInQue, &dwRead, NULL);
dwTemp += dwRead;
}
}
}
if (dwTemp != dwTotal)
return S_FALSE;
if (cReceive[1] != 1)
return S_FALSE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -