|
|
|
1 引言 在當今的工業控製領域,串口通信是計算機與其他設備進行數據通信時經常使用的方法,具有實現簡單、使用靈活、數據傳輸可靠等幾個優點,特別是在實時監控係統中得到廣泛應用,在我們使用的計算機上使用的串口一般是RS232,使用RS232接(jie)口(kou)隻(zhi)能(neng)進(jin)行(xing)一(yi)對(dui)一(yi)的(de)通(tong)信(xin),然(ran)而(er)在(zai)工(gong)業(ye)控(kong)製(zhi)領(ling)域(yu)往(wang)往(wang)是(shi)一(yi)台(tai)工(gong)控(kong)機(ji)和(he)多(duo)台(tai)智(zhi)能(neng)設(she)備(bei)進(jin)行(xing)通(tong)信(xin),並(bing)且(qie)要(yao)求(qiu)傳(chuan)輸(shu)距(ju)離(li)遠(yuan),因(yin)為(wei)這(zhe)些(xie)需(xu)求(qiu),在(zai)工(gong)控(kong)領(ling)域(yu)一(yi)般(ban)使(shi)用(yong)RS485。 在Win32下,可以使用兩種編程方式實現串口通信,其一是使用MScomm控件,這種方法程序簡單,但欠靈活。其二是調用Windows的API函數,這種方法可以清楚地掌握串口通信的機製,並且自由靈活。使用控件的方法在本質上也是使用API進行串口通信,控件隻不過是對API的一個封裝處理,本文隻介紹使用API進行串口通信編程的方法。 2 串口通信的一般步驟 2.1 打開串口 在32位Windows中,串口和其他通信設備(如磁盤等)都(dou)被(bei)作(zuo)為(wei)文(wen)件(jian)進(jin)行(xing)處(chu)理(li),在(zai)使(shi)用(yong)前(qian)必(bi)須(xu)先(xian)將(jiang)其(qi)打(da)開(kai),為(wei)保(bao)證(zheng)串(chuan)口(kou)通(tong)信(xin)數(shu)據(ju)傳(chuan)輸(shu)的(de)可(ke)靠(kao)性(xing),串(chuan)口(kou)一(yi)般(ban)以(yi)非(fei)共(gong)享(xiang)模(mo)式(shi)打(da)開(kai),也(ye)就(jiu)是(shi)在(zai)被(bei)串(chuan)口(kou)打(da)開(kai)後(hou),其(qi)他(ta)程(cheng)序(xu)不(bu)能(neng)在(zai)去(qu)打(da)開(kai)此(ci)設(she)備(bei)。 2.2 配置串口 在使用串口進行數據通信前必須對其進行正確的配置,串口需要配置的主要參數有波特率、數據位、停止位、奇偶校驗、收(shou)發(fa)數(shu)據(ju)緩(huan)衝(chong)區(qu)大(da)小(xiao)。除(chu)此(ci)之(zhi)外(wai)還(hai)要(yao)對(dui)串(chuan)口(kou)進(jin)行(xing)超(chao)時(shi)設(she)置(zhi),以(yi)防(fang)止(zhi)在(zai)串(chuan)口(kou)通(tong)信(xin)時(shi)數(shu)據(ju)傳(chuan)輸(shu)突(tu)然(ran)中(zhong)斷(duan)而(er)導(dao)致(zhi)讀(du)寫(xie)操(cao)作(zuo)進(jin)入(ru)無(wu)限(xian)期(qi)等(deng)待(dai)的(de)狀(zhuang)態(tai),設(she)置(zhi)了(le)超(chao)時(shi),如(ru)果(guo)在(zai)指(zhi)定(ding)時(shi)間(jian)內(nei)沒(mei)有(you)完(wan)成(cheng)所(suo)進(jin)行(xing)的(de)操(cao)作(zuo),則(ze)此(ci)操(cao)作(zuo)被(bei)自(zi)動(dong)放(fang)棄(qi)。 2.3 讀寫串口 在串口被打開並設置好後,就可以使用串口進行讀寫數據了,讀寫數據可以采用同步、異步及事件驅動等多種方式。 2.4 關閉串口 在使用完串口後應該將其關閉,如果沒有關閉,該串口會處於打開狀態,其他的應用程序便無法打開使用該串口。 3 利用API函數實現串口通信 3.1 打開串口 Win32係統把文件的概念進行了擴展。無論是文件、通信設備、命名管道、郵件槽、磁盤、還是控製台,都是用API函數CreateFile來打開或創建的。該函數的原型為: HANDLE CreateFile(LPCTSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDistribution, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile); 各個參數說明如下: lpFileName:將要打開的串口邏輯名,如“COM1”; dwDesiredAccess:指定串口訪問的類型,可以是讀取、寫入或二者並列; dwShareMode:指定共享屬性,由於串口不能共享,該參數必須置為0; lpSecurityAttributes:引用安全性屬性結構,缺省值為NULL; dwCreationDistribution:創建標誌,對串口操作該參數必須置為OPEN_EXISTING; dwFlagsAndAttributes:屬性描述,用於指定該串口是否進行異步操作,該值為FILE_FLAG_OVERLAPPED,表示使用異步的I/O;該值為0,表示同步I/O操作; hTemplateFile:對串口而言該參數必須置為NULL; 3.2 配置串口 在打開通訊設備句柄後,常常需要對串口進行一些初始化配置工作。這需要通過一個DCB結構來進行。DCB結構包含了諸如波特率、數據位數、奇偶校驗和停止位數等信息。在查詢或配置串口的屬性時,都要用DCB結構來作為緩衝區。在打開串口後,可以調用GetCommState函數來獲取串口的默認配置,該函數獲取一個DCB結構體,隻要在該結構內對應該先修改DCB結構,然後再調用SetCommState函數以修改後的DCB結構設置串口。DCB主要有以下幾個重要的成員: BYTE ByteSize; // 通信字節位數 BYTE Parity; //指定奇偶校驗方法。此成員可以有下列值: //EVENPARITY 偶校驗 NOPARITY 無校驗 //MARKPARITY 標記校驗 ODDPARITY 奇校驗 BYTE StopBits; //指定停止位的位數。此成員可以有下列值: //ONESTOPBIT 1位停止位 //TWOSTOPBITS 2位停止位 //ONE5STOPBITS 1.5位停止位 除了使用BCD設she置zhi串chuan口kou的de一yi些xie基ji本ben參can數shu外wai,一yi般ban還hai需xu要yao設she置zhi串chuan口kou收shou發fa數shu據ju緩huan衝chong區qu的de大da小xiao和he超chao時shi,超chao時shi的de作zuo用yong是shi在zai指zhi定ding的de時shi間jian內nei沒mei有you讀du入ru或huo發fa送song指zhi定ding數shu量liang的de字zi符fu,讀du寫xie操cao作zuo仍reng然ran會hui結jie束shu。Windows用I/O緩衝區來暫存串口輸入和輸出的數據,如果通信的速率較高,則應該設置較大的緩衝區。我們可以使用API函數SetupComm設置串口的輸入和輸出緩衝區的大小,其原型如下: BOOL SetupComm( HANDLE hFile, // 串口句柄 DWORD dwInQueue, // 輸入緩衝區的大小(字節數) DWORD dwOutQueue ); // 輸出緩衝區的大小(字節數) 關於讀寫串口的超時設置,windows給我們提供一個專門的結構體COMMTIMEOUTS,其定義如下: typedef struct _COMMTIMEOUTS { DWORD ReadIntervalTimeout; //讀間隔超時 DWORD ReadTotalTimeoutMultiplier; //讀時間係數 DWORD ReadTotalTimeoutConstant; //讀時間常量 DWORD WriteTotalTimeoutMultiplier; //寫時間係數 DWORD WriteTotalTimeoutConstant; //寫時間常量 } COMMTIMEOUTS,*LPCOMMTIMEOUTS; COMMTIMEOUTS結構的成員都以毫秒為單位。總超時的計算公式是: 總超時=時間係數×要求讀/寫的字符數+時間常量 例如,要讀入10個字符,那麼讀操作的總超時的計算公式為: 讀總超時=ReadTotalTimeoutMultiplier×10+ReadTotalTimeoutConstant 通過該結構體windowsAPI為我們提供兩個函數:GetCommTimeouts和SetCommTimeouts,前者獲取當前的超時設置,後者使用修改後的COMMTIMEOUTS設置超時,與設置串口闡述類似。 在讀寫串口之前,還要用PurgeComm(…)函數清空緩衝區,該函數原型: BOOL PurgeComm( HANDLE hFile, //串口句柄 DWORD dwFlags ); //需要完成的操作 參數dwFlags指定要完成的操作,可以是下列值的組合: PURGE_TXABORT 中斷所有寫操作並立即返回,即使寫操作還沒有完成。 PURGE_RXABORT 中斷所有讀操作並立即返回,即使讀操作還沒有完成。 PURGE_TXCLEAR 清除輸出緩衝區 PURGE_RXCLEAR 清除輸入緩衝區 3.3 讀寫串口 讀寫串口使用ReadFile和WriteFile兩個函數,其原型如下: BOOL ReadFile( HANDLE hFile, //串口的句柄 LPVOID lpBuffer, //保存讀入數據的指針 DWORD nNumberOfBytesToRead, //要讀入的數據的字節數 LPDWORD lpNumberOfBytesRead, //實際讀入的字節數 LPOVERLAPPED lpOverlapped ); //OVERLAPPED,同步為NULL BOOL WriteFile( HANDLE hFile, //串口的句柄 LPCVOID lpBuffer, //要寫入數據的地址 DWORD nNumberOfBytesToWrite, //要寫入數據的字節數 LPDWORD lpNumberOfBytesWritten, //實際寫入的字節數 LPOVERLAPPED lpOverlapped); //OVERLAPPED,同步為NULL 在進行同步操作時,讀寫函數要等到執行完才返回,而在異步操作時函數立即返回,但不保證讀寫操作完成,這時候就需要使用OVERLAPPED結構進行異步控製,該結構體有一個重要的成員hEvent,該成員是windows事件對象的句柄在控製線程同步及異步操作時常用到,如果是異步操作,我們可以使用CreateEvent(…)創建事件對象並將返回值賦給hEvent,然後使用WaitForSingleObject或GetOverlappedResult等待讀寫操作完成,進而達到控製異步操作的目的。 3.4 關閉串口 在不使用串口的時候應該將其關閉,以釋放windows的資源供其他程序使用,關閉串口隻需調用CloseHandle(hComm/*串口句柄*/)即可。 4 串行通信在世紀星組態軟件中的應用 作為通用的組態軟件,世紀星要與其他PLC、智能儀表等設備進行通信,串行通信是主要的方式之一,基於前麵所述使用API進行串行通信開發的優點,並考慮程序開發的便捷和可重用等,在世紀星中,我們將串行通信APIjinxingfengzhuang,yileidefangshiduichuankoujinxingcaozuo,qizhongdakaichuankoujipeizhichuankoucanshudecaozuowomentongguokeshihuachuangkoujinxingsheding,ranhouzaifengzhuangleizhongshixian,xiangguandecaozuochuliduxieshujuwaijibendouyishixian,yinweibutongdeshebeiyoubutongdexieyi,yinerduxiechuankoudecaozuozaiqudongchengxuzhongwancheng,zheyangwomendekaifarenyuanjiububiguanzhutaiduoqitadexiangguancaozuo,zhixugenjushijishebeizhongxieduxiechuankoudechengyuanhanshujike。 5 結論 Windows是當前應用程序開發的主流平台,VC++6.0是該平台強大的開發工具,使用windowsAPI開發串口通信的程序可使我們更加清晰的了解串口通信的機製,並且開發人員可以根據需要使用API進行靈活的程序設計,在SCADA中串行通信是必不可少的技術,所以掌握串行通信的開發方法具有現實意義。
|
|
狀 態:
離線
公司簡介
產品目錄
|
|
|
公司名稱:
|
北京世紀長秋科技有限公司
|
| 聯 係 人: |
徐向農
|
| 電 話: |
010-84645656
|
| 傳 真: |
|
| 地 址: |
北京市朝陽區惠新東街8號設計大廈14層 |
| 郵 編: |
100029 |
| 主 頁: |
|
|
|
|
|