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