Win32SDK中(串行)通信资源概要(不断更新)
說在前面的話:
該"概要"是我在學習Windows上的串口通信資源的時候順便翻譯的, 可能存在相當多的翻譯得不正確的地方, 還有很多不妥的地方, 如果您覺得哪個地方出了問題, 請你聯系我(屏幕的右上角有QQ臨時會話), 我也作好修改工作, 以免讓后面的人被誤導了. 當然, 介紹Windows上用SDK編程的文章并不多------能找到的基本上介紹控件開發的, 真可惜我把VB忘了, MFC也不會, 更別提C4個加了------而我也幾乎完全只是按照MS的原文譯過來的, 并沒有抓重點講, 希望讀者不要指責, 不過后來我應該會不斷地對文章作一些勘誤工作. 以使文章盡量"生動".
通信資源
??? 通信資源是一種提供雙向的, 異步數據流的物理或邏輯設備. 串口, 并口, 傳真機, 調制解調器等都是通信資源的例子. 對于每一種通信資源, 都有一個由庫或驅動組成的服務供應者, 它使得應用程序可以訪問這些資源.
用這些方式寫的一個示例程序:串口調試助手
地址:http://www.9mcu.com/9mcubbs/forum.php?mod=viewthread&tid=1023821&extra=page%3D1
?
??? 1 關于通信資源 ??? 2 使用通信資源 ??? 3 通信資源參考 |
1. 關于通信資源
??? 文件I/O函數(CreateFile,CloseHandle,ReadFile,ReadFileEx,WriteFile,WriteFileEx)為打開和關閉一個通信資源句柄, 執行讀和寫的功能提供了基本的接口. 這些通信接口函數提供了訪問通信資源的方式. 下面的概要簡單地描述了文件I/O函數的通信函數的使用.
| ??? 1.1 通信資源句柄 ??? 1.2 通信資源設置的修改 ??? 1.3 通信資源的配置 ??? 1.4 調制解調器的配置 ??? 1.5 讀和寫操作 ??? 1.6 通信事件 ??? 1.7 擴展功能 |
1.1 通信資源句柄
??? 一個進程通過 CreateFile 函數打開一個通信資源的句柄. 比如說:指定COM1可以打開一個串口的句柄, LPT1可以打開一個并口的句柄. 如果指定的資源當前正被其它的進程所使用, CreateFile就會失敗. 當前進程的任何線程都可以使用由CreateFile函數返回的句柄來標識某種資源.
??? 當進程調用CreateFile打開一個俼資源時, 它應該指定下列的屬性:
??????? o 對指定的資源的讀寫操作類型
??????? o 句柄是否可被子進程繼承
??????? o 句柄是否可用戶重疊(異步)I/O操作(見 同步 部分)
??? 當進程調用CreateFile打開一個俼資源時, 它也必須為下列參數指定明確的值:
??????? o fdwShareMode參數必須設置為0, 即打開為獨占模式
??????? o fdwCreate參數必須指定OPEN_EXISTING標志位
??????? o hTemplate參數必須為NULL
??? 當使用CreateFile直接打開一個設備的句柄時, 應用程序必須用字符串"\\.\"來標識該設備. 比如:要打開驅動器A, 就要為 CreateFile的lpszName 參數指定 "\\.\a:" 調用進程可以使用這個句柄通過DeviceIoControl函數向設備發出控制碼.
1.2 通信資源設置的修改
??? 當用CreateFile打開一個串行通信資源的句柄時, 系統默認根據最后一次該資源被打開時的設置來初始化和配置該資源.? 保留先前的設置可以使得用戶在重新打開該資源時可通過一個 模式命令(mode command) 來獲得指定的設置. 由先前的打開操作繼承來的設置包括 設備控制塊(DCB,Device Control Block), I/O操作超時值. 如果該設置從未被打開過, 它被配置為系統默認配置.
??? 要取得當前串行通信資源的配置狀態, 進程可以調用GetCommState來獲得, 該函數會用當前的配置設置填充串口DCB結構. 要修改該配置, 進程可以指定一個DCB結構然后調用SetCommState函數.
??? DCB結構成員指定了一些配置設置, 比如波特率(baud rate),每字節的數據位, 每字節的停止位的長度. DCB的其它成員指定特殊的字符,開啟奇偶校驗,流量控制等. 當進程只是需要修改設置的一小部分時, 它應該先調用GetCommState用當前配置來填充DCB結構, 然后可以調節DCB結構中重要的成員值, 最后再用修改后的DCB結構通過調用SetCommState來重新配置該設備. 該過程能夠確保DCB結構中沒有被修改的成員包含正確合適的值. 比如, 一個常見的錯誤是用XonChar成員和XoffChar成員相等的DCB結構體去配置某個設備.
??? BuildCommDCB函數提供修改DCB結構的另一種方式. BuildCommDCB使用了包含模式命令指定的波特率,奇偶校驗方式,停止位長度,數據位長度等的字符串的命令行. 除設置合適的值來禁止XON/XOFF和硬件流量控制, DCB結構的其它成員不會被該函數修改. BuildCommDCB只會修改該結構體, 并不會去重新配置某個設備.
??? SetCommState函數會重新配置通信資源, 但它并不會影響到驅動的內部輸出/輸入緩沖. 緩沖區不會被清除, 掛起的讀寫操作也不會被意外地終止.
??? 進程通過調用SetupComm函數來重新初始化一個通信資源, 它將執行以下操作:
??????? o 終止掛起的讀寫操作, 不管它是否完成
??????? o 拋棄未讀取的字符, 并且釋放指定資源驅動內部分配的輸入/輸出緩沖區
??????? o 重新分配內部輸入/輸出緩沖區
??? 進程不需要請求調用SetupComm. 如果一定要這樣, 該資源的驅動會用第一次該通信資源被使用時的默認設置來初始化該設備.
1.3 通信資源的配置
??? COMMCONFIG結構定義了通信資源,串口等的配置. 該結構的格式與通信資源的類型有關(提供者子類). 開始的一些結構成員是所有通信資源共有的. 附加的成員為指定的提供者子類所定義. 特殊的服務提供者也可以擴展該結構.
??? 應用程序可以通過調用GetCommConfig/SetCommConfig來得到/設置這些配置. 當資源被打開時, 通信資源被提供者子類的默認配置初始化. 要得到/設置提供者子類的默認配置, 調用GetDefaultCommConfig/SetDefaultCommConfig即可.
??? 要提示用戶配置配置信息, 調用CommConfigDialog函數. 該函數顯示一個由服務提供者提供的對話框并基于用戶的輸入來填充COMMCONFIG結構.
1.4 調制解調器的配置
??? (略)
1.5 讀和寫操作
??? Windows支持對串行通信資源的同步和異步(重疊)I/O文件操作. 重疊操作允許該文件操作在后臺工作的同時調用線程可執行其它的任務. 線程調用ReadFile/ReadFileEx函數從通信資源中讀取, 使用WriteFile/WriteFileEx函數寫通信資源. ReadFile/WriteFile可以執行同步的異步操作, ReadFileEx和WriteFileEx僅可以執行異步操作.
??? 這些讀寫函數的表現形式受該函數是否被作為重疊文件操作,該句柄的超時設置, 該句柄的流量控制參數的影響.
??? 線程也可以通過TransmitCommChar函數來寫通信資源, 該函數會寫一個指定的字符在輸出緩沖區中任何掛起數據之前. 該函數在傳送一個高優先級信號到接收系統時很有用. 該傳輸操作也同時受到流量控制, 寫超時, 同步操作的影響.
??? 線程可以調用PurgeComm函數拋棄設備輸入/輸出緩沖區的所有字符. PurgeComm也可以終止掛起的讀寫操作, 而不管它是否完成. 如果線程使用PurgeComm去清除輸出緩沖區, 被刪除的字符不會被傳送. 為清空輸出緩沖區并保證內容被傳送, 線程可以調用FlushFileBuffers函數(同步操作). 注意, 雖然FlushFileBuffers受流量控制, 但不受寫超時影響, 并且在所有掛起的寫操作完成之前不會返回.
1.6 通信事件
??? 進程可以監視一系列發生于通信資源中的事件. 比如, 應用程序可以使用事件監視來決定什么時候CTS(clear to send)和DSR(data set ready)信號改變狀態.
??? 進程可以通過調用SetCommMask函數創建事件的掩碼來監視給定的通信資源. 要決定當前的通信資源的掩碼, 可以調用GetCommMask, 下面的事件可供監視:
| EV_BREAK | 輸入被中斷 |
| EV_CTS | CTS(clear to send)信號改變狀態 |
| EV_DSR | DSR(data set ready)信號改變狀態 |
| EV_ERR | 行狀態錯誤, 包括:CE_FRAME,CE_OVERRUN,CE_RXPARTY |
| EV_RING | 檢測到響鈴指示 |
| EV_RLSD | RLSD(Receive-line-signal-detect)信號改變狀態 |
| EV_RXCHAR | 接收到一個字符并被放置于輸入緩沖區 |
| EV_RXFLAG | 收到事件字符并被放置于輸入緩沖區.事件字符在設備的DCB結構中被指定,通過SetCommState函數用于串口 |
| EV_TXEMPTY | 輸出緩沖區的最后一個字符被發送 |
???
在指定一系列的事件后, 進程可以使用WaitCommEvent函數監視事件中事件之一發生. WaitCommEvent可用于同步或異步操作. 要了解同步的更多信息, 參閱同步部分.
??? 當事件掩碼中的事件之一發生后, 進程完成等待操作并設置一個事件掩碼變量來指示檢測到的已經發生的事件的類型. 如果 SetCommMask 在等待掛起的操作時被調用, WaitCommMask返回一個錯誤.
當檢測的事件信號(CTS,DSR等等)改變狀態時, WaitCommEvent 會報告這個改變, 但報告的不是當前的狀態, 只是一個改變而已. 要查詢當前CTS,DSR,RLSD,響鈴指示器的狀態, 進程可以調用GetCommModemStatus函數.
1.7 擴展功能
??? 一些通信函數可以被設備通過EscapeCommFunction調用. 該函數發送一個代碼指示設備去執行一個擴展函數. 比如: 應用程序可以用SETBREAK暫停字符發送, 并且可以用CLRBREAK繼續發送, 這些特殊的操作也可以調用SetCommBreak/ClearCommBreak函數來完成. EscapeCommFunction也可以用于實現手動調制解調器控制. 比如:CLRDTR和SETDTR代碼可以實現手動DTR流量控制. 注意, 當設備被配置為使能DTR握手, 或RTS行被使能時, 進程使用EscapeCommFunction操作DTR行會導致產生錯誤.
??? DeviceIoControl 函數使進程可以直接發送擴展功能代碼到指定的設備驅動, 以使設備產生指定的操作. DeviceIoControl使得設備關聯了標準串行通信功能不支持的能力. 它使得應用程序可以使用獨特的參數配置那個設備和任何設備相關的函數.
2.使用通信資源
??? 2.1 配置通信資源
??? 2.2 監視通信事件
2.1 配置通信資源
??? 參看下面的例子, 打開串口2, 填充DCB結構:
2.2 監視通信事件
??? 下面的例子采用異步方式打開串口, 創建事件監視掩碼CTS,DSR信號, 并且等待一個事件的發生. WaitCommEvent函數應該被執行為異步操作, 所以在此等待期間, 其它線程可以做其它的事情.
?
3.通信資源參考
??? 3.1 通信函數
??? 3.2 通信控制碼
??? 3.3 通信結構體
3.1 通信函數
3.1.1 BuildCommDCB
| 描述 | 用設備控制字符串中的值填充指定的DCB結構. 設備控制字符串使用 調制命令 | ||
| 語法 | BOOL WINAPI BuildCommDCB( ??? __in LPCTSTR lpDef, ??? __out LPDCB lpDCB ); | ||
| 參數 | lpDef | 設備控制信息. 該函數提取該字符串, 解析它, 并且設置lpDCB指向的結構中指定的成員. 該字符串必須有與模式命令同樣形式的命令行參數: ??? COMx[:][baud=b][parity=p][data=d][stop=s][to={on|off}][xon={on|off}][odsr={on|off}][octs={on|off}][dtr={on|off|hs}][rts={on|off|hs|tg}][idsr={on|off}] ??? 設備名可選, 如果要使用, 必須指定有效的設備. ??? 比如, 設置波特率為1200,無奇偶校驗,8位數據位,1停止位 ??? baud=1200 parity=N data=8 stop=1 | |
| lpDCB | 獲取該信息的DCB結構的指針. | ||
| 返回值 | 成功返回非0 失敗返回0, 調用GetLastError()取得更多信息 | ||
| 說明 | BuildCommDCB函數僅改變lpDef字符串中指定的成員, 但有以下例外: ??? o 如果波特率是110, 函數會設置停止位為2以保持與模式命令的兼容性 ??? o BuildCommDCB默認會禁用XON/XOFF和硬件流量控制. 要使能硬件流量控制, 你必須手動設置DCB結構中合適的成員 BuildCommDCB 函數只是起填充作用, 要應用這些設置到串口, 需調用SetCommState函數. 有許多新的或舊的模式語法. BuildCommDCB函數支持這兩種形式. 然而, 你不能濫用這兩種形式. 模式語法的新形式讓你顯式的設置DCB結構中流量控制成員. 如果你使用較舊的模式語法, BuildCommState函數用以下方式設置流量控制成員的值: o 不以x或p結尾的字符串: ??? o fInX,fOutX,fOutXDsrFlow,和fOutCtsFlow均被設置為FALSE ??? o fDtrControl被設置為DTR_CONTROL_ENABLE ??? o fRtsControl被設置為RTS_CONTROL_ENABLE o 以x結尾的字符串: ??? o fInx,fOutX都被設置為 TRUE ??? o fOutXDsrFlow,fOutXCtsFlow都被設置為FALSE ??? o fDtrControl 被設置為DTR_CONTROL_ENABLE ??? o fRtsControl 被設置為RTS_CONTROL_ENABEL o 以p結尾的字符串: ??? o fInX和fOutX都被設置的FALSE ??? o fOutXDsrFlow和fOutXCtsFlow都被設置為TRUE ??? o fDtrControl被設置為DTR_CONTROL_HANDSHAKE ??? o fRtsControl被設置為RTS_CONTROL_HANDSHAKE | ||
| 引用 | winbase.h(windows.h),kernel32.lib | ||
?
3.1.2 BuildCommDCBAndTimeouts
| 描述 | 翻譯一個設備定義的字符串為合適的設備控制塊代碼, 并且把她們放到設備控制塊中. 該函數也可以用于設置超時值, 包含沒有超時值的設備. | |
| 語法 | BOOL WINAPI BuildCommDCBAndTimeouts( ? __in?? LPCTSTR lpDef, ? __out? LPDCB lpDCB, ? __out? LPCOMMTIMEOUTS lpCommTimeouts ); | |
| 參數 | lpDef | 設備控制信息. 該函數提取該字符串, 解析它, 并且設置lpDCB指向的結構中指定的成員. 該字符串必須有與模式命令同樣形式的命令行參數: ??? COMx[:][baud=b][parity=p][data=d][stop=s][to={on|off}][xon={on|off}][odsr={on|off}][octs={on|off}][dtr={on|off|hs}][rts={on|off|hs|tg}][idsr={on|off}] ??? 設備名可選, 如果要使用, 必須指定有效的設備. ??? 比如, 設置波特率為1200,無奇偶校驗,8位數據位,1停止位 ??? baud=1200 parity=N data=8 stop=1 |
| lpDCB | 獲取該信息的DCB結構的指針 | |
| lpCommTimeouts | 接收超時值的COMMTIMEOUTS結構體指針 | |
| 返回值 | 成功:非0 失敗:0, 調用GetLastError()取得詳細信息 | |
| 說明 | BuildCommDCBAndTimeouts函數會通過判斷lpDef字符串中是否有"to={on|off}"來修改結構體的超時設置: | |
3.1.3 ClearCommBreak
| 描述 | 還原指定通信設備的字符傳送狀態,? 并設置傳輸結的狀態為非中斷狀態 | |
| 語法 | BOOL WINAPI ClearCommBreak( ? __in? HANDLE hFile ); | |
| 參數 | hFile | 由CreateFile函數返回的正確的通信設備的句柄 |
| 返回值 | 成功, 返回非零 失敗, 返回零 調用GetLastError以獲得更多錯誤相關的信息 | |
| 說明 | 通信資源的中斷狀態是由SetCommBreak 或 EscapeCommFunction 設定的 如果不調用ClearCommBreak清除中斷標志, 字符傳送將被掛起 | |
?
?
3.1.4 ClearCommError
| 描述 | 取得通信錯誤相關的信息, 并且報告通信設備當前的狀態 該函數調用于當通信設備產生錯誤的時候, 并且它會清除通信設備的錯誤標志以使用其它的I/O操作 | ||||||||||
| 語法 | BOOL WINAPI ClearCommError( ? __in?????? HANDLE hFile, ? __out_opt? LPDWORD lpErrors, ? __out_opt? LPCOMSTAT lpStat ); | ||||||||||
| 參數 | hFile | 由CreateFile函數返回的正確的通信設備的句柄 | |||||||||
| lpErrors | 一個用來接收錯誤標志類型的變量的指針, 該錯誤標志可以是以下一個或多個:
以下值不受支持: CE_DNS CE_IOE CE_MODE CE_OOP CE_PTO CE_TXFULL | ||||||||||
| lpStat | 指向COMSTAT結構體的指針, 容納設備的返回信息, 如果為NULL,? 則沒有信息被返回 | ||||||||||
| 返回值 | 成功:返回非零 失敗:返回零 調用GetLastError以獲得更多信息 | ||||||||||
| 說明 | 如果一個通信端口的DCB結構體中的fAbortOnError被設置為TRUE, 當通信設備發生錯誤時, 所有的通信軟件將會終止所有的讀寫操作. 除非軟件調用ClearCommError, 否則所有的讀寫操作將被拒絕. | ||||||||||
?
?
?
?
?
?
?
3.1.5 CommConfigDialog
| 描述 | 顯示一個由驅動程序提供的串口配置對話框 | |
| 語法 | BOOL WINAPI CommConfigDialog( ? __in???? LPCTSTR lpszName, ? __in???? HWND hWnd, ? __inout? LPCOMMCONFIG lpCC ); | |
| 參數 | lpszName | 對話框顯示的配置設備的名字, 如:COM-COM9代表串口設備, LPT1-LPT9代表并口設備 |
| hwnd | 該對話框所屬的父窗口(擁有者), 可以是任意有效的窗口句柄, 也可以是NULL, 如果沒有擁有都的話. | |
| lpCC | 指向COMMCONFIG結構體的指針, 該結構體初始化配置對話框, 并在調用后被配置對話框改變 | |
| 返回值 | 如果成功:返回非零 如果失敗:返回為零 調用GetLastError()獲得更多信息 | |
| 說明 | CommConfigDialog需要通信硬件提供者的動態鏈接庫的支持 | |
3.1.6 EscapeCommFunction
| 描述 | 指導通信設備執行某項擴展功能 | ||||||||||||||||
| 語法 | BOOL WINAPI EscapeCommFunction( ? __in? HANDLE hFile, ? __in? DWORD dwFunc ); | ||||||||||||||||
| 參數 | hFile | 由CreateFile返回的通信設備的句柄 | |||||||||||||||
| dwFunc | 要執行的擴展功能, 可以是以下一個值:
| ||||||||||||||||
| 返回值 | 如果成功:返回非零 如果失敗:返回為零 調用GetLastError()獲得更多信息 | ||||||||||||||||
---pre---
總結
以上是生活随笔為你收集整理的Win32SDK中(串行)通信资源概要(不断更新)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: FireFox and IE CSS兼容
- 下一篇: 使用Dnsmasq加速苹果App Sto