《電子技術(shù)應(yīng)用》
您所在的位置:首頁(yè) > 模擬設(shè)計(jì) > 設(shè)計(jì)應(yīng)用 > 基于VC++6.0的串口通信開發(fā)方法
基于VC++6.0的串口通信開發(fā)方法
摘要: 在32位windows中,,串口和其他通信設(shè)備(如磁盤等)都被作為文件進(jìn)行處理,,在使用前必須先將其打開,,為保證串口通信數(shù)據(jù)傳輸?shù)目煽啃裕谝话阋苑枪蚕砟J酱蜷_,,也就是在被串口打開后,,其他程序不能在去打開此設(shè)備,。
Abstract:
Key words :

1.引言

  在當(dāng)今的工業(yè)控制領(lǐng)域,串口通信是計(jì)算機(jī)與其他設(shè)備進(jìn)行數(shù)據(jù)通信時(shí)經(jīng)常使用的方法,,具有實(shí)現(xiàn)簡(jiǎn)單,、使用靈活、數(shù)據(jù)傳輸可靠等幾個(gè)優(yōu)點(diǎn),,特別是在實(shí)時(shí)監(jiān)控系統(tǒng)中得到廣泛應(yīng)用,,在我們使用的計(jì)算機(jī)上使用的串口一般是rs232,使用rs232接口只能進(jìn)行一對(duì)一的通信,,然而在工業(yè)控制領(lǐng)域往往是一臺(tái)工控機(jī)和多臺(tái)智能設(shè)備進(jìn)行通信,,并且要求傳輸距離遠(yuǎn),因?yàn)檫@些需求,,在工控領(lǐng)域一般使用rs485,。

  在win32下,可以使用兩種編程方式實(shí)現(xiàn)串口通信,,其一是使用mscomm控件,,這種方法程序簡(jiǎn)單,但欠靈活,。其二是調(diào)用windows的api函數(shù),,這種方法可以清楚地掌握串口通信的機(jī)制,,并且自由靈活,。使用控件的方法在本質(zhì)上也是使用api進(jìn)行串口通信,控件只不過是對(duì)api的一個(gè)封裝處理,,本文只介紹使用api進(jìn)行串口通信編程的方法,。
 
2 串口通信的一般步驟

  2.1 打開串口
  在32位windows中,串口和其他通信設(shè)備(如磁盤等)都被作為文件進(jìn)行處理,,在使用前必須先將其打開,,為保證串口通信數(shù)據(jù)傳輸?shù)目煽啃裕谝话阋苑枪蚕砟J酱蜷_,,也就是在被串口打開后,,其他程序不能在去打開此設(shè)備。
  2.2 配置串口
  在使用串口進(jìn)行數(shù)據(jù)通信前必須對(duì)其進(jìn)行正確的配置,,串口需要配置的主要參數(shù)有波特率,、數(shù)據(jù)位、停止位,、奇偶校驗(yàn),、收發(fā)數(shù)據(jù)緩沖區(qū)大小。除此之外還要對(duì)串口進(jìn)行超時(shí)設(shè)置,,以防止在串口通信時(shí)數(shù)據(jù)傳輸突然中斷而導(dǎo)致讀寫操作進(jìn)入無限期等待的狀態(tài),,設(shè)置了超時(shí),,如果在指定時(shí)間內(nèi)沒有完成所進(jìn)行的操作,則此操作被自動(dòng)放棄,。
  2.3 讀寫串口
  在串口被打開并設(shè)置好后,,就可以使用串口進(jìn)行讀寫數(shù)據(jù)了,讀寫數(shù)據(jù)可以采用同步,、異步及事件驅(qū)動(dòng)等多種方式,。
  2.4 關(guān)閉串口
  在使用完串口后應(yīng)該將其關(guān)閉,如果沒有關(guān)閉,,該串口會(huì)處于打開狀態(tài),,其他的應(yīng)用程序便無法打開使用該串口。
 
3 利用api函數(shù)實(shí)現(xiàn)串口通信

  3.1 打開串口
  win32系統(tǒng)把文件的概念進(jìn)行了擴(kuò)展,。無論是文件,、通信設(shè)備、命名管道,、郵件槽,、磁盤、還是控制臺(tái),,都是用api函數(shù)createfile來打開或創(chuàng)建的,。該函數(shù)的原型為:
  handle createfile( lpctstr lpfilename,
                    dword dwdesiredaccess,
                    dword dwsharemode,
                    lpsecurity_attributes lpsecurityattributes,
                    dword dwcreationdistribution,
  dword dwflagsandattributes,
  handle htemplatefile);
  各個(gè)參數(shù)說明如下:
  lpfilename:將要打開的串口邏輯名,如“com1”,;
  dwdesiredaccess:指定串口訪問的類型,,可以是讀取、寫入或二者并列,;
  dwsharemode:指定共享屬性,,由于串口不能共享,該參數(shù)必須置為0,;
  lpsecurityattributes:引用安全性屬性結(jié)構(gòu),,缺省值為null;
  dwcreationdistribution:創(chuàng)建標(biāo)志,,對(duì)串口操作該參數(shù)必須置為open_existing,;
  dwflagsandattributes:屬性描述,用于指定該串口是否進(jìn)行異步操作,,該值為       file_flag_overlapped,,表示使用異步的i/o;該值為0,,表示同步i/o操作,;
  htemplatefile:對(duì)串口而言該參數(shù)必須置為null;

  3.2 配置串口
  在打開通訊設(shè)備句柄后,常常需要對(duì)串口進(jìn)行一些初始化配置工作,。這需要通過一個(gè)dcb結(jié)構(gòu)來進(jìn)行,。dcb結(jié)構(gòu)包含了諸如波特率、數(shù)據(jù)位數(shù),、奇偶校驗(yàn)和停止位數(shù)等信息,。在查詢或配置串口的屬性時(shí),都要用dcb結(jié)構(gòu)來作為緩沖區(qū),。在打開串口后,,可以調(diào)用getcommstate函數(shù)來獲取串口的默認(rèn)配置,該函數(shù)獲取一個(gè)dcb結(jié)構(gòu)體,,只要在該結(jié)構(gòu)內(nèi)對(duì)應(yīng)該先修改dcb結(jié)構(gòu),,然后再調(diào)用setcommstate函數(shù)以修改后的dcb結(jié)構(gòu)設(shè)置串口。dcb主要有以下幾個(gè)重要的成員:
  byte bytesize; // 通信字節(jié)位數(shù)byte parity;   //指定奇偶校驗(yàn)方法,。此成員可以有下列值://evenparity 偶校驗(yàn)     noparity 無校驗(yàn)//markparity 標(biāo)記校驗(yàn)   oddparity 奇校驗(yàn)byte stopbits; //指定停止位的位數(shù),。此成員可以有下列值://onestopbit   1位停止位   //twostopbits  2位停止位//one5stopbits 1.5位停止位
  除了使用bcd設(shè)置串口的一些基本參數(shù)外,一般還需要設(shè)置串口收發(fā)數(shù)據(jù)緩沖區(qū)的大小和超時(shí),,超時(shí)的作用是在指定的時(shí)間內(nèi)沒有讀入或發(fā)送指定數(shù)量的字符,,讀寫操作仍然會(huì)結(jié)束。windows用i/o緩沖區(qū)來暫存串口輸入和輸出的數(shù)據(jù),,如果通信的速率較高,,則應(yīng)該設(shè)置較大的緩沖區(qū)。我們可以使用api函數(shù)setupcomm設(shè)置串口的輸入和輸出緩沖區(qū)的大小,,其原型如下:bool setupcomm(    handle hfile,          // 串口句柄     dword dwinqueue,      // 輸入緩沖區(qū)的大?。ㄗ止?jié)數(shù))     dword dwoutqueue );   // 輸出緩沖區(qū)的大小(字節(jié)數(shù))
關(guān)于讀寫串口的超時(shí)設(shè)置,,windows給我們提供一個(gè)專門的結(jié)構(gòu)體commtimeouts,,其定義如下:typedef struct _commtimeouts {        dword readintervaltimeout;         //讀間隔超時(shí)    dword readtotaltimeoutmultiplier;  //讀時(shí)間系數(shù)    dword readtotaltimeoutconstant;    //讀時(shí)間常量    dword writetotaltimeoutmultiplier;  // 寫時(shí)間系數(shù)    dword writetotaltimeoutconstant;   //寫時(shí)間常量} commtimeouts,*lpcommtimeouts;

  commtimeouts結(jié)構(gòu)的成員都以毫秒為單位??偝瑫r(shí)的計(jì)算公式是:
  總超時(shí)=時(shí)間系數(shù)×要求讀/寫的字符數(shù)+時(shí)間常量
  例如,要讀入10個(gè)字符,,那么讀操作的總超時(shí)的計(jì)算公式為:
  讀總超時(shí)=readtotaltimeoutmultiplier×10+readtotaltimeoutconstant
  通過該結(jié)構(gòu)體windowsapi為我們提供兩個(gè)函數(shù):getcommtimeouts和setcommtimeouts,,前者獲取當(dāng)前的超時(shí)設(shè)置,后者使用修改后的commtimeouts設(shè)置超時(shí),,與設(shè)置串口闡述類似,。
  在讀寫串口之前,還要用purgecomm(…)函數(shù)清空緩沖區(qū),,該函數(shù)原型:
  bool purgecomm(
      handle hfile,     //串口句柄
      dword dwflags );   // 需要完成的操作
  參數(shù)dwflags指定要完成的操作,,可以是下列值的組合:
  purge_txabort  中斷所有寫操作并立即返回,即使寫操作還沒有完成。
  purge_rxabort  中斷所有讀操作并立即返回,,即使讀操作還沒有完成,。
  purge_txclear  清除輸出緩沖區(qū)
  purge_rxclear  清除輸入緩沖區(qū)

  3.3 讀寫串口
  讀寫串口使用readfile和writefile兩個(gè)函數(shù),其原型如下:bool readfile(    handle hfile,                     //串口的句柄    lpvoid lpbuffer,                  // 保存讀入數(shù)據(jù)的指針,,       dword nnumberofbytestoread,     // 要讀入的數(shù)據(jù)的字節(jié)數(shù)lpdword lpnumberofbytesread,   //  實(shí)際讀入的字節(jié)數(shù)    lpoverlapped lpoverlapped );    // overlapped,,同步為null    
  bool writefile(
    handle hfile,                    //串口的句柄
    lpcvoid lpbuffer,                 // 要寫入數(shù)據(jù)的地址
    dword nnumberofbytestowrite,     // 要寫入數(shù)據(jù)的字節(jié)數(shù)
    lpdword lpnumberofbyteswritten,  //實(shí)際寫入的字節(jié)數(shù)
    lpoverlapped lpoverlapped);      // overlapped,同步為null 在進(jìn)行同步操作時(shí),,讀寫函數(shù)  要等到執(zhí)行完才返回,,而在異步操作時(shí)函數(shù)立即返回,但不保證讀寫操作完成,,這時(shí)候就需要使用overlapped結(jié)構(gòu)進(jìn)行異步控制,,該結(jié)構(gòu)體有一個(gè)重要的成員hevent,該成員是windows事件對(duì)象的句柄在控制線程同步及異步操作時(shí)常用到,,如果是異步操作,,我們可以使用createevent(…)創(chuàng)建事件對(duì)象并將返回值賦給hevent,然后使用waitforsingleobject或getoverlappedresult等待讀寫操作完成,,進(jìn)而達(dá)到控制異步操作的目的,。

3.4   關(guān)閉串口

  在不使用串口的時(shí)候應(yīng)該將其關(guān)閉,以釋放windows的資源供其他程序使用,,關(guān)閉串口只需調(diào)用closehandle(hcomm/*串口句柄*/)即可,。

4.串行通信在世紀(jì)星組態(tài)軟件中的應(yīng)用

  作為通用的組態(tài)軟件,世紀(jì)星要與其他plc,、智能儀表等設(shè)備進(jìn)行通信,,串行通信是主要的方式之一,基于前面所述使用api進(jìn)行串行通信開發(fā)的優(yōu)點(diǎn),,并考慮程序開發(fā)的便捷和可重用等,,在世紀(jì)星中,我們將串行通信api進(jìn)行封裝,,以類的方式對(duì)串口進(jìn)行操作,,其中打開串口及配置串口參數(shù)的操作我們通過可視化窗口進(jìn)行設(shè)定,然后在封裝類中實(shí)現(xiàn),,相關(guān)的操作處理讀寫數(shù)據(jù)外基本都已實(shí)現(xiàn),,因?yàn)椴煌脑O(shè)備有不同的協(xié)議,因而讀寫串口的操作在驅(qū)動(dòng)程序中完成,,這樣我們的開發(fā)人員就不必關(guān)注太多其他的相關(guān)操作,,只需根據(jù)實(shí)際設(shè)備重寫讀寫串口的成員函數(shù)即可。

 5 結(jié)論

  windows是當(dāng)前應(yīng)用程序開發(fā)的主流平臺(tái),,vc++6.0是該平臺(tái)強(qiáng)大的開發(fā)工具,,使用windowsapi開發(fā)串口通信的程序可是使我們更加清晰的了解串口通信的機(jī)制,,并且開發(fā)人員可以根據(jù)需要使用api進(jìn)行靈活的程序設(shè)計(jì),在scada中串行通信是必不可少的技術(shù),,所以掌握串行通信的開發(fā)方法具有現(xiàn)實(shí)意義,。

此內(nèi)容為AET網(wǎng)站原創(chuàng),未經(jīng)授權(quán)禁止轉(zhuǎn)載,。