開(kāi)發(fā)真空測(cè)量與控制系統(tǒng)

2010-07-22 劉鼎鑫 上海玉川真空技術(shù)有限公司

開(kāi)發(fā)真空測(cè)量與控制系統(tǒng)
VC++下用MSComm控件實(shí)現(xiàn)PG500真空計(jì)與PC機(jī)的通訊

0、引言

  上海玉川真空有限技術(shù)公司推出的PG500+DM100AC真空計(jì)產(chǎn)品是可以和PC機(jī)、PLC、單片機(jī)系統(tǒng)、組態(tài)軟件--組態(tài)王等上位機(jī)進(jìn)行通訊的。本文建立PG500真空計(jì)與PC機(jī)的通訊,可以實(shí)現(xiàn)真空計(jì)的壓力值顯示、遠(yuǎn)程操作、狀態(tài)控制、數(shù)據(jù)處理等功能。本文介紹了在基于對(duì)話框的MFC應(yīng)用程序中應(yīng)用MSComm控件編程實(shí)現(xiàn)PG500真空計(jì)串口與PC機(jī)串口的控制代碼,并加入了測(cè)量數(shù)據(jù)的數(shù)據(jù)庫(kù)處理(如將真空計(jì)壓力數(shù)值記錄在Excel表格中等)。

1、硬件連接

  PG500真空計(jì)的通訊接口為RS-485串行接口,而PC機(jī)上為RS-232-C串口,所以事前準(zhǔn)備好了RS-485與RS-232-C的轉(zhuǎn)換器,連接方式如右圖

2、軟件代碼

  這里總結(jié)一下用MSComm控件進(jìn)行串口編程的基本步驟:

  • 在建立的工程中插入MSComm控件
  • 添加MSComm控件ID的控制變量或?qū)ο?
  • 對(duì)串口進(jìn)行初始化,設(shè)置MSComm控件的屬性
  • 添加串口事件的消息處理函數(shù)OnComm()函數(shù),在函數(shù)中根據(jù)應(yīng)用需要,編寫數(shù)據(jù)  處理代碼
  • 編寫串口發(fā)送等其他代碼
  • 關(guān)閉串口

2.1、創(chuàng)建工程并添加MSComm控件

  建立首先打開(kāi)VC 6.0,建立一個(gè)基于對(duì)話框的MFC應(yīng)用程序:PG500。在對(duì)話框中創(chuàng)建通信控件,若Control工具欄中缺少該控件,可通過(guò)菜單Project --> Add to Project --> Components and Control插入即可,再將該控件從工具箱中拉到對(duì)話框中。此時(shí),你只需要關(guān)心控件提供的對(duì) Windows 通訊驅(qū)動(dòng)程序的 API 函數(shù)的接口。換句話說(shuō),只需要設(shè)置和監(jiān)視MSComm控件的屬性和事件。

2.2、初始化串口:設(shè)置MSComm控件的屬性

  在CPG500Dlg::OnInitDialog()函數(shù)中寫入對(duì)串口的初始化語(yǔ)句:
   //串口初始化
   m_DM100Comm.SetCommPort(1);//選擇COM1
   m_DM100Comm.SetInputMode(1);//輸入方式為二進(jìn)制方式
   m_DM100Comm.SetInBufferSize(1024);//設(shè)置輸入緩沖區(qū)大小
    m_DM100Comm.SetOutBufferSize(512);//設(shè)置輸出緩沖區(qū)大小
   m_DM100Comm.SetSettings("9600,n,8,1");//波特率9600無(wú)檢驗(yàn)位,8個(gè)數(shù)據(jù)位,1個(gè)停止位
   if (!m_DM100Comm.GetPortOpen())//如果串口沒(méi)有打開(kāi)則打開(kāi)
    m_DM100Comm.SetPortOpen(TRUE);//打開(kāi)串口
    else
     AfxMessageBox("串口已打開(kāi)或不存在");
   m_DM100Comm.SetRThreshold(1);//接收緩沖區(qū)有1個(gè)及1個(gè)以上字符時(shí),將引發(fā)接收數(shù)據(jù)的OnComm事件
   m_DM100Comm.SetInputLen(0);//設(shè)置當(dāng)前接收區(qū)數(shù)據(jù)長(zhǎng)度為0,表示全部讀
   m_DM100Comm.GetInput();//先預(yù)讀緩沖區(qū)以清除殘留數(shù)據(jù)

2.3、添加串口事件消息處理函數(shù)

  MSComm控件一般用事件驅(qū)動(dòng)方式來(lái)從串口接收數(shù)據(jù),也就是消息處理,當(dāng)串口有時(shí)間發(fā)生時(shí),程序調(diào)用消息函數(shù)來(lái)處理數(shù)據(jù)。

  void CDM100Dlg::OnComm()
  {
   // TODO: Add your control notification handler code here
   VARIANT m_input;
   COleVariant nyVar;
   char* str;
   if(m_DM100Comm.GetCommEvent()==2)//事件值為2表示接收緩沖區(qū)
   {
    int l = m_DM100Comm.GetInBufferCount();
    if(l > 0)
    {
     nyVar.Attach(m_DM100Comm.GetInput());//讀緩沖區(qū)
     m_input=nyVar;//VARIANT型變量轉(zhuǎn)換為ColeSafeArray型變量
     str = (char*)(unsigned char*)m_input.parray->pvData;//字符型
    }
    str[l]='\0';
      if(str[0]==':')
       {
       m_zstrtmp=_T("");
      }
    m_zstrtmp+=(const char*)str;
    if(str[l-1]==0x0D)
    {
     if (m_bShowData)//已發(fā)送數(shù)據(jù)
     {
      m_strtmp=m_zstrtmp;
         m_strfinal=GetShowMode();//顯示壓力值的單位以及壓力數(shù)據(jù)顯示方式
      if (m_strtmp.Mid(3,2)=="1D")//
      {
       m_nCount1++;
       m_strRecv1=m_strfinal;
       if (m_bExcelSave)//存入Excel表格的數(shù)據(jù)
       {
        m_time=m_time.GetCurrentTime();
        m_SampleArray.Add(m_time.Format("%H:%M:%S"));
        m_SampleArray.Add(m_strRecv1);
       }
       UpdateData(FALSE);
      }
      else if (m_strtmp.Mid(3,2)=="2D")
       m_strRecv2=m_strfinal;
      else if (m_strtmp.Mid(3,2)=="1R") 
      m_strExpo1=m_strfinal;
      else if (m_strtmp.Mid(3,2)=="2R")
       m_strExpo2=m_strfinal;
      else if (m_strtmp.Mid(3,2)=="3R")
       m_strExpo3=m_strfinal;
           UpdateData(FALSE);
     }
     m_zstrtmp.Empty();
    }
   } 
  }

2.4、發(fā)送數(shù)據(jù)

  為發(fā)送按鈕添加一個(gè)單擊響應(yīng)函數(shù),添加如下代碼

  void CDM100Dlg::OnCheckCycleSend1() //向PG500配置的DM100顯示屏1通道循環(huán)發(fā)送數(shù)據(jù)

{
 // TODO: Add your control notification handler code here
 if (m_bAutoSend2)
 {
  m_ctrlCycleSend2.SetCheck(0);
  KillTimer(2);
 }
 if (m_ctrlCycleSend1.GetCheck())
 {
  m_bAutoSend1=TRUE;
 ((CButton*)GetDlgItem(IDC_BTN_PORT_OPEN))->EnableWindow(FALSE);
  SetTimer(1,m_nCycleTime1,NULL);
 }
 else
 {
  m_bAutoSend1=FALSE;
  ((CButton*)GetDlgItem(IDC_BTN_PORT_OPEN))->EnableWindow();
  KillTimer(1);
 }
}
void CDM100Dlg::OnCheckCycleSend2() //向PG500配置的DM100顯示屏2通道循環(huán)發(fā)送數(shù)據(jù)
{
 // TODO: Add your control notification handler code here
 if (m_bAutoSend1)
 {
  m_ctrlCycleSend1.SetCheck(0);
  KillTimer(1);
 }
 if (m_ctrlCycleSend2.GetCheck())
 {
  m_bAutoSend2=TRUE;
 ((CButton*)GetDlgItem(IDC_BTN_PORT_OPEN))->EnableWindow(FALSE);
  SetTimer(2,m_nCycleTime2,NULL);
 }
 else
 {
  m_bAutoSend2=FALSE;
  ((CButton*)GetDlgItem(IDC_BTN_PORT_OPEN))->EnableWindow();
  KillTimer(2);
 }
}
定時(shí)器消息處理函數(shù)代碼如下:
void CDM100Dlg::OnTimer(UINT nIDEvent)
{
 // TODO: Add your message handler code here and/or call default
switch (nIDEvent)
 {
 case 1:
  OnBtnShow1();//1通道發(fā)送一次數(shù)據(jù)
  break;
 case 2:
  OnBtnShow2();//2通道發(fā)送一次數(shù)據(jù)
  break;
 case 3:
  SetWindowText(m_strCaption.Mid(0,13+m_ncaption));
  if(m_ncaption<(m_strCaption.GetLength()+1))
      m_ncaption++;
  else
   m_ncaption=0;
  break;
 default:
  break;
 }
 CDialog::OnTimer(nIDEvent);
}

3、結(jié)束語(yǔ)

  使用以上代碼可以通過(guò)PC機(jī)實(shí)現(xiàn)PG500真空計(jì)的遠(yuǎn)程設(shè)置、壓力顯示、狀態(tài)控制、數(shù)據(jù)處理等過(guò)程。

  注:以上代碼為PG500真空計(jì)與PC機(jī)通訊的主干代碼,另有大部分函數(shù)原型由于文字限制在本文中未寫出。 真空測(cè)量軟件開(kāi)發(fā)可聯(lián)系仇小姐,電話:021-61526449,分機(jī)號(hào)8002