串口調試助手源程序及編程詳細過程(轉載)

 

串口調試助手源程序及編程詳細過程(轉載)

標籤: 編程microsoftbytebtinitializationcomponents

 

 

http://www.gjwtech.com/vcandc/scommassistantcode.htm編程

目次:數組

1.創建項目  安全

2.在項目中插入MSComm控件函數

3.利用ClassWizard定義CMSComm類控制變量工具

4.在對話框中添加控件  post

5.添加串口事件消息處理函數OnComm()測試

6.打開和設置串口參數spa

7.發送數據.net

 

 

    在衆多網友的支持下,串口調試助手從2001年5月21日發佈至今,短短一個月,在全國各地累計下載量近5000人次,在近200多個電子郵件中,20多人提供了使用測試意見,更有50多位朋友提出要串口調試助手的源代碼,爲了答謝謝朋友們的支持,公開推出我最初用VC控件MSComm編寫串口通訊程序的源代碼,並寫出詳細的編程過程,姑且叫串口調試助手源程序V1.0或VC串口通信源程序吧,我相信,若是你用VC編程,那麼有了這個代碼,就能夠垂手可得地完成串口編程任務了。(也許本文過於詳細,高手就不用看)翻譯

開始吧:

1.創建項目:打開VC++6.0,創建一個基於對話框的MFC應用程序SCommTest(與我源代碼一致,等會你會方便一點);

2.在項目中插入MSComm控件   選擇Project菜單下Add To Project子菜單中的 Components and Controls…選項,在彈出的對話框中雙擊Registered ActiveX Controls項(稍等一會,這個過程較慢),則全部註冊過的ActiveX控件出如今列表框中。 選擇Microsoft Communications Control, version 6.0,,單擊Insert按鈕將它插入到咱們的Project中來,接受缺省的選項。(若是你在控件列表中看不到Microsoft Communications Control, version 6.0,那多是你在安裝VC6時沒有把ActiveX一項選上,從新安裝VC6,選上ActiveX就能夠了),

這時在ClassView視窗中就能夠看到CMSComm類了,(注意:此類在ClassWizard中看不到,重構clw文件也同樣),而且在控件工具欄Controls中出現了電話圖標(如圖1所示),如今要作的是用鼠標將此圖標拖到對話框中,程序運行後,這個圖標是看不到的。

3.利用ClassWizard定義CMSComm類控制對象 打開ClassWizard->Member Viariables選項卡,選擇CSCommTestDlg類,爲IDC_MSCOMM1添加控制變量:m_ctrlComm,這時你能夠看一看,在對話框頭文件中自動加入了//{{AFX_INCLUDES() #include "mscomm.h" //}}AFX_INCLUDES (這時運行程序,若是有錯,那就再從頭開始)。

4.在對話框中添加控件 向主對話框中添加兩個編輯框,一個用於接收顯示數據ID爲IDC_EDIT_RXDATA,另外一個用於輸入發送數據,ID爲IDC_EDIT_TXDATA,再添加一個按鈕,功能是按一次就把發送編輯框中的內容發送一次,將其ID設爲IDC_BUTTON_MANUALSEND。別忘記了將接收編輯框的Properties->Styles中把Miltiline和Vertical Scroll屬性選上,發送編輯框若你想輸入多行文字,也可選上Miltiline。

再打開ClassWizard->Member Viariables選項卡,選擇CSCommTestDlg類, 爲IDC_EDIT_RXDATA添加CString變量m_strRXData, 爲IDC_EDIT_TXDATA添加CString變量m_strTXData。說明: m_strRXData和m_strTXData分別用來放入接收和發送的字符數據。

      休息一會吧?咱們每天與電腦打交道,要注意保重,我如今在單槓上作引體向上能夠來40次,可我都32了,佩服嗎?。。。。。。好了,再接着來,下面是關鍵了:

5.添加串口事件消息處理函數OnComm() 打開ClassWizard->Message Maps,選擇類CSCommTestDlg,選擇IDC_MSCOMM1,雙擊消息OnComm,將彈出的對話框中將函數名改成OnComm,(好記而已)OK。

這個函數是用來處理串口消息事件的,如每當串口接收到數據,就會產生一個串口接收數據緩衝區中有字符的消息事件,咱們剛纔添加的函數就會執行,咱們在OnComm()函數加入相應的處理代碼就能實現自已想要的功能了。請你在函數中加入以下代碼:

void CSCommTestDlg::OnComm() 
{
    // TODO: Add your control notification handler code here
    VARIANT variant_inp;
    COleSafeArray safearray_inp;
    LONG len,k;
    BYTE rxdata[2048]; //設置BYTE數組 An 8-bit integerthat is not signed.
    CString strtemp;
    if(m_ctrlComm.GetCommEvent()==2) //事件值爲2表示接收緩衝區內有字符
    {             ////////如下你能夠根據本身的通訊協議加入處理代碼
        variant_inp=m_ctrlComm.GetInput(); //讀緩衝區
        safearray_inp=variant_inp; //VARIANT型變量轉換爲ColeSafeArray型變量
        len=safearray_inp.GetOneDimSize(); //獲得有效數據長度
        for(k=0;k<len;k++)
            safearray_inp.GetElement(&k,rxdata+k);//轉換爲BYTE型數組
        for(k=0;k<len;k++) //將數組轉換爲Cstring型變量
        {
            BYTE bt=*(char*)(rxdata+k); //字符型
            strtemp.Format("%c",bt); //將字符送入臨時變量strtemp存放
            m_strRXData+=strtemp; //加入接收編輯框對應字符串 
        }
    }
    UpdateData(FALSE); //更新編輯框內容
}

到目前爲止還不能在接收編輯框中看到數據,由於咱們尚未打開串口,但運行程序不該該有任何錯誤,否則,你確定哪兒沒看仔細,由於我是打開VC6對照着作一步寫一行的,運行試試。沒錯吧?那麼作下一步:

6.打開串口和設置串口參數 你能夠在你須要的時候打開串口,例如在程序中作一個開始按鈕,在該按鈕的處理函數中打開串口。如今咱們在主對話框的CSCommTestDlg::OnInitDialog()打開串口,加入以下代碼:

// TODO: Add extra initialization here
if(m_ctrlComm.GetPortOpen())
m_ctrlComm.SetPortOpen(FALSE);

m_ctrlComm.SetCommPort(1); //選擇com1
if( !m_ctrlComm.GetPortOpen())
m_ctrlComm.SetPortOpen(TRUE);//打開串口
else
AfxMessageBox("cannot open serial port");

m_ctrlComm.SetSettings("9600,n,8,1"); //波特率9600,無校驗,8個數據位,1箇中止位

m_ctrlComm.SetInputModel(1); //1:表示以二進制方式檢取數據
m_ctrlComm.SetRThreshold(1); 
//參數1表示每當串口接收緩衝區中有多於或等於1個字符時將引起一個接收數據的OnComm事件
m_ctrlComm.SetInputLen(0); //設置當前接收區數據長度爲0
m_ctrlComm.GetInput();//先預讀緩衝區以清除殘留數據

如今你能夠試試程序了,將串口線接好後(不會接?去看看我寫的串口接線基本方法),打開串口調試助手,並將串口設在com2,選上自動發送,也能夠等會手動發送。再執行你編寫的程序,接收框裏應該有數據顯示了。

7.發送數據 先爲發送按鈕添加一個單擊消息即BN_CLICKED處理函數,打開ClassWizard->Message Maps,選擇類CSCommTestDlg,選擇IDC_BUTTON_MANUALSEND,雙擊BN_CLICKED添加OnButtonManualsend()函數,並在函數中添加以下代碼:

void CSCommTestDlg::OnButtonManualsend() 
{
// TODO: Add your control notification handler code here
UpdateData(TRUE); //讀取編輯框內容
m_ctrlComm.SetOutput(COleVariant(m_strTXData));//發送數據
}

運行程序,在發送編輯框中隨意輸入點什麼,單擊發送按鈕,啊!看看,在另外一端的串口調試助手(或別的調試工具)接收框裏出現了什麼。

若是你真是初次涉獵串口編程,又一次成功,那該說聲謝謝我了,由於我第一次作串口程序時可費勁了,那時網上的資料也很差找。開開玩笑,謝謝你的支持,有什麼好東西別忘了給我寄一份。

最後說明一下,因爲用到VC控件,在沒有安裝VC的計算機上運行時要從VC中把mscomm32.ocx、msvcrt.dll、mfc42.dll拷到Windows目錄下的System子目錄中(win2000爲System32)並再進行註冊設置,請參考

如何手工註冊MSComm控件。

龔建偉 2001.6.20


什麼是VARIANT數據類型?如何使用VARIANT數據類型? 怎麼以十六進制或二進制發送和接收?

若是還想再深刻了解,請看:

串口調試助手源程序及編程詳細過程(二)2001.8.26

目次:

1.創建項目  

2.在項目中插入MSComm控件

3.利用ClassWizard定義CMSComm類控制變量

4.在對話框中添加控件  

5.添加串口事件消息處理函數OnComm()

6.打開和設置串口參數

7.發送數據

8.發送十六進制字符

9.在接收框中以十六進制顯示

10.如何設置自動發送

11.什麼是VARIANT數據類型?如何使用VARIANT數據類型?

 

 

    這是串口調試助手源程序及編程詳細過程(一)的續篇,首先謝謝朋友們的支持與鼓勵。

  

8.發送十六進制字符

    在主對話框中加入一個複選接鈕,ID爲IDC_CHECK_HEXSEND Caption: 十六進制發送,再利用ClassWizard爲其添加控制變量:m_ctrlHexSend;

    在ClassView中爲SCommTestDlg類添加如下兩個PUBLIC成員函數,並輸入相應代碼;

 

 

[cpp]  view plain  copy
 
  1. //因爲這個轉換函數的格式限制,在發送框中的十六制字符應該每兩個字符之間插入一個空隔  
  2. //如:A1 23 45 0B 00 29  
  3. //CByteArray是一個動態字節數組,可參看MSDN幫助  
  4. int CSCommTestDlg::String2Hex(CString str, CByteArray &senddata)  
  5. {  
  6. int hexdata,lowhexdata;  
  7. int hexdatalen=0;  
  8. int len=str.GetLength();  
  9. senddata.SetSize(len/2);  
  10. for(int i=0;i<len;)  
  11. {  
  12. char lstr,hstr=str[i];  
  13. if(hstr==' ')  
  14. {  
  15. i++;  
  16. continue;  
  17. }  
  18. i++;  
  19. if(i>=len)  
  20. break;  
  21. lstr=str[i];  
  22. hexdata=ConvertHexChar(hstr);  
  23. lowhexdata=ConvertHexChar(lstr);  
  24. if((hexdata==16)||(lowhexdata==16))  
  25. break;  
  26. else  
  27. hexdata=hexdata*16+lowhexdata;  
  28. i++;  
  29. senddata[hexdatalen]=(char)hexdata;  
  30. hexdatalen++;  
  31. }  
  32. senddata.SetSize(hexdatalen);  
  33. return hexdatalen;  
  34. }  
  35.   
  36. //這是一個將字符轉換爲相應的十六進制值的函數  
  37. //好多C語言書上均可以找到  
  38. //功能:如果在0-F之間的字符,則轉換爲相應的十六進制字符,不然返回-1  
  39. char CSCommTestDlg::ConvertHexChar(char ch)  
  40. {  
  41. if((ch>='0')&&(ch<='9'))  
  42. return ch-0x30;  
  43. else if((ch>='A')&&(ch<='F'))  
  44. return ch-'A'+10;  
  45. else if((ch>='a')&&(ch<='f'))  
  46. return ch-'a'+10;  
  47. else return (-1);  
  48. }  

 

 

再將CSCommTestDlg::OnButtonManualsend()修改爲如下形式:

 

[cpp]  view plain  copy
 
  1. void CSCommTestDlg::OnButtonManualsend()  
  2. {  
  3. // TODO: Add your control notification handler code here  
  4. UpdateData(TRUE); //讀取編輯框內容  
  5. if(m_ctrlHexSend.GetCheck())  
  6. {  
  7. CByteArray hexdata;  
  8. int len=String2Hex(m_strTXData,hexdata); //此處返回的len能夠用於計算髮送了多少個十六進制數  
  9. m_ctrlComm.SetOutput(COleVariant(hexdata)); //發送十六進制數據  
  10. }  
  11. else  
  12. m_ctrlComm.SetOutput(COleVariant(m_strTXData));//發送ASCII字符數據  
  13.   
  14. }  

 

如今,你先將串口線接好並打開串口調試助手V2.1,選上以十六制顯示,設置好相應串口,而後運行咱們這個程序,在發送框中輸入00 01 02 03 A1 CC等十六進制字符,並選上以十六進制發送,單擊手動發送,在串口調試助手的接收框中應該能夠看到00 01 02 03 A1 CC了。

 

9.在接收框中以十六進制顯示

    這就容易多了:   在主對話框中加入一個複選接鈕,IDC_CHECK_HEXDISPLAY Caption: 十六進制顯示,再利用ClassWizard爲其添加控制變量:m_ctrlHexDiaplay。 而後修改CSCommTestDlg::OnComm()函數:

 

[cpp]  view plain  copy
 
  1. void CSCommTestDlg::OnComm()  
  2. {  
  3. // TODO: Add your control notification handler code here  
  4. VARIANT variant_inp;  
  5. COleSafeArray safearray_inp;  
  6. LONG len,k;  
  7. BYTE rxdata[2048]; //設置BYTE數組 An 8-bit integerthat is not signed.  
  8. CString strtemp;  
  9. if(m_ctrlComm.GetCommEvent()==2) //事件值爲2表示接收緩衝區內有字符  
  10. {  
  11. variant_inp=m_ctrlComm.GetInput(); //讀緩衝區  
  12. safearray_inp=variant_inp; //VARIANT型變量轉換爲ColeSafeArray型變量  
  13. len=safearray_inp.GetOneDimSize(); //獲得有效數據長度  
  14. for(k=0;k<len;k++)  
  15. safearray_inp.GetElement(&k,rxdata+k);//轉換爲BYTE型數組  
  16. for(k=0;k<len;k++) //將數組轉換爲Cstring型變量  
  17. {  
  18. BYTE bt=*(char*)(rxdata+k); //字符型  
  19. if(m_ctrlHexDisplay.GetCheck())  
  20. strtemp.Format("%02X ",bt); //將字符以十六進制方式送入臨時變量strtemp存放,注意這裏加入一個空隔  
  21. else  
  22. strtemp.Format("%c",bt); //將字符送入臨時變量strtemp存放  
  23.   
  24. m_strRXData+=strtemp; //加入接收編輯框對應字符串  
  25. }  
  26. }  
  27. UpdateData(FALSE); //更新編輯框內容  
  28. }  

 

測試:在串口調試助手發送框中輸入00 01 02 03 A1 CC等十六進制字符,並選上以十六進制發送,單擊手動發送,在本程序運行後選上以十六進制顯示,在串口調試助手中單擊手動發送或自動發送,則在本程序的接收框中應該能夠看到00 01 02 03 A1 CC了。

 

10.如何設置自動發送

     最簡單的設定自動發送週期是用SetTimer()函數,這在數據採集中頗有用,在控制中指令的傳送也可能用到定時發送。

    方法是:在ClassWizard中選上MessageMap卡,而後在Objects IDs選中CSCommTestDlg類,再在Messages框中選上WM_TIMER消息,單擊ADD_FUNCTION加入void CSCommTestDlg::OnTimer(UINT nIDEvent) 函數,這個函數是放入「時間到」後要處理的代碼:

 

[cpp]  view plain  copy
 
  1. void CSCommTestDlg::OnTimer(UINT nIDEvent)  
  2. {  
  3. // TODO: Add your message handler code here and/or call default  
  4. OnButtonManualsend();  
  5. CDialog::OnTimer(nIDEvent);  
  6. }  


 

再在在主對話框中加入一個複選接鈕,ID爲IDC_CHECK_AUTOSEND Caption: 自動發送(週期1秒),再利用ClassWizard爲其添加BN_CLICK消息處理函數void CSCommTestDlg::OnCheckAutosend():

 

[cpp]  view plain  copy
 
  1. void CSCommTestDlg::OnCheckAutosend()  
  2. {  
  3. // TODO: Add your control notification handler code here  
  4. m_bAutoSend=!m_bAutoSend;  
  5. if(m_bAutoSend)  
  6. {  
  7. SetTimer(1,1000,NULL);//時間爲1000毫秒  
  8. }  
  9. else  
  10. {  
  11. KillTimer(1); //取消定時  
  12. }  
  13. }  

 

其中:m_bAutoSend爲BOOL型變量,在CLASSVIEW中爲CSCommTestDlg類加入,並在構造函數中初始化:

      m_bAutoSen=FALSE;
如今能夠運行程序測試了。

 

11.什麼是VARIANT數據類型?如何使用VARIANT數據類型?

     不知如何使用VARIANT數據類型, 有很多朋友對VARIANT這個新的數據類型大感頭疼。SetOutput()函數中 須要的VARIANT參數還可使用COleVariant類的構造函數簡單生成,如今GetInput()函數的返回值也成了VARIANT類型,那麼如何從返回的值中提取有用的內容。 VARIANT及由之而派生出的COleVariant類主要用於在OLE自動化中傳遞數據。實際上VARIANT也只不過是一個新定義的結構罷了,它的主要成員包括一個聯合體及一個變量。該聯合體由各類類型的數據成員構成, 而該變量則用來指明聯合體中目前起做用的數據類型。咱們所關心的接收到的數據就存儲在該聯合體的某個數據成員中。 該聯合體中包含的數據類型不少,從一些簡單的變量到很是複雜的數組和指針。因爲經過串口接收到的內容經常是一個字節串,咱們將使用其中的某個數組或指針來訪問接收到的數據。這裏推薦給你們的是指向一個SAFEARRAY(COleSafeArray)類型變量。新的數據類型SAFEARRAY正如其名字同樣,是一個「安全數組」,它能根據系統環境自動調整其16位或32 位的定義,而且不會被OLE改變(某些類型如BSTR在16位或32位應用程序間傳遞時會被OLE翻譯從而破壞其中的二進制數據)。你們無須瞭解SAFEARRAY的具體定義,只要知道它是另一個結構,其中包含一個 (void *)類型的指針pvData,其指向的內存就是存放有用數據的地方。 簡而言之,從GetInput()函數返回的VARIANT類型變量中,找出parray 指針,再從該指針指向的SAFEARRAY變量中找出pvData指針,就能夠向訪問數組同樣取得所接收到的數據了。具體應用請參見void CSCommTestDlg::OnComm()函數。

    大概我如今也說不清這個問題,我本身從第一次接觸這個東西,到如今仍是給別人講不清。

 

另:二進制收發設置請參考MSComm控件說明

相關文章
相關標籤/搜索