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

📄 jkmodbusdlg.cpp

📁 MODBUS主、子站规约模拟程序。可以做为MODBUS规约测试的工具
💻 CPP
📖 第 1 页 / 共 2 页
字号:

/* --------------------------------------------------------
 *	函数名称:	QueryYXState							  *	
 *	功能    :	遥信状态查询							  *
 *	参数    :	pYXData ---- 指向遥信数据缓冲区			  *
 *				iYXID   ---- 遥信点的序号                 * 
 *	返回值  :	遥信状态							      *
 -------------------------------------------------------- */													
BOOL CJkModbusDlg::QueryYXState(BYTE* pYXData, int iYXID)
{
	if(pYXData == NULL) {
		TRACE("The pointer don`t be initialized!\n");
		return FALSE;
	}

	if(pYXData[iYXID] == 0x01)
		return TRUE;

	if(pYXData[iYXID] == 0x00)
		return FALSE;

	return TRUE;
}

void CJkModbusDlg::SetYXState(BYTE* pYXData, int iYXID)
{
	pYXData[iYXID]=m_bytStateValue;
}

WORD CJkModbusDlg::GetCrc(BYTE *DataFrame,int FrameNum)
{
	WORD ret32;
	ret32=crc->getcrc((char *)&DataFrame[0],FrameNum);
	return ret32;
}

void CJkModbusDlg::OnProducemessage() //生成报文
{
	// TODO: Add your control notification handler code here
	UpdateData(TRUE);
	CString str;
	SYSTEMTIME tm;
	GetLocalTime(&tm);
	CString time;
	time.Format(_T("%2d日%02.2d:%2.2d"), tm.wDay,tm.wMinute, tm.wSecond);
	BYTE yxdata[1024];
	BYTE* ucharYxData = yxdata;
	if(m_nYXNum != 0) {
		
		if(!m_nRead)
		{
			YxFrameNum= ReadFrame(ucharYxData,yxdata);
			for (int i=0; i<YxFrameNum; i++)
			{
				str.Format(str+"%02X"+" ",yxdata[i]);
			}			
			str=time+"读数据:"+'\r'+'\n'+str+'\r'+'\n'+"发送数据成功";
			m_szSendView = m_szSendView + str+'\r'+'\n'+'\r'+'\n';			
		}		
		else
		{
			YxFrameNum= WriteFrame(ucharYxData,yxdata);
			for (int i=0; i<YxFrameNum; i++)
			{
				str.Format(str+"%02X"+" ",yxdata[i]);
			}			
			str=time+"写数据:"+'\r'+'\n'+str+'\r'+'\n'+"发送数据成功";
			m_szSendView = m_szSendView + str+'\r'+'\n'+'\r'+'\n'  ;
		}			
	}

	UpdateData(FALSE);
	m_edtSendView.LineScroll(m_edtSendView.GetLineCount());//使滚动条向下.注意m_szSendView累加时,放前和放后有区别.
}

void CJkModbusDlg::OnWritevalue() //单点设置状态
{
	// TODO: Add your control notification handler code here
	UpdateData(TRUE);
	SetYXState(m_bytLocalYXData,m_nIDNumber);
	UpdateData(FALSE);
}

void CJkModbusDlg::OnAlldispart() //状态全分
{
	// TODO: Add your control notification handler code here
	UpdateData(TRUE);
	for(int i=0;i<m_nYXNum;i++)
	{
		m_bytLocalYXData[i]=0X00;
	}
	UpdateData(FALSE);	
}

void CJkModbusDlg::OnAllshut() //状态全合
{
	// TODO: Add your control notification handler code here
	UpdateData(TRUE);
	for(int i=0;i<m_nYXNum;i++)
	{
		m_bytLocalYXData[i]=0X01;
	}
	UpdateData(FALSE);	
}

void CJkModbusDlg::OnClearsend() 
{
	// TODO: Add your control notification handler code here
	UpdateData(TRUE);
	m_szSendView.Empty();	
	UpdateData(FALSE);	
}

void CJkModbusDlg::OnClearreceive() 
{
	// TODO: Add your control notification handler code here
	UpdateData(TRUE);
	m_szReceiveView.Empty();	
	UpdateData(FALSE);	
}

void CJkModbusDlg::OnCommset() 
{
	// TODO: Add your command handler code here

	CDlgComSet	DlgComSet;
	DlgComSet.m_szPort = m_Com->m_szPortName;

	CString br;
	br.Format("%d", m_Com->m_lBaudRate);
	DlgComSet.m_szBaud = br;
	
	CString jy;
	switch(m_Com->m_nParity)
	{
		case ODDPARITY:
			jy = "奇校验";
			break;
		case EVENPARITY:
			jy = "偶校验";
			break;
		default:
			jy = "无校验";
			break;
	}
	DlgComSet.m_szParity = jy;

	if(DlgComSet.DoModal() == IDOK)
	{
		m_Com->m_szPortName	= DlgComSet.m_szPort;
		m_Com->m_lBaudRate		= atol(DlgComSet.m_szBaud);
		jy = DlgComSet.m_szParity;
		if(jy == "奇校验")
			m_Com->m_nParity = ODDPARITY;
		else if(jy == "偶校验")
			m_Com->m_nParity = EVENPARITY;
		else 
			m_Com->m_nParity = NOPARITY;

/*		if(m_Com != INVALID_HANDLE_VALUE)//设置串口后直接打开串口
		{
			m_Com->ClosePort();
			Sleep(10);		// I don't know reason,if don't do this,OpenPort may fail
			m_Com->OpenPort();
		}
*/	}
}

void CJkModbusDlg::OnCommopen() 
{
	// TODO: Add your command handler code here
	m_Com->OpenPort();
	if(!m_Com->PortOpened())
	{
		AfxMessageBox("不能打开通信口"+m_Com->m_szPortName);
		return;
	}
	m_Com->SetThreshold(1);
}

void CJkModbusDlg::OnCommclose() 
{
	// TODO: Add your command handler code here
	m_Com->ClosePort();
	if(m_chkContinualSend)
	{
		KillTimer(ID_SEND);		
	}
}

void CJkModbusDlg::OnSenddata() 
{
	// TODO: Add your control notification handler code here
	
	if (!m_Com->PortOpened())
	{
		AfxMessageBox("通讯串口没有打开!");
		return;
	}
	BYTE yxdata[1024];
	BYTE* ucharYxData = yxdata;
	if(!m_nRead)
	{
		YxFrameNum= ReadFrame(ucharYxData,yxdata);
	}
	else{
		YxFrameNum= WriteFrame(ucharYxData,yxdata);
	}
	
	m_bSendok = m_Com->Send((BYTE*)(ucharYxData), YxFrameNum);
	if(m_bSendok)OnProducemessage();

}

void CJkModbusDlg::OnUpdateCommopen(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	UpdateData(TRUE);
	pCmdUI->Enable(!m_Com->PortOpened());
	pCmdUI->SetCheck(1);
	UpdateData(FALSE);
}

void CJkModbusDlg::OnUpdateCommclose(CCmdUI* pCmdUI) 
{
	// TODO: Add your command update UI handler code here
	UpdateData(TRUE);
	pCmdUI->Enable(m_Com->PortOpened());
	UpdateData(FALSE);
	/*
	//是否在 显示在所有窗口最前端 菜单项打上标记
			if(m_bAlwaysTop)
			{
				pMenu->CheckMenuItem( IDC_ALWAYSTOP,MF_CHECKED);    
			}
			else
			{
				pMenu->CheckMenuItem( IDC_ALWAYSTOP,MF_UNCHECKED);    
			}
*/
}

void CJkModbusDlg::OnTimer(UINT nIDEvent) 
{
	// TODO: Add your message handler code here and/or call default
	OnSenddata();
	CDialog::OnTimer(nIDEvent);
}

void CJkModbusDlg::OnContinuesend() 
{
	// TODO: Add your control notification handler code here
	UpdateData(true);
	if(m_chkContinualSend)
	{
		SetTimer(ID_SEND, m_dwInterval, NULL);
	} 
	else
	{
		m_nSendTimes = 0;
		UpdateData(false);
		KillTimer(ID_SEND);
	}		
}

LRESULT CJkModbusDlg::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) 
{
	// TODO: Add your specialized code here and/or call the base class
	if(message == WM_COM)
	{
		if(wParam != COM_THRESHOLD)
		{
			if(wParam == 5)
			{
				int m_xx=0;
				m_xx++;
//				char buf[10];
//				SetDlgItemText(IDC_EDIT1, itoa(m_xx, buf, 10));
			}
			return 0;
		}
		
		bool m_bRvSucced;
		BYTE buff[2048];
//		BYTE receive[2048];
		DWORD dwReaded=0;
		if(!m_nRead)
		{
			m_bRvSucced = m_Com->Receive(buff, 1024, dwReaded);//接收数据的长度dwReaded
			buff[dwReaded] = '\0';
			ReceiveDataDeal_write(buff, dwReaded);
			char ShowValue[2];
			for(DWORD i=0; i<dwReaded; i++) 
			{
				wsprintf(ShowValue, "%02X", buff[i]);//取两位十六进制方式数据
				m_szReceiveView += ShowValue;
				m_szReceiveView += 0X20;//接收数据间的空格
				if(i%8 == 0 && i>0)
				{
					m_szReceiveView = m_szReceiveView + "\r\n";
				}	
			}

		}
		else
		{
			m_bRvSucced = m_Com->Receive(buff, 8, dwReaded);//接收数据的长度dwReaded
			buff[dwReaded] = '\0';
			ReceiveDataDeal_read(buff, dwReaded);
				char ShowValue[2];
				for(DWORD i=0; i<dwReaded; i++) 
				{
					wsprintf(ShowValue, "%02X", buff[i]);//取两位十六进制方式数据
					m_szReceiveView += ShowValue;
					m_szReceiveView += 0X20;//接收数据间的空格
				}
			if(dwReaded != 0)m_szReceiveView = m_szReceiveView + "\r\n";
		}		

		
		if((UINT)m_szReceiveView.GetLength() >= 1024) {
			m_szReceiveView = "";
			UpdateData(false);
		}		


		SetDlgItemText(IDC_RECEIVEVIEW, m_szReceiveView);//显示接收的数据
//		UpdateData(false);

		m_Com->SetThreshold(1);
		return true;
	} 
	else
	{
		return CDialog::WindowProc(message, wParam, lParam);
	}
	
}

void CJkModbusDlg::ReceiveDataDeal_write(BYTE receive[], DWORD r)
{
	


}

void CJkModbusDlg::ReceiveDataDeal_read(BYTE receive[], DWORD r)
{	
	WORD CRC;
	int DataLength;
	DataLength=(int)r-2;
	CRC=GetCrc(receive,DataLength);
	BYTE bytLowCRC = LOBYTE(CRC);
	BYTE bytHightCRC = HIBYTE(CRC);
	CString str="",StrValue="";
	str.Format(str+"%02X",bytLowCRC);
	str.Format(str+" %02X",bytHightCRC);
	
	if(receive[0] == m_bytSlaveAddress)
	{
		if(receive[1] == 0x05)return;
		bytComand = receive[1];		
//		if(receive[6] == bytLowCRC && receive[7]==bytHightCRC)
//		{	
			BYTE yxdata[1024];
			BYTE* ucharYxData = yxdata;			
			YxFrameNum= WriteFrame(ucharYxData,yxdata);	
			
			m_bSendok = m_Com->Send((BYTE*)(ucharYxData), YxFrameNum);
			if(m_bSendok)OnProducemessage();
//		}
//		else 
//		{
//			StrValue.Format(StrValue+"%02x",receive[6]);
//			StrValue.Format(StrValue+" %02X",receive[7]);
//			m_szReceiveView = m_szReceiveView + "\r\n" + "CRC校验码错误:应该为"+str+" 接收为:"+StrValue+"\r\n";
//			UpdateData(false);
//		}
	}
	
			
}

⌨️ 快捷键说明

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