使用MSComm控件进行多串口通信(转载)

时间:2022-09-06 10:18:50
 

使用MSComm控件进行多串口通信(转载)

使用MSComm控件进行多串口通信(转载) 分类:
 
 

目录(?)[+]

 

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

 CMSComm* m_ctrlComm[50];

2 编写ID值

  使用MSComm控件进行多串口通信(转载)

 

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

1 在头文件中 

[html]  view plain  copy
 
  1. // Generated message map functions  
  2. //{{AFX_MSG(CSellWatchDlg)  
  3. afx_msg void OnOnCommMscomm1(UINT nID);  
  4. virtual BOOL OnInitDialog();  
  5. DECLARE_EVENTSINK_MAP()  
  6. //}}AFX_MSG  
  7. DECLARE_MESSAGE_MAP()  
 

2在cpp文件中

[html]  view plain  copy
 
  1. BEGIN_EVENTSINK_MAP(CSellWatchDlg, CDialog)  
  2. //{{AFX_EVENTSINK_MAP(CSellWatchDlg)  
  3.   
  4. //ON_EVENT(CSellWatchDlg, IDC_MSCOMM, 1 /* OnComm */, OnOnCommMscomm1, VTS_NONE)  
  5. //}}AFX_EVENTSINK_MAP  
  6. 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 打开串口

[html]  view plain  copy
 
  1. CString strPortNo;  
  2.       
  3.     // 保存ini各项值数组  
  4.     char szOption1[MAX_PATH];  
  5.     char szOption2[MAX_PATH];  
  6.     char szOption3[MAX_PATH];  
  7.     char szOption4[MAX_PATH];  
  8.     char szOption5[MAX_PATH];     
  9.       
  10.     CString str;  
  11.       
  12.     CString strNum;  
  13.       
  14.     g_strCommOpening = "已打开串口号";  
  15.       
  16.       
  17.     int n = GetCommNum();  
  18.       
  19.     int i =1,j=0;  
  20.       
  21.     if(n > 0)  
  22.     {  
  23.           
  24.         while( n > 0)  
  25.         {  
  26.             str = "COM";  
  27.               
  28.             strPortNo.Format("%d",i);  
  29.               
  30.             str= str+strPortNo;  
  31.               
  32.             char * p = str.GetBuffer(str.GetLength()+1);  
  33.               
  34.             Cini::ReadString(p , "串口号", szOption1, "COMM.ini");//端口号  
  35.               
  36.             if(szOption1[0] == '\0')  
  37.             {  
  38.                 i++;  
  39.   
  40.                 continue;         
  41.             }  
  42.   
  43.             i++;  
  44.               
  45.             p = str.GetBuffer(str.GetLength()+1);  
  46.               
  47.             Cini::ReadString(p , "波特率", szOption2, "COMM.ini");//波特率  
  48.             Cini::ReadString(p , "检验位", szOption3, "COMM.ini");//校验位  
  49.             Cini::ReadString(p , "数据位", szOption4, "COMM.ini");//数据位  
  50.             Cini::ReadString(p , "停止位", szOption5, "COMM.ini");//停止位  
  51.               
  52.             m_strPortNo.Format("%s",szOption1); //端口号  
  53.             m_strBaud.Format("%s",szOption2);//波特率  
  54.             m_strParity.Format("%s",szOption3);//校验位  
  55.             m_strDatabits.Format("%s",szOption4);//数据位  
  56.             m_strStopbits.Format("%s",szOption5);//停止位  
  57.               
  58.             UpdateData(FALSE);  
  59.               
  60.             //打开串口  
  61.               
  62.             int nport,nRate,nData,nStop;  
  63.               
  64.             char cCheck;  
  65.               
  66.             CString str_setting;  
  67.               
  68.             if(m_strParity == "无")  
  69.                 cCheck = 'n';   // 校验位为无  
  70.             else if ( m_strParity == "奇校验")  
  71.                 cCheck = 'o'; //校验位为奇校验  
  72.             else   
  73.                 cCheck = 'e'; // 校验位为偶校验  
  74.               
  75.             g_strPortNo = m_strPortNo;  
  76.               
  77.             nport = atoi(m_strPortNo);//端口号  
  78.               
  79.             nRate = atoi(m_strBaud);//波特率  
  80.               
  81.             //nCheck = atoi(strCheck);//校验位  
  82.               
  83.             nData = atoi (m_strDatabits);//数据位  
  84.               
  85.             nStop = atoi(m_strStopbits);//停止位  
  86.               
  87.             str_setting.Format(_T("%d, %c, %d, %d"), nRate, cCheck, nData, nStop);  
  88.               
  89.             m_ctrlComm[j]->SetCommPort(nport);//选择COM[nPort]  
  90.               
  91.             m_ctrlComm[j]->SetInputMode(1);//表示以二进制方式取回数据  
  92.               
  93.             m_ctrlComm[j]->SetInBufferSize(2000);//设置接收缓冲区大小  
  94.               
  95.             m_ctrlComm[j]->SetOutBufferSize(512);//设置发送缓冲区的大小  
  96.               
  97.             m_ctrlComm[j]->SetSettings(str_setting);  
  98.               
  99.             if(!m_ctrlComm[j]->GetPortOpen())  
  100.             {  
  101.                   
  102.                 m_ctrlComm[j]->SetPortOpen(TRUE);  
  103.             }  
  104.               
  105.             if(m_ctrlComm[j]->GetPortOpen())  
  106.             {  
  107.                 m_ctrlComm[j]->SetRThreshold(1);//每接收1个字节就产生一个OnComm 事件  
  108.                   
  109.                 m_ctrlComm[j]->SetInputLen(0);//表示一次读取全部数据  
  110.                   
  111.                 g_strCommOpening = g_strCommOpening+m_strPortNo+",";  
  112.             }  
  113.               
  114.             j++;  
  115.   
  116.             n--;  
  117.               
  118.         }  
  119.           
  120.     }  
  121.       
  122.     else  
  123.     {  
  124.         AfxMessageBox("请先设置串口");  
  125.           
  126.         CSerialPortDlg dlg;  
  127.           
  128.         dlg.DoModal();  
  129.           
  130.     }  


 

6 编写OnOnCommMscomm1(UINT nID)事件

[html]  view plain  copy
 
  1. VARIANT variant_inp;  
  2.   
  3. COleSafeArray safearray_inp;  
  4.   
  5. BOOL b = FALSE;  
  6.   
  7. LONG len=0;  
  8.   
  9. LONG k=0;  
  10.   
  11. //m_strReceive = _T("");  
  12.   
  13. BYTE rxdata[2048];  
  14.   
  15. CString strtemp = _T("");  
  16.   
  17. int i =nID - 900;  
  18.   
  19. m_strReceive[i] = _T("");  
  20.   
  21. if(m_ctrlComm[i] != NULL)  
  22. {  
  23.   
  24.     if(m_ctrlComm[i]->GetCommEvent() == 2) //如果接收缓冲区内有字符  
  25.     {  
  26.         Sleep(1000);  
  27.   
  28.         variant_inp = m_ctrlComm[i]->GetInput();//读缓冲区  
  29.           
  30.         safearray_inp = variant_inp;  
  31.           
  32.         len=safearray_inp.GetOneDimSize(); //得到有效数据长度  
  33.   
  34.         for( k=0; k<len; k++ )  
  35.         {  
  36.             safearray_inp.GetElement(&k,rxdata+k);//转换为BYTE型数组  
  37.               
  38.             BYTE bt=*(char*)(rxdata+k);//字符型  
  39.               
  40.             strtemp.Format("%c",bt);  
  41.               
  42.             m_strReceive[i]+=strtemp;//加入接受编辑框对应字符  
  43.         }  
  44.   
  45.         SYSTEMTIME sys;  
  46.           
  47.         GetLocalTime(&sys);//接收数据的日期及时间  
  48.           
  49.         int day = sys.wDay;  
  50.           
  51.         int month =sys.wMonth;  
  52.           
  53.         int year = sys.wYear;  
  54.           
  55.         int hour = sys.wHour;  
  56.           
  57.         int minute = sys.wMinute;  
  58.           
  59.         int second = sys.wSecond;  
  60.           
  61.         CString strDateStart,strTimeStart;  
  62.           
  63.         strDateStart.Format("%d-%d-%d",year,month,day);  
  64.           
  65.         strTimeStart.Format("%d:%d:%d",hour,minute,second);           
  66.           
  67.         m_strReceive[i] += strDateStart+"|"+strTimeStart+"|";  
  68.   
  69.         char *p10 = strTimeStart.GetBuffer(strTimeStart.GetLength()+1);  
  70.   
  71.         char *p0 = m_strReceive[i].GetBuffer(m_strReceive[i].GetLength()+1);  
  72.   
  73.         Cini::WriteString(p10, "商品详细信息", p0, "Log.ini");  
  74.           
  75.         //MessageBox(m_strReceive[i],"商品信息");  
  76.   
  77.         b = SplitInformation(m_strReceive[i]);  
  78.   
  79.         if(!b)//检测分割的数据  
  80.         {  
  81.             MessageBox("商品信息传输错误");  
  82.   
  83.             return ;  
  84.         }  
  85.                       
  86.         ShowString(m_strInfor);//叠加商品信息  
  87.   
  88.         VideoView();//销售预览  
  89.   
  90.         SendToTable(m_strReceive[i]);//存入数据库  
  91.           
  92.         m_ctrlComm[i]->SetInBufferCount(0);  
  93.               
  94.         UpdateData(FALSE);  
  95.           
  96.     }  
  97. }  
  98. else  
  99. {  
  100.     MessageBox("动态内存分配失败","警告",MB_ICONEXCLAMATION);  
  101. }