windows串口編程Win32,PComm串口開發


https://blog.csdn.net/u011430225/article/details/51496456

https://blog.csdn.net/eit520/article/details/7861029

關於串口編程的,有用API的,有用mscomm的。

其實用了Pcomm lite,很多問題都不會碰到,只需要打開串口,建個線程收數據,然后只需要關注自己要收發的數據就行了。

PComm Lite是家叫moxa的公司出的,做了幾十年工業串口卡、串口服務器之類設備了。提供的pcomm易用性、可靠性久經考驗。

下載地址:http://www.moxa.com/product/download_pcommlite_info.htm

 

目前最新版是Version 1.5 Released 2010-09-20 支持XP/win7, 32/64bit的庫都有,開發環境支持VC/VB/Delphi。

注意可以會搜到另外一個Version 2.6. Released Jul 8, 2008是WIN9x/NT4用的,不要看版本號高下錯了。

國外工業上還有很多老系統在用。

 

用起來很簡單,pcomm.h/pcomm.lib兩個文件復制到項目目錄並引用,pcomm.dll丟到windows\system32下。
整個庫包含50多個函數,最常用的也就10來個:
打開、關閉、設波特率的:sio_open ()、sio_close()、sio_baut()
發送數據的:sio_putch(),sio_write() 
接收數據的:sio_getch(),sio_read()
查詢輸入輸出緩沖區狀態的:sio_iqueue(), sio_oqueue()
有時可能要設讀寫超時:sio_SetReadTimeouts(), sio_SetWriteTimeouts()
這些函數見名知義,用法查一下PComm.chm就行了。
接收數據一般免不了要開線程的,在接收線程里sio_iqueue()看一下有沒有數據,有就處理,沒就Sleep()一會。接收數據時它至少會幫你緩沖幾十k,一般也不會丟數據。也可以用sio_term_irq()指定接收一定長數據數據就調用一個CALLBACK函數。

 

這些基本就齊活了。需要控制DTS/RTS、自動流控件有都有,甚至還有Xmoderm/Ymoderm/Zmoderm發送文件。如果要Modbus之類的協議就要自己寫了。

 

Windows下串口編程

 造冰箱的大熊貓@cnblogs 2019/1/27

 

將Windows下串口編程相關信息進行下簡單小結,以備后用。

 

1、打開串口

打開串口使用CreateFile()函數。以打開COM6為例:

HANDLE hComm;

hComm = CreateFile( TEXT("COM6"), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );

 其中:

- "COM6",待打開串口的串口名。

- GENERIC_READ | GENERIC_WRITE,串口讀寫權限。

- 0,固定值。

- NULL,指向SECURITY_ATTRIBUTES的指針。通常設置為NULL,此時CreateFile()函數返回的句柄不能被子進程繼承。

- OPEN_EXISTING,固定值。

- FILE_ATTRIBUTE_NORMAL,文件屬性。

- NULL,固定值。

- hComm,函數返回的句柄。如果打開串口成功,則在后續操作中使用該句柄訪問串口。如果打開串口失敗,函數返回句柄為INVALID_HANDLE_VALUE

 這里兩點需要說明:

 一是CreateFile()、CreateFileA()[1]和CreateFileW()[2]的區別。在大部分說明如何使用Win32 API打開串口的文檔中都介紹用CreateFile()函數打開串口,但某些文檔中卻使用CreateFileA()或CreateFileW()函數。實際上三個函數的功能是相同的,只是所采用的字符串編碼格式不同。CreateFileA()函數名中的A代表ANSI,而CreateFileW()中的W代表UNICODE。所謂ANSI編碼,是各國根據自己的語言定義的字符編碼格式,其中0~0x7F與ASCII字符相同,其余則與具體語言相關。因此,中文ANSI編碼(GB2312)和日文ANSI編碼無法互通。UNICODE則是將所有語言的編碼進行統一,用同一個編碼空間覆蓋所有語言文字。從下面的代碼中可以清楚地看出三個函數的關系。 在前面CreateFile()示例中,TEXT宏的用途就是根據當前操作系統的編碼格式對字符串"COM6"進行適當的格式轉換。

復制代碼
HANDLE CreateFileA(
    __in     LPCSTR lpFileName,
    __in     DWORD dwDesiredAccess,
    __in     DWORD dwShareMode,
    __in_opt LPSECURITY_ATTRIBUTES lpSecurityAttributes,
    __in     DWORD dwCreationDisposition,
    __in     DWORD dwFlagsAndAttributes,
    __in_opt HANDLE hTemplateFile
    );

HANDLE CreateFileW(
    __in     LPCWSTR lpFileName,
    __in     DWORD dwDesiredAccess,
    __in     DWORD dwShareMode,
    __in_opt LPSECURITY_ATTRIBUTES lpSecurityAttributes,
    __in     DWORD dwCreationDisposition,
    __in     DWORD dwFlagsAndAttributes,
    __in_opt HANDLE hTemplateFile
    );

#ifdef UNICODE
#define CreateFile CreateFileW
#else
#define CreateFile CreateFileA
#endif
復制代碼

二是對於串口號大於9的串口(例如COM12),在CreateFile()函數中串口名應寫作"\.\COM12"。

 

2、關閉串口

關閉串口則使用CloseHandle()函數。示例如下:

CloseHandle(hComm);

 

3、配置串口工作參數

以設置串口為波特率115200,數據位8bit,停止位1bit為例:

復制代碼
DCB dcb;

GetComm(hComm, &dcb);

dcb.BaudRate = CBR_115200;
dcb.ByteSize = 8;
dcb.StopBits = ONESTOPBIT;

SetCommState(hComm, &dcb); 
復制代碼

 

4、寫串口

以發送字符串"abcd"為例:

復制代碼
char  buf[] = "abcd";
DWORD buf_len = 4; // 待寫入串口的字節數
DWORD written_cnt; // 實際寫入串口的字節數

WreteFile( hComm, (void *)buf, buf_len, &written_cnt, NULL );
復制代碼

 

 5、讀串口

以讀取12個字符為例:

復制代碼
char  buf[128];
DWORD toread_cnt = 12; // 要從串口讀入的字節數
DWORD read_cnt;        // 實際從串口讀入的字節數

ReadFile( hComm, (void *)buf, toread_cnt, &read_cnt, NULL );
復制代碼

 

6、清除串口緩沖區

當串口接收到一個字節時,串口驅動程序將接收到的字節寫入內存的某個位置(輸入緩沖區)。當應用程序讀取串口時,操作系統按照“先進先出”的原則從輸入緩沖區取出數據交給應用程序。在某些應用場景下,應用程序需要舍棄輸入緩沖區內當前數據。這可通過PurgeComm()函數實現。

PurgeComm( hComm, PURGE_RXCLEAR );

 

7、其它

在Windows操作系統中,計算機上實際存在的或者虛擬的通信端口,包括串口和並口等,統稱為通信資源(Communication Resource)。本文總結的串口編程信息對通信資源也是適用的。

 本文只涉及簡單的串口讀寫操作,對於流量控制、異步讀寫、讀寫操作超時等復雜的串口控制,請參考相關函數微軟文檔中的詳細說明。

 

參考資料:

[1] 函數CreateFileA()說明 @ Microsoft

[2] 函數CreateFileW()說明 @ Microsoft

[3] 結構DCB說明 @ Microsoft

[4] 函數PurgeComm()說明 @ Microsoft

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM