C/C++ 打開串口和關閉串口


通常使用下列函數來通過Win系統來對外圍設備進行通信處理:

0. 前言

  做串口方面的程序,使用CreateFile打開串口通信端口。在對串口操作之前,需要首先打開串口。使用C++進行串口編程,如果采用VS開發,則可以直接借助於串口通信控件來操作,其次,直接調用Windows的底層API函數來控制串口通信。

  在Window 32bit 的操作系統上, 將串口(通信設備)作為文件來處理,所以串口的打開、關閉、讀寫所使用的API函數與文件操作一樣。所以打開串口使用CreateFile函數,讀寫串口使用ReadFile、WriteFile,函數。關閉串口使用CloseHandle函數。

 

1. 查看通信串口設備,可以在設備管理器中查看;

2.

 

 

-------------------------------

1. CreateFile

  這個函數的功能是創建或者打開一個文件或者I/O設備,通常使用的I/O形式有文件、文件流、目錄、物理磁盤、卷、終端流等。如執行成功,則返回文件句柄。 INVALID_HANDLE_VALUE 表示出錯,會設置 GetLastError 。
  函數的聲明定義:

  HANDLE WINAPI CreateFile(
  _In_      LPCTSTR lpFileName,              
  _In_      DWORD dwDesiredAccess,
  _In_      DWORD dwShareMode,
  _In_opt_  LPSECURITY_ATTRIBUTES lpSecurityAttributes,
  _In_      DWORD dwCreationDisposition,
  _In_      DWORD dwFlagsAndAttributes,
  _In_opt_  HANDLE hTemplateFile
);

參數列表:

 

 部分參數Tips:

  1. lpFileName:指定要打開的串口邏輯名,用字符串來表示。如COM1, COM2,分別表示串口1,和串口2.

  如果要確定工控機上有那些串口,可以使用設備管理器查看。如下圖:

  

  查看方式如下圖:我的電腦,右鍵, 開發“設備管理器”即可。

  

   2. dwDesiredAccess:端口屬性的訪問類型,

  3.  dwShareMode:指定端口的共享屬性。

  該參數是由那些應用程序共享的文件提供。對於串口來說,是不能共享的,因此,必須設置為0,這是通信設備與文件的特殊差別

  如果當前的應用程序調用CreateFile打開一個串口,另外一個程序如果已經打開了該串口,此時CreateFile會返回一個錯誤代碼。

  然而,同一個應用程序的多個線程是可以共享CreateFile返回的端口句柄。並且根據安全屬性設置,該句柄可以打開端口的應用程序的子程序來繼承。

  4. lpSecurityAttributes:安全屬性,一般該參數為NULL,即該端口被設置為缺省的安全屬性。缺省安全屬性下,端口的句柄是不能繼承的

  5. dwCreationDisposition:指定此端口正在被其他程序占用采取的動作,因為串口總是存在的,因此必須設置為OPEN_EXISTing, 該標志高速Windows不要創建新的端口。而是打開一個已經存在的端口

,  6. dwFlagsAndSttributes:描述了端口的各種屬性,對於文件來說有很多屬性,但是對於串口來說,唯一的意義是FILE_FLAG _OVERLAPPED 屬性,當設置該屬性時,端口IO可以在后台進行,稱為異步IO重疊結構。

  7. hTemplateFile: 指定模板的文件句柄,對於串口來說,此參數必須設置為0

  

關閉串口

  關閉串口,使用CloseHandle,函數聲明為:

  

  函數很簡單,參數是使用CreateFile打開的端口句柄。調用這個函數可以實現串口關閉。

   示例如下:

  

 

 

2. ReadFile

文件指針指向的位置(設備文件,通信)開始將數據讀出到一個文件中, 且支持同步和異步操作,如果文件打開方式沒有指明FILE_FLAG_OVERLAPPED的話,當程序調用成功時,它將實際讀出文件的字節數保存到lpNumberOfBytesRead指明的地址空間中。FILE_FLAG_OVERLAPPED 允許對文件進行重疊操作。
  函數聲明定義:

 BOOL WINAPI ReadFile(
  __in          HANDLE hFile,                   // 文件句柄
  __out         LPVOID lpBuffer,                // 接收數據用的 buffer
  __in          DWORD nNumberOfBytesToRead,     // 要讀取的字節數
  __out         LPDWORD lpNumberOfBytesRead,    // 實際讀取到的字節數
  __in          LPOVERLAPPED lpOverlapped       // OVERLAPPED 結構,一般設定為 NULL 
);

代碼示例:、

 1 BOOL Read(char *filePath)
 2 {
 3     HANDLE pFile;
 4     DWORD fileSize;
 5     char *buffer,*tmpBuf;
 6     DWORD dwBytesRead,dwBytesToRead,tmpLen;
 7 
 8     pFile = CreateFile(filePath,GENERIC_READ,          
 9         FILE_SHARE_READ,
10         NULL,               
11         OPEN_EXISTING,        //打開已存在的文件 
12         FILE_ATTRIBUTE_NORMAL, 
13         NULL);
14   // 創建設備文件,返回文件的位置
15     if ( pFile == INVALID_HANDLE_VALUE)
16     {
17         printf("open file error!\n");
18         CloseHandle(pFile);
19         return FALSE;
20     }
21   
22     fileSize = GetFileSize(pFile,NULL);          //得到文件的大小
23 
24     buffer = (char *) malloc(fileSize);
25     ZeroMemory(buffer,fileSize);
26     dwBytesToRead = fileSize;
27     dwBytesRead = 0;
28     tmpBuf = buffer;
29 
30     do{                                       //循環讀文件,確保讀出完整的文件    
31 
32         ReadFile(pFile,tmpBuf,dwBytesToRead,&dwBytesRead,NULL);
33 
34         if (dwBytesRead == 0)
35             break;
36 
37         dwBytesToRead -= dwBytesRead;
38         tmpBuf += dwBytesRead;
39 
40         } while (dwBytesToRead > 0);
41 
42         //  TODO 處理讀到的數據 buffer
43 
44     free(buffer);
45     CloseHandle(pFile);
46 
47     return TRUE;
48 }

3. WriteFile

  將數據寫入一個文件(設備文件,通信)。該函數比fwrite函數要靈活的多。也可將這個函數應用於對通信設備、管道、套接字以及郵槽的處理。返回時,TRUE(非零)表示成功,否則返回零。會設置GetLastError。
函數聲明定義:

BOOL WINAPI WriteFile(
  __in          HANDLE hFile,                   // 文件句柄
  __in          LPCVOID lpBuffer,               // 要寫入的數據
  __in          DWORD nNumberOfBytesToWrite,    // 要寫入的字節數
  __out         LPDWORD lpNumberOfBytesWritten, // 實際寫入的字節數
  __in          LPOVERLAPPED lpOverlapped       // OVERLAPPED 結構,一般設定為 NULL
);

示例代碼:

 1 BOOL Write(char *buffer, DWORD contentLen)
 2 {
 3     HANDLE pFile;
 4     char *tmpBuf;
 5     DWORD dwBytesWrite,dwBytesToWrite;
 6 
 7     pFile = CreateFile(filePath,GENERIC_WRITE,          
 8         0,
 9         NULL,               
10         CREATE_ALWAYS,        //總是創建文件
11         FILE_ATTRIBUTE_NORMAL, 
12         NULL);
13 
14     if ( pFile == INVALID_HANDLE_VALUE)
15     {
16         printf("create file error!\n");
17         CloseHandle(pFile);
18         return FALSE;
19     }
20 
21     dwBytesToWrite = contentLen;
22     dwBytesWrite = 0;
23 
24     tmpBuf = buffer;
25 
26     do{                                       //循環寫文件,確保完整的文件被寫入  
27 
28         WriteFile(pFile,tmpBuf,dwBytesToWrite,&dwBytesWrite,NULL);
29 
30         dwBytesToWrite -= dwBytesWrite;
31         tmpBuf += dwBytesWrite;
32 
33         } while (dwBytesToWrite > 0);
34 
35     CloseHandle(pFile);
36 
37     return TRUE;
38 }

 

參考博客:

http://www.cnblogs.com/findumars/p/5636108.html

打開Usb

http://blog.csdn.net/dongpanshan/article/details/7898583

 

endl;

 


免責聲明!

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



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