使用MSComm控件进行多串口通信

1 在类的头文件中定义串口控件数组

 CMSComm* m_ctrlComm[50];

2 编写ID值

 

 

3 手动添加事件,不要利用ClassWizard

1 在头文件中 
	// Generated message map functions
	//{{AFX_MSG(CSellWatchDlg)
	afx_msg void OnOnCommMscomm1(UINT nID);
	virtual BOOL OnInitDialog();
	DECLARE_EVENTSINK_MAP()
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()

 
2在cpp文件中
BEGIN_EVENTSINK_MAP(CSellWatchDlg, CDialog)
//{{AFX_EVENTSINK_MAP(CSellWatchDlg)

//ON_EVENT(CSellWatchDlg, IDC_MSCOMM, 1 /* OnComm */, OnOnCommMscomm1, VTS_NONE)
//}}AFX_EVENTSINK_MAP
ON_EVENT_RANGE(CSellWatchDlg, IDC_MSCOMM,IDC_MSCOMM+49, 1 /* OnComm */, OnOnCommMscomm1,  VTS_I4 )

4 在OnInitDialog()初始化控件数组


 for(int i=0; i<50; i++)
 {
  m_ctrlComm[i] = new CMSComm();
  
  if(!m_ctrlComm[i]->Create(NULL,style,CRect(0,0,0,0),this,IDC_MSCOMM+i))
  {
   AfxMessageBox("创建MSComm失败");
  }

 }

5 打开串口

CString strPortNo;
	
	// 保存ini各项值数组
	char szOption1[MAX_PATH];
	char szOption2[MAX_PATH];
	char szOption3[MAX_PATH];
	char szOption4[MAX_PATH];
	char szOption5[MAX_PATH];	
	
	CString str;
	
	CString strNum;
	
	g_strCommOpening = "已打开串口号";
	
	
	int n = GetCommNum();
	
	int i =1,j=0;
	
	if(n > 0)
	{
		
		while( n > 0)
		{
			str = "COM";
			
			strPortNo.Format("%d",i);
			
			str= str+strPortNo;
			
			char * p = str.GetBuffer(str.GetLength()+1);
			
			Cini::ReadString(p , "串口号", szOption1, "COMM.ini");//端口号
			
			if(szOption1[0] == '\0')
			{
				i++;

				continue;		
			}

			i++;
			
			p = str.GetBuffer(str.GetLength()+1);
			
			Cini::ReadString(p , "波特率", szOption2, "COMM.ini");//波特率
			Cini::ReadString(p , "检验位", szOption3, "COMM.ini");//校验位
			Cini::ReadString(p , "数据位", szOption4, "COMM.ini");//数据位
			Cini::ReadString(p , "停止位", szOption5, "COMM.ini");//停止位
			
			m_strPortNo.Format("%s",szOption1); //端口号
			m_strBaud.Format("%s",szOption2);//波特率
			m_strParity.Format("%s",szOption3);//校验位
			m_strDatabits.Format("%s",szOption4);//数据位
			m_strStopbits.Format("%s",szOption5);//停止位
			
			UpdateData(FALSE);
			
			//打开串口
			
			int nport,nRate,nData,nStop;
			
			char cCheck;
			
			CString str_setting;
			
			if(m_strParity == "无")
				cCheck = 'n';   // 校验位为无
			else if ( m_strParity == "奇校验")
				cCheck = 'o'; //校验位为奇校验
			else 
				cCheck = 'e'; // 校验位为偶校验
			
			g_strPortNo = m_strPortNo;
			
			nport = atoi(m_strPortNo);//端口号
			
			nRate = atoi(m_strBaud);//波特率
			
			//nCheck = atoi(strCheck);//校验位
			
			nData = atoi (m_strDatabits);//数据位
			
			nStop = atoi(m_strStopbits);//停止位
			
			str_setting.Format(_T("%d, %c, %d, %d"), nRate, cCheck, nData, nStop);
			
			m_ctrlComm[j]->SetCommPort(nport);//选择COM[nPort]
			
			m_ctrlComm[j]->SetInputMode(1);//表示以二进制方式取回数据
			
			m_ctrlComm[j]->SetInBufferSize(2000);//设置接收缓冲区大小
			
			m_ctrlComm[j]->SetOutBufferSize(512);//设置发送缓冲区的大小
			
			m_ctrlComm[j]->SetSettings(str_setting);
			
			if(!m_ctrlComm[j]->GetPortOpen())
			{
				
				m_ctrlComm[j]->SetPortOpen(TRUE);
			}
			
			if(m_ctrlComm[j]->GetPortOpen())
			{
				m_ctrlComm[j]->SetRThreshold(1);//每接收1个字节就产生一个OnComm 事件
				
				m_ctrlComm[j]->SetInputLen(0);//表示一次读取全部数据
				
				g_strCommOpening = g_strCommOpening+m_strPortNo+",";
			}
			
			j++;

			n--;
			
		}
		
	}
	
	else
	{
		AfxMessageBox("请先设置串口");
		
		CSerialPortDlg dlg;
		
		dlg.DoModal();
		
	}


 

6 编写OnOnCommMscomm1(UINT nID)事件

	VARIANT variant_inp;
	
	COleSafeArray safearray_inp;

	BOOL b = FALSE;

	LONG len=0;
	
	LONG k=0;
	
	//m_strReceive = _T("");
	
	BYTE rxdata[2048];
	
	CString strtemp = _T("");
	
	int i =nID - 900;
	
	m_strReceive[i] = _T("");

	if(m_ctrlComm[i] != NULL)
	{

		if(m_ctrlComm[i]->GetCommEvent() == 2) //如果接收缓冲区内有字符
		{
			Sleep(1000);

			variant_inp = m_ctrlComm[i]->GetInput();//读缓冲区
			
			safearray_inp = variant_inp;
			
			len=safearray_inp.GetOneDimSize(); //得到有效数据长度

			for( k=0; k<len; k++ )
			{
				safearray_inp.GetElement(&k,rxdata+k);//转换为BYTE型数组
				
				BYTE bt=*(char*)(rxdata+k);//字符型
				
				strtemp.Format("%c",bt);
				
				m_strReceive[i]+=strtemp;//加入接受编辑框对应字符
			}

			SYSTEMTIME sys;
			
			GetLocalTime(&sys);//接收数据的日期及时间
			
			int day = sys.wDay;
			
			int month =sys.wMonth;
			
			int year = sys.wYear;
			
			int hour = sys.wHour;
			
			int minute = sys.wMinute;
			
			int second = sys.wSecond;
			
			CString strDateStart,strTimeStart;
			
			strDateStart.Format("%d-%d-%d",year,month,day);
			
			strTimeStart.Format("%d:%d:%d",hour,minute,second);			
			
			m_strReceive[i] += strDateStart+"|"+strTimeStart+"|";
	
			char *p10 = strTimeStart.GetBuffer(strTimeStart.GetLength()+1);

			char *p0 = m_strReceive[i].GetBuffer(m_strReceive[i].GetLength()+1);
	
			Cini::WriteString(p10, "商品详细信息", p0, "Log.ini");
			
			//MessageBox(m_strReceive[i],"商品信息");

			b = SplitInformation(m_strReceive[i]);

			if(!b)//检测分割的数据
			{
				MessageBox("商品信息传输错误");

				return ;
			}
						
			ShowString(m_strInfor);//叠加商品信息

			VideoView();//销售预览

			SendToTable(m_strReceive[i]);//存入数据库
			
			m_ctrlComm[i]->SetInBufferCount(0);
				
			UpdateData(FALSE);
			
		}
	}
	else
	{
		MessageBox("动态内存分配失败","警告",MB_ICONEXCLAMATION);
	}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值