使用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);
- }