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

📄 itkplcdlg.cpp

📁 工业强度的PLC模拟程序
💻 CPP
📖 第 1 页 / 共 5 页
字号:
								start		= 0,
								len			= 0, 
								cmd			= 0, 
								dle_flag	= 0,
								ans_len		= 0, 
								ans_start	= 0, 
								ans_src		= 0,	// destination (to who)
								ans_dest	= 0,	// source (our station)
								set_mask	= 0, 
								reset_mask	= 0,
								transaction	= 0;

	static unsigned short int	write_val[120];
	
	unsigned int				i;
	
	this->m_pdlgCommStats->m_dwAckRcvdCount++;
    
	for (dwLoop = 0; dwLoop < dwSize; dwLoop++)
	{
		Value = this->m_chReceiveBuffer[dwLoop];

		//
		//  Check for doubled-up DLE's
		//
		if (Value == DLE)
        {
			if (dle_flag)				// was previous dle ?
            {
				dle_flag = FALSE;       // clear flag
				continue;               // done
            }    
			else
			{
				dle_flag = TRUE;        // first dle
			}
        }
		else
		{
			dle_flag = FALSE;           // clear flag
		}

		switch (rcv_state)
        {
        case DLE1:
            if (Value == DLE)
            {
                calc_bcc = 0;			// reset bcc
                rcv_state = STX1;
            }
            break;

        case STX1:
			switch(Value)
			{
			case STX:
				if (this->m_bSourceStn)
				{
					rcv_state = SRC1;
				}
				else
				{
					rcv_state = DEST1;
				}
				calc_bcc = 0;			// reset bcc
				break;
			case NAK:
				rcv_state = DLE1;
				this->m_pdlgCommStats->m_dwNakRcvdCount++;
				AnswerRead(ans_dest, ans_src, ans_start, ans_len, cmd, transaction, ClientSocket);
				break;
			case ACK:
				rcv_state = DLE1;
				this->m_pdlgCommStats->m_dwAckRcvdCount++;
				break;
			}
			break;

		case SRC1:				// Source Station address
			src = Value;
			rcv_state = DEST1;
			calc_bcc += Value;
			break;

        case DEST1:				// Destination Station address
            dest = Value;
			//
			// Make sure the message is for us. A Local Station
			// set to 0 means to accept ALL messages.
			//
			if ((this->m_dwLocalStation == 0) || 
				(this->m_dwLocalStation == dest))
			{
				rcv_state = CMD1;
				calc_bcc += Value;
				break;
			}
			else
			{
				rcv_state = DLE1;
				this->m_pdlgCommStats->m_dwNakSentCount++;
				return;
			}

        case CMD1:				// Command
            cmd = Value;
			if (this->m_bTransNum)
			{
				rcv_state = TRANHI;
			}
			else
			{
				rcv_state = ADDLO;
			}
            calc_bcc += Value;
            break;

		case TRANHI:			// Transaction Number hi-byte
			transaction = (Value << 8);
			rcv_state = TRANLO;
			calc_bcc += Value;
			break;

		case TRANLO:			// Transaction Number lo-byte
			transaction += Value;
			rcv_state = ADDLO;
			calc_bcc += Value;
			break;

        case ADDLO:				// Start Adress lo-byte
            start = Value;
            rcv_state = ADDHI;
            calc_bcc += Value;
            break;

        case ADDHI:				// Start Address hi-byte
            start |= ((Value<<8) & 0xff00);
            calc_bcc += Value;
            switch (cmd)
            {
			case READ_CMD:
				rcv_state = LEN1;
				break;    
			case BIT_WRITE_CMD:
				rcv_state = SET1;
				break;    
			case WRITE_CMD:    
				len = 0;
				rcv_state = DATA1;
				break;    
			default:
				rcv_state = DLE1;
            }
            break;

        case DATA1:
            write_val[len] = Value;

			if (Value == DLE)     
			{
				rcv_state = DATA_DLE;
				dle_flag = FALSE;
			}
			else
			{
				rcv_state = DATA2;
				calc_bcc += Value;
			}
            break;

        case DATA2:
            write_val[len] |= ((Value << 8) & 0xff00);
            len++;             

			if (Value == DLE)          
			{
				rcv_state = DATA_DLE2;
				dle_flag = FALSE;
			}
			else
			{
				rcv_state = DATA1;
				calc_bcc += Value;
			}
			break;

        case DATA_DLE:
			switch(Value)
			{
			case DLE:
				rcv_state = DATA2;
                calc_bcc += Value;
                break;
			case ETX:
				rcv_state = BCC1;
				break;
			default:
				rcv_state = DLE1;
				break;
			}
			break;
 
        case DATA_DLE2:  
			switch(Value)
			{
			case DLE:
				rcv_state = DATA1;
                calc_bcc += Value;
                break;
			case ETX:
				rcv_state = BCC1;
				break;
			default:
				rcv_state = DLE1;
				break;
			}
			break;
 
        case SET1:
            set_mask = Value;
            rcv_state = SET2;
            calc_bcc += Value;
            break;

        case SET2:
            set_mask |= ((Value<<8) & 0xff00 );
            rcv_state = RESET1;
            calc_bcc += Value; 
            break;

        case RESET1:
            reset_mask = Value;
            rcv_state = RESET2;
            calc_bcc += Value;
            break;

        case RESET2:
            reset_mask |= ( (Value<<8) & 0xff00 );
            rcv_state = DLE2;
            calc_bcc += Value;
            break;

        case LEN1:
            len = Value;
            rcv_state = DLE2;
            calc_bcc += Value;
            break;

        case DLE2:
            if (Value == DLE)
            {
				rcv_state = ETX1;
			}
            else
			{
				rcv_state = DLE1;
			}
            break;

        case ETX1:
            if ( Value == ETX )
			{
				rcv_state = BCC1;
			}
            else
			{
				rcv_state = DLE1;
			}
            break;
    
        case BCC1:					// Checksum
            calc_bcc += Value;
            rcv_state = DLE1;

            if ((calc_bcc & this->m_cBCCMask) == 0)
            {
				this->m_pdlgCommStats->m_dwAckSentCount++;

                switch (cmd)
                {
                case READ_CMD:
					this->m_pdlgCommStats->m_dwReadCount++;
                    ans_len = len;
                    ans_start = start;
                    ans_src = dest;
					ans_dest = src;
                    AnswerRead(ans_dest, ans_src, ans_start, ans_len, cmd, transaction, ClientSocket);
                    break;    

				case BIT_WRITE_CMD:
					this->m_pdlgCommStats->m_dwBitWriteCount++;
					PlcMemory[start] &= ~reset_mask;	// clear bits
					PlcMemory[start] |= set_mask;		// set bits
					this->UpdateRow((start / REGISTERS_PER_ROW));
					ans_len = 2;
					ans_start = start;
					ans_src = dest;
					ans_dest = src;
					AnswerRead(ans_dest, ans_src, ans_start, ans_len, cmd, transaction, ClientSocket);
					break;    

				case WRITE_CMD:    
				{
					DWORD	dwNumRows = 0,
							dwFirstRow,
							dwRow;

					this->m_pdlgCommStats->m_dwWriteCount++;

					//
					// Put the write data in the memory map
					//
                    for (i = 0; i < len; i++)
                    {
						PlcMemory[start + i] = write_val[i];
					}     
						
					dwNumRows = (len / REGISTERS_PER_ROW) + 1;
					dwFirstRow = (start / REGISTERS_PER_ROW);
					
					//
					// Update the rows changed
					//
					for (dwRow = 0; dwRow < dwNumRows; dwRow++)
					{
						this->UpdateRow(dwFirstRow + dwRow);
					}
                    ans_len = 2;
                    ans_start = start;
                    ans_src = dest;
					ans_dest = src;
                    AnswerRead(ans_dest, ans_src, ans_start, ans_len, cmd, transaction, ClientSocket);
                    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, ClientSocket);
					break;

                default:
					break;    
                }
            }
            else
            {
//                SendDLE(NAK, ClientSocket);
				this->m_pdlgCommStats->m_dwNakSentCount++;
            }
            break;

        default:
            rcv_state = DLE1;
        }
	 }// end of for loop

	}
	__finally
	{
		LeaveCriticalSection(&this->m_Lock);
	}

}


//
//	CALLBACK Function UdpSrvCallback() for the Server Receive Message
//
void EXPORT32 CALLBACK UdpSrvCallback(LPVOID ptr, SOCKADDR ClientSockAddr, DWORD dwTransferred )
{

	CItkPlcDlg		*pThis = (CItkPlcDlg *)ptr;

	pThis->ParseUdpMsg(ClientSockAddr, dwTransferred);
}


void CItkPlcDlg::ParseUdpMsg(SOCKADDR ClientSockAddr, 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)
								start		= 0,
								len			= 0, 
								cmd			= 0, 
								dle_flag	= 0,
								ans_len		= 0, 
								ans_start	= 0, 
								ans_src		= 0,	// destination (to who)
								ans_dest	= 0,	// source (our station)
								set_mask	= 0, 
								reset_mask	= 0,
								transaction	= 0;

	static unsigned short int	write_val[120];
	
	unsigned int				i;
	
	this->m_pdlgCommStats->m_dwAckRcvdCount++;
    
	for (dwLoop = 0; dwLoop < dwSize; dwLoop++)
	{
		Value = this->m_chReceiveBuffer[dwLoop];

		//
		//  Check for doubled-up DLE's
		//
		if (Value == DLE)
        {
			if (dle_flag)				// was previous dle ?
            {
				dle_flag = FALSE;       // clear flag
				continue;               // done
            }    
			else
			{
				dle_flag = TRUE;        // first dle
			}
        }
		else
		{
			dle_flag = FALSE;           // clear flag
		}

		switch (rcv_state)
        {
        case DLE1:
            if (Value == DLE)
            {
                calc_bcc = 0;			// reset bcc
                rcv_state = STX1;
            }
            break;

        case STX1:
			switch(Value)
			{
			case STX:
				if (this->m_bSourceStn)
				{
					rcv_state = SRC1;
				}
				else
				{
					rcv_state = DEST1;
				}
				calc_bcc = 0;			// reset bcc
				break;
			case NAK:
				rcv_state = DLE1;
				this->m_pdlgCommStats->m_dwNakRcvdCount++;
				AnswerRead(ans_dest, ans_src, ans_start, ans_len, cmd, transaction, INVALID_SOCKET, &ClientSockAddr);
				break;
			case ACK:
				rcv_state = DLE1;
				this->m_pdlgCommStats->m_dwAckRcvdCount++;
				break;
			}
			break;

		case SRC1:				// Source Station address
			src = Value;
			rcv_state = DEST1;
			calc_bcc += Value;
			break;

        case DEST1:				// Destination Station address
            dest = Value;
			//
			// Make sure the message is for us. A Local Station
			// set to 0 means to accept ALL messages.
			//
			if ((this->m_dwLocalStation == 0) || 
				(this->m_dwLocalStation == dest))
			{
				rcv_state = CMD1;
				calc_bcc += Value;
				break;
			}
			else
			{
				rcv_state = DLE1;
				this->m_pdlgCommStats->m_dwNakSentCount++;
				return;
			}

        case CMD1:				// Command
            cmd = Value;
			if (this->m_bTransNum)
			{
				rcv_state = TRANHI;
			}
			else
			{
				rcv_state = ADDLO;
			}
            calc_bcc += Value;
            break;

		case TRANHI:			// Transaction Number hi-byte
			transaction = (Value << 8);
			rcv_state = TRANLO;
			calc_bcc += Value;
			break;

		case TRANLO:			// Transaction Number lo-byte
			transaction += Value;
			rcv_state = ADDLO;
			calc_bcc += Value;
			break;

        case ADDLO:				// Start Adress lo-byte
            start = Value;
            rcv_state = ADDHI;
            calc_bcc += Value;
            break;

        case ADDHI:				// Start Address hi-byte
            start |= ((Value<<8) & 0xff00);
            calc_bcc += Value;
            switch (cmd)
            {
			case READ_CMD:
				rcv_state = LEN1;
				break;    
			case BIT_WRITE_CMD:
				rcv_state = SET1;
				break;    
			case WRITE_CMD:    
				len = 0;
				rcv_state = DATA1;
				break;    
			default:
				rcv_state = DLE1;
            }
            break;

       

⌨️ 快捷键说明

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