⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 itkplcdlg.cpp

📁 工业强度的PLC模拟程序
💻 CPP
📖 第 1 页 / 共 5 页
字号:
                    break;    
				}

				//
				// Reponse commands that the driver will send when the ITKPLC sends
				// an unsolicited message. We should never get a READ_RESPONSE_CMD
				// because the ITKPLC does not issue read requests to the driver.
				//
				case READ_RESPONSE_CMD:
				case BIT_WRITE_RESPONSE_CMD:
				case WRITE_RESPONSE_CMD:
					SendDLE(ACK);
					break;

                default:
					break;    
                }
            }
            else
            {
                SendDLE(NAK);
            }
            break;

        default:
            rcv_state = DLE1;
        }
	}
}



//----(Member Function)-------------------------------------------------------
//
// @mfunc void | CItkPlcDlg | AnswerRead |
//
// This function builds a responce to a read message containing the data
// requested.
//
void CItkPlcDlg::AnswerRead(unsigned short int nDest, unsigned short int nSource, 
							unsigned short int nStart, unsigned short int nLength,
							unsigned short int nCmd, unsigned short int nTransNum,
							SOCKET ClientSocket,
							LPSOCKADDR ClientSockAddr)
{
	int index;

    short int nSendBcc = 0;

	unsigned short int nValue;

    PutSend(DLE);
    PutSend(STX);

	// Put in the source ID
    PutSendBcc((unsigned char)nSource, &nSendBcc);	// put the source (us)

	// Put in the destination ID, if enabled
	if (this->m_bSourceStn)
	{
		PutSendBcc((unsigned char)nDest, &nSendBcc);	// put the destination (ITK)
	}

	// Put in the command.
	// Switch on the command issued and respond with the correct command
	switch(nCmd)
	{
	case READ_CMD:
		PutSendBcc((unsigned char)READ_RESPONSE_CMD, &nSendBcc);
		break;

	case WRITE_CMD:
		PutSendBcc((unsigned char)WRITE_RESPONSE_CMD, &nSendBcc);
		break;

	case BIT_WRITE_CMD:
		PutSendBcc((unsigned char)BIT_WRITE_RESPONSE_CMD, &nSendBcc);
		break;

	default:
		break;
	}

	if (this->m_bTransNum)
	{
		// Put the transaction number
		PutSendBcc((unsigned char)(nTransNum >> 8), &nSendBcc);	// hi-byte
		PutSendBcc((unsigned char)nTransNum, &nSendBcc);		// lo-byte
	}

	// Put the data
    for ( index = 0; index < (nLength >> 1); index++ )
    {     
        nValue = PlcMemory[nStart + index];
        PutSendBcc((unsigned char)( nValue & 0xff), &nSendBcc);
        PutSendBcc((unsigned char)(( nValue >> 8 ) & 0xff), &nSendBcc);
    }        

	// Put the trailing stuff
    PutSend(DLE);
    PutSend(ETX);

	// Put in the checksum
    PutSend((unsigned char)((-nSendBcc) & 0xff));

	__try
	{
		EnterCriticalSection(&this->m_Lock);

		switch (this->m_dwProtocol)
		{
			case TCPIP_PROTOCOL:
				this->m_pTcp->Send(ClientSocket, this->m_nTransmitBuffer,
								   this->m_dwTransmitIndex);
				break;

			case UDPIP_PROTOCOL:
				if (ClientSockAddr != NULL)
				{
					this->m_pTcp->Send(*ClientSockAddr, this->m_nTransmitBuffer,
								   this->m_dwTransmitIndex);
				}
				break;

			case SERIAL_PROTOCOL:
			default:
				this->m_pIo->Send(this->m_nTransmitBuffer, 
								  this->m_dwTransmitIndex);
				break;
		}
	}
	__finally
	{
		LeaveCriticalSection(&this->m_Lock);
	}

	this->m_dwTransmitIndex = 0;
}



//----(Member Function)-------------------------------------------------------
//
// @mfunc void | CItkPlcDlg | PutSend |
//
//
void CItkPlcDlg::PutSend( unsigned char nValue )
{    
	this->m_nTransmitBuffer[this->m_dwTransmitIndex++] = nValue;
	if (this->m_dwTransmitIndex >= TRANSMIT_BUFFER_SIZE)
	{
		this->m_dwTransmitIndex = 0;
	}
}    



//----(Member Function)-------------------------------------------------------
//
// @mfunc void | CItkPlcDlg | PutSendBcc |
//
//
void CItkPlcDlg::PutSendBcc( unsigned char nValue, short int *nBcc )
{
   	this->m_nTransmitBuffer[this->m_dwTransmitIndex++] = nValue;
	if (this->m_dwTransmitIndex >= TRANSMIT_BUFFER_SIZE)
	{
		this->m_dwTransmitIndex = 0;
	}

    *nBcc += nValue; 

    if ( nValue == DLE )
    {
		this->m_nTransmitBuffer[this->m_dwTransmitIndex++] = DLE;
		if (this->m_dwTransmitIndex >= TRANSMIT_BUFFER_SIZE)
		{
			this->m_dwTransmitIndex = 0;
		}
    }        
}    



//----(Member Function)-------------------------------------------------------
//
// @mfunc UINT | CItkPlcDlg | SendDLE |
//
// Sends a DLE to the I/O Driver
//
void CItkPlcDlg::SendDLE(unsigned char acknak, SOCKET ClientSocket)
{
    PutSend(DLE);
    PutSend((unsigned char)acknak);

	__try
	{
		EnterCriticalSection(&this->m_Lock);

		switch (this->m_dwProtocol)
		{
		case TCPIP_PROTOCOL:
			// Nothing to send for TCP protocol.
			break;

		case UDPIP_PROTOCOL:
			// Nothing to send for UDP protocol.
			break;

		case SERIAL_PROTOCOL:
		default:
			this->m_pIo->Send(this->m_nTransmitBuffer, this->m_dwTransmitIndex);
			break;
		}
	}
	__finally
	{
		LeaveCriticalSection(&this->m_Lock);
	}

	//
	// Increment the correct count
	//
	switch (acknak)
	{
	case NAK:
		this->m_pdlgCommStats->m_dwNakSentCount++;
		break;

	case ACK:
		this->m_pdlgCommStats->m_dwAckSentCount++;
		break;
	}

	this->m_dwTransmitIndex = 0;
    
    return;
}



//----(Member Function)-------------------------------------------------------
//
// @mfunc UINT | CItkPlcDlg | GetBCCMask |
//
// Sets and returns the BCC mask for the parse routine. This mask is dependant
// on the data bits.
//
unsigned short int CItkPlcDlg::GetBCCMask()
{
	unsigned short int nDataBits = this->GetDataBits();


	nDataBits = this->GetDataBits();
	switch(nDataBits)
	{
	case 5:
		this->m_cBCCMask = 0x1f; 
		break;

	case 6:
		this->m_cBCCMask = 0x3f;
		break;

	case 7:
		this->m_cBCCMask = 0x7f;
		break;

	case 8:
	default:
		this->m_cBCCMask = 0xff;
		break;
	}

	return (this->m_cBCCMask);
}



//----(Member Function)-------------------------------------------------------
//
// @mfunc UINT | CItkPlcDlg | GetDataBits |
//
// Returns the data bits for the given port params.
//
unsigned short int CItkPlcDlg::GetDataBits()
{
	char	cDataBits[2];


	if (this->m_szPortMode.IsEmpty())
	{
		return 0;
	}

	//
	// The nPortParams will be in the format of "9600,n,8,1",
	// so the data bits will be the second to last parameter,
	// which is the third from last character
	//
	*cDataBits = this->m_szPortMode[(this->m_szPortMode.GetLength() - 3)];
	*(cDataBits+1) = NULL;

	return ((unsigned short int)atoi(cDataBits));
}



//----(Member Function)-------------------------------------------------------
//
// @mfunc UINT | CItkPlcDlg | UnsolIoHandler |
//
// Handler for the Unsolicitied Messaging thread (if enabled).
//
UINT CItkPlcDlg::UnsolIoHandler(LPVOID ptr)
{
	CItkPlcDlg	*pThis = (CItkPlcDlg *)ptr;

	DWORD		dwStatus = IO_SUCCESS,
				dwIndex = 0,
				dwSize,
				dwStartRegisters[10] = {0, 50, 100, 150, 200,
										250, 300, 350, 400, 450 };

	unsigned char buffer[4096];


	SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_NORMAL);
	SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS);


	while (!pThis->m_bShutdown)
	{
		dwSize = pThis->BuildWriteMsg(dwStartRegisters[dwIndex],(unsigned char *)&buffer);

		__try
		{
			EnterCriticalSection(&pThis->m_Lock);

			switch (pThis->m_dwProtocol)
			{
			case TCPIP_PROTOCOL:
			// Currently not implemented for TCP protocol.
				break;

			case UDPIP_PROTOCOL:
			// Currently not implemented for UDP protocol.
				break;

			case SERIAL_PROTOCOL:
			default:
				pThis->m_pIo->Send(buffer, dwSize);
				break;
			}
		}
		__finally
		{
			LeaveCriticalSection(&pThis->m_Lock);
		}

		pThis->m_pdlgCommStats->m_dwUnsolicitedSentCount++;
		
		if (++dwIndex >= 10)
		{
			dwIndex = 0;
		}

		Sleep(pThis->m_dwUnsolFrequency);
	}

	return(1);
}



//----(Member Function)-------------------------------------------------------
//
// @mfunc UINT | CItkPlcDlg | BuildWriteMsg |
//
// Builds a write message for unsolicitied messaging
//
DWORD CItkPlcDlg::BuildWriteMsg(DWORD dwStart, unsigned char *buffer)
{
	unsigned char *pXmit,
				  chBCC = 0;

	DWORD dwLength = 0;
	
	pXmit = buffer;

	
	// put on the message header
	*pXmit++ = DLE;
	dwLength++;

	*pXmit++ = STX;
	dwLength++;

	// Who it came from
	if (this->m_bSourceStn)
	{
		*pXmit = (unsigned char)this->m_dwLocalStation;
		chBCC = (unsigned char)(chBCC + *pXmit);
		dwLength++;

		// if a DLE, add another (DLE escaping)
		if (*pXmit++ == (unsigned char)DLE)
		{
			*pXmit++ = (unsigned char)DLE;
			dwLength++;
		}
	}

	// Who to send to
	*pXmit = (unsigned char)this->m_dwRemoteStation;  
	chBCC = (unsigned char)(chBCC + *pXmit);
	dwLength++;

	// if a DLE, add another (DLE escaping)
	if (*pXmit++ == (unsigned char)DLE)
	{
		*pXmit++ = (unsigned char)DLE;
		dwLength++;
	}
	
	*pXmit = (unsigned char)WRITE_CMD;		// Word Write
	
	chBCC = (unsigned char)(chBCC + *pXmit);
	pXmit++;
	dwLength++;

	// Transaction number
	if (this->m_bTransNum)
	{
		//
		// Get a random number for the transaction number
		//
		this->m_nTransactionNumber = (unsigned short int)rand();

		// hi byte
		*pXmit = (unsigned char)((this->m_nTransactionNumber >> 8) & 0xFF);  
		chBCC = (unsigned char)(chBCC + *pXmit);
		dwLength++;

		// if a DLE, add another (DLE escaping)
		if (*pXmit++ == (unsigned char)DLE)
		{
			*pXmit++ = (unsigned char)DLE;
			dwLength++;
		}

		// lo byte
		*pXmit = (unsigned char)(this->m_nTransactionNumber & 0xFF);  
		chBCC = (unsigned char)(chBCC + *pXmit);
		dwLength++;

		// if a DLE, add another (DLE escaping)
		if (*pXmit++ == (unsigned char)DLE)
		{
			*pXmit++ = (unsigned char)DLE;
			dwLength++;
		}
	}
	
	// Word address low byte
	*pXmit = (unsigned char)(dwStart & 0xFF);
	chBCC = (unsigned char)(chBCC + *pXmit);
	dwLength++;

	// if a DLE, add another (DLE escaping)
	if (*pXmit++ == (unsigned char)DLE)
	{
		*pXmit++ = (unsigned char)DLE;
		dwLength++;
	}
	
	// Word Address high byte
	*pXmit = (unsigned char)(dwStart >> 8);
	chBCC = (unsigned char)(chBCC + *pXmit);
	dwLength++;

	// if a DLE, add another (DLE escaping)
	if (*pXmit++ == (unsigned char)DLE)
	{
		*pXmit++ = (unsigned char)DLE;
		dwLength++;
	}

	//
	// Write 10 words.
	//
	for (int nOffset = 0; nOffset < 10; nOffset++)
	{
		// Data low
		*pXmit = (unsigned char)(this->PlcMemory[dwStart + nOffset] & 0xFF);
		chBCC = (unsigned char)(chBCC + *pXmit);
		dwLength++;

		// if a DLE, add another (DLE escaping)
		if (*pXmit++ == (unsigned char)DLE)
		{
			*pXmit++ = (unsigned char)DLE;
			dwLength++;
		}

		// Data High
		*pXmit = (unsigned char)(this->PlcMemory[dwStart + nOffset] >> 8);	
		chBCC = (unsigned char)(chBCC + *pXmit);
		dwLength++;

		// if a DLE, add another (DLE escaping)
		if (*pXmit++ == (unsigned char)DLE)
		{
			*pXmit++ = (unsigned char)DLE;
			dwLength++;
		}
	}

	// put on the message trailer
	*pXmit++ = (unsigned char)DLE;	// DLE
	dwLength++;
	*pXmit++ = (unsigned char)ETX;	// ETX
	dwLength++;
	*pXmit = (unsigned char)-chBCC;
	dwLength++;

	return(dwLength);
}

//
//	CALLBACK Function TcpSrvCallback() for the Server Receive Message
//
void EXPORT32 CALLBACK TcpSrvCallback(LPVOID ptr, SOCKET ClientSocket, DWORD dwTransferred )
{

	CItkPlcDlg		*pThis = (CItkPlcDlg *)ptr;

	pThis->ParseTcpMsg(ClientSocket, dwTransferred);

}


void CItkPlcDlg::ParseTcpMsg(SOCKET ClientSocket, DWORD dwSize)
{

	__try
	{
		EnterCriticalSection(&this->m_Lock);

	DWORD						dwLoop;

	unsigned char				Value;

	unsigned short int	rcv_state	= DLE1,
								calc_bcc	= 0,
								dest		= 0,	// destination (our station)
								src			= 0,	// source (from who)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -