串口是常用的計算機與外部串行設備之間的數據傳輸通道,由於串行通信方便易行,所以應用廣泛。現在國際上不斷有串口新技術及新規格推出,結合社會各方面需要,串口通信發展的空間龐大。串口通訊技術因其自身的優勢和特性,及計算機技術的廣泛應用深入到生活和生產的各個領域,世界上數以億計的通訊設備都以串口通訊的方式。在進行着數據的傳輸。在一個應用系統中,同時使用Windows和Linux操作系統,合理地分配資源,各取所長,是實現系統高性能的有效途徑。為了使兩個不同操作系統能協同工作,實現資源和數據共享,需要在兩者問進行通信。本課題分別研究Linux操作系統與Window操作系統平台下串口通信程序設計。串口通信程序設計的主要模塊分別采用Visual C++6.0編程環境與Unux進行開發。本文同時給出了兩種編程環境中串口通信程序設計相同點與相異點,以及它們的比較。
1、開發環境
1.1硬件環境
能運行Windows 9X/2000/XP和Linux系統的PC機,配有兩個串行口或者是兩台配有串行口的PC機,RS232串口連接線。
1.2軟件環境
Visual C++6.0,GCC編程器,Windows9X/2000/XP操作系統和Liunx操作系統。
1.3設計原理圖
PCI運行Windows系統,PCII運行Linux系統。他們通過RS232串行線連接實現跨平台間的串口通信。
2 、Windows平台下串口通信程序設計
2·1 打開串口
嵌入式軟件開發,系統集成。用CreateFile函數來打開串El句柄,首先看到,該類中的串口句柄為HANDLE in—hComm;該句柄在應用CreateFile()函數創建后,就得到了指定了的串口句柄,其后,幾乎所有的函數要對串口進行操作時,必須通過ITI—hComm進行。因為串口句柄在打開時,設置了異步(重疊)I/O操作方式,岡此,必須對串口的超時做出說明,並在對超時變量進行設置。
2.2設置串口
在打開通訊設備句柄后,常常需要對串口進行一些初始化配置工作。這需要通過一個DCB結構來進行。DCB結構包含了諸如波特率、數據位數、奇偶校驗和停止位數等信息。在查詢或配置串口的屬性時,都要用DCB結構來作為緩沖區。一般用CreateFile打開串口后,可以調用GetCommState函數來獲取串口的初始配置。要修改串口的配置,應該先修改DCB結構,然后再調用SetCommState函數設置串口。
2.3建立線程
在主線程中寫數據,因為寫是可以控制的,而讀的時候不知道數據什么時候會到,所以要建立一個線程專門用來讀線程。在這個線程中,循環地用ReadFile函數讀串口,同時用WaitCommEvent函數檢測線路狀態。建立讀線程需要用到的函數較多:ReadFile,如果要檢測通信狀態,如CTS信號,Ringln等等,則用SetCommMask,WaitCommEvent,ClearCommError。在SerialPor類中,監測線程函數為CommThread函數。在SerialPort::CommThread()函數中:首先利用PurgeComm函數清空緩沖區,調用通信事件監測函數。在監測事件時,如果異步操作不能立即完成,則該函數返回FALSE(0),並GetLastError函數返回ERROR—IO—PENDING,表明該操作在后台執行。發生這種情況時,系統在WaitCommEvent函數返回之前將OVERLAPPED結構中的成員hEvent參數值設置為無信號狀態,之后等到特定通信事件或發生錯誤時,系統再將其設置為有信號狀態。所以只要有字符到達,就會產生事件。當監測到是讀事件的時候,就調用ReceiveChar函數去接收數據;當監測到是寫事件的時候,就調用WriteChar函數就發送數據。調用EnterCriticalSection函數來獲得串口的Critical Section,保證本進程中沒有其他函數或線程使用本串口資源。用ReadFile函數讀出緩沖區中的字節數,ReadFile(HANDLE nl—hcom,LPVOID RXBuff,DWORD dwlenth.LPDWORD&BytesRead,LPOVERLAPPED
mov);參數RXBuff指向接收緩沖區,dwlenth指明要從串口讀取的字節數,在此設置為1,BytesRead指明實際從串口設備中讀出的字節數,ITI—OV指向異步I/0結構。
2.4讀寫串口
使用ReadFile和WriteFile讀寫串口,在用ReadFile和WriteFile讀寫串口時,既可以同步執行,也可以重疊執行。在同步執行時,函數直到操作完成后才返回。這意味着同步執行時線程會被阻塞,從而導致效率下降。在重疊執行時,即使操作還未完成,這兩個函數也會立即返回,費時的I/0操作在后台進行。ReadFile函數只要在串口輸入緩沖區中讀人指定數量的字符,就算完成操作。而WriteFile函數不但要把指定數量的字符拷入到輸出緩沖區,而且要等這些字符從串行口送出去后才算完成操作。
如果操作成功,這兩個函數都返回TRUE。需要注意的是,當ReadFile和WriteFile返回FALSE時。不一定就是操作失敗,線程應該調用GetLastError函數分析返回的結果。例如,在重疊操作時如果操作還未完成函數就返回,那么函數就返回FALSE,而且GetLastError函數返回ERROR—IO—PENDING。
2.5關閉串口
調用ClosePort()函數來關閉串口。
3 、Linux平台下串口通信程序設計
3.1打開串口
在Linux下串口文件是位=J=/dev下,串口l為/dev/ttySO,串口2為/dev/ttySl,通過調用open()打開串口設備,返回一個整形文件句柄,以后所有的端口操作都針對這個句柄進行。如果open()出錯,則返回.1。open()函數帶有2個參數,其中參數1為要打開的設備文件名,參數2為打開方式。
3.2設置串口
進行串口操作之前,先要對串口通訊的波特率、校驗位、輸A/輸出方式等參數進行設置。Linux下的串口設置實際上是根據POSIX規范來設置的。POSIX規范是由IEEE提出的,用於定義一系列可移植的操作系統接口。串口設置的所有參數都包含在Termios結構中。Linux提供了兩個函數對termios進行操作,它們是tcgetattr()和tcsetattr()。tcgetattr()函數獲得指定串口的設置情況,tesetattr()函數用來設置串口的參數。
3.3讀寫串口
串口配置完成后,把串口當作文件來讀寫。調用write()函數讀寫端口,返回實際讀寫的字節數,如果有錯誤發生則返回一1。在主線程中寫數據,因為寫是可以控制的,write
(fd,&WriteData,sizeof(WriteData));而讀的時候不知道數據什么時候會到,所以要建立一個線程專門用來讀數據,在這個線程中,循環地用Read讀串口。在程序結束時關閉串口close(fd)。串口配置完成后,把串口當作文件來讀寫。調用read()函數讀寫端口,返回實際讀寫的字節數,如果有錯誤發生則返回一1。
3.4關閉串口
關閉串口就是關閉文件。使用close()關閉打開的串口,唯一的參數是打開串口的文件描述符。
4 、Windows和Linux串口通信的異同
4.1 Windows和Linux串口通信的相同點
Windows和Linux啟動時均自動檢測到標准的串口設備,而且對串口的打開、關閉、讀取和寫人所用的函數與操作文件的函數都是相同的。訪問串口的幾個簡單步驟是:
(1)打開串口設備,獲取Handle;
(2)設置串口通信參數(Windows是設置結構體DCB,Linux是設置結構體Termios),串口通信初始化設置,包括數據位、波特率、流量控制等參數;
(3)准備發送/接收數據;
(4)數據的發送/接收;
(5)關閉使用的串口設備。
此外,在Linux下有許多XWindows開發工具。
4.2 Windows和Linux串口通信的不同點
在Linux下實現串口通信編程和Windows環境不太一樣:Linux的串口結合了很多終端特性(比如在,I,IY模式下會自動處理某些字符終端控制符),與Windows的方式有很大的差異。添加擴展的多口串行通信卡時,Windows則是通過控制面板添加新硬件來完成的,Linux下是通過在系統啟動的配置腳本中配置/ete/serial.conf文件完成的。在打開串口時,Windows則需要提供串口的邏輯名,如COMl;Linux需要提供的是串口的路徑及名稱,且區分大小寫,女fl/dev/ttySO。Linux支持NONE,EVEN,ODD和SPACE四種校驗,而Windows除此之外還支持MASK。在Linux下,奇偶產生和檢測(PARENB)及輸入奇偶性檢驗(INPCK)是不同的兩件事:奇偶位的產生和檢測是對輸出字符產生奇偶位;輸入奇偶性檢驗則是對輸入字符驗證其奇偶性。Windows的停止位只有1位、1.5位和2位三種,Linux沒有1.5位。Linux支持輸入和輸出的波特率不同,可以分開設置。在通過串口傳輸文件的時候要注意,Linux中的文件行結束符是換行符(ASCIll3),而在Windows下是回車換行符(ASCIIIO/ASCIll3)。
參考鏈接:http://d.g.wanfangdata.com.cn/Periodical_kxjsygc200903041.aspx