串口通信模块2:串口通信编程基础(打开、配置)
生活随笔
收集整理的這篇文章主要介紹了
串口通信模块2:串口通信编程基础(打开、配置)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
有兩種方式可以操作串口:同步操作方式和異步操作方式(即重疊操作方式)。同步操作時,API函數會阻塞直到操作完成以后才能返回(在多線程方式中,雖然不會阻塞主線程,但是仍然會阻塞監聽線程);而異步操作方式,API函數會立即返回,操作在后臺進行,避免進程阻塞。異步操作方式還允許讀、寫操作能同時進行(即重疊操作),在實際科研項目中非常有用。但是無論哪種操作方式,一般都通過下面的四個步驟來完成:
1.打開串口;
2.配置串口
3.讀寫串口
4.關閉串口
1. 打開串口
在很多系統中(包括Windows系統)把文件的概念進行了拓展。無論是文件、通信設備、命名管道、郵件槽、磁盤、還是控制臺,都是用API函數CreateFile()來打開或創建的。該函數的原型是: <span style="font-size:18px;">HANDLE CreateFile( LPCTSTR lpFileName, //將要打開的串口邏輯名 DWORD dwDesiredAccess, //指定串口訪問的類型 DWORD dwShareMode, //指定共享屬性 LPSECURITY_ATTRIBUTES lpSecurityAttributes, //引用安全型屬性結構 DWORD dwCreationDistribution, //創建標志 DWORD dwFlagsAndAttributes, //屬性描述 HANDLE hTemplateFile //對串口而言該參數必須置為NULL );</span>同步I/O方式打開串口的示例代碼如下: <span style="font-size:18px;">HANDLE OpenCom() { HANDLE hCom; <span style="font-family: Arial, Helvetica, sans-serif;">//串口句柄</span> hCom = CreateFile("COM1", //打開COM1串口 GENERIC_READ|GENERIC_WRITE, //允許串口讀寫 0, //獨占方式,即串行 NULL, OPEN_EXISTING, //打開已存在的文件 0, //同步方式打開 NULL); if(hCom == (HANDLE)-1) //打開失敗 { AfxMessageBox("打開串口失敗!"); return NULL; } return hCom; }</span>與同步I/O方式打開的過程與步驟相同,只是參數有點變化,異步I/O打開串口的代碼示例如下: <span style="font-size:18px;">HANDLE OpenCom() { HANDLE hCom; hCom = CreateFile("COM1", GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, //打開已經存在的文件 FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED, //重疊方式 NULL); if(hCom == (HANDLE)-1) { AfxMessageBox("打開串口失敗!"); return NULL; } return hCom; }</span>2. 配置串口
再打開通信設備句柄后,常常需要對串口進行一些初始化配置工作。配置串口的一些屬性,如串口通信參數、通信超時設置、緩沖區申請及緩沖區清空操作等。 2.1 設置串口參數: 設置串口參數需要通過一個DCB結構來進行。DCB結構包含了諸如波特率、數據位數、奇偶校驗和停止位數等信息。在查詢或配置串口的屬性時,都要通過一個DCB結構的緩沖區。 一般情況下,我們在采用CreateFile打開串口后,可以調用GetCommonState()函數來獲取串口的初始配置。要修改串口的配置,應該先修改DCB結構,然后調用SetCommonState()函數設置串口。DCB結構包含了串口的各項參數設置,下面給出了DCB結構中常用的5個成員變量: BaudRate:波特率,DWORD型變量,指定通信設備的傳輸速率。這個成員可以是實際波特率值或者是下表的常量值之一。fParity:指定奇偶校驗使能,DWORD型變量,若此成員為1,則允許奇偶校驗檢查。 ByteSize:通信字節位數,4-8,BYTE型變量。 Parity:指定奇偶校驗方法,BYTE型變量。此成員的取值如下表所示。
| 值 | winbase.h中的定義 | 說明 |
| NOPARITY | #define NOPARITY 0 | 采用無校驗方式 |
| ODDPARITY | #define ODDPARITY 1 | 采用奇校驗方式 |
| EVENPARITY | #define EVENPARITY 2 | 采用偶校驗方式 |
| MARKPARITY | #define MARKPARITY 3 | 采用標記校驗方式 |
StopBits:指定停止位的位數,BYTE型變量。此成員取值如下表所示。
| 值 | winbase.h中的定義 | 說明 |
| ONESTOPBIT | #define ONESTOPBIT 0 | 1位停止位 |
| ONE5STOPBITS | #define ONE5STOPBITS 1 | 1.5位停止位 |
| TWOSTOPBITS | #define TWOSTOPBITS 2 | 2位停止位 |
再用ReadFile和WriteFile讀寫串行口時,必須要考慮超時問題。超時的作用是在指定的時間內沒有讀入或發送指定數量的字符,ReadFile或WriteFile的操作仍然會結束。 要查詢當前的超時設置,用調用GetCommTimeouts()函數,該函數會填充一個COMMTIMEOUTS結構。調用SetCommTimeouts()函數可以用某一個COMMTIMEOUTS結構的內容來設置超時。 讀寫串口的超時有兩種:間隔超時和總超時。間隔超時是指在接收時兩個字符之間的最大延時。總超時是指讀寫操作總共花費的最大時間。寫操作只支持總延時,而讀操作都支持。用COMMTIMEOUTS結構可以規定讀寫操作的延時。COMMTIMEOUTS結構的定義如下: Typedef struct_COMMTIMEOUTS { ? DWORD ReadIntervalTimeout; ?//讀間隔超時 ??DWORD ReadTotalTimeoutMultiplier; ?//讀時間系數 ??DWORD ReadTotalTimeoutConstant; ?//讀時間常量 ??DWORD WriteTotalTimeoutMultiplier; ?//寫時間系數 ??DWORD WriteTotalTimeoutConstant; ?//寫時間常量 }?COMMTIMEOUTS,*PLCOMMTIMEOUTS;
?COMMTIMEOUTS結構的成員都是以毫秒為單位,總超時的計算公式:
總超時=時間系數*要求讀/寫的字符數+時間常量 例如,要讀入50個字符,那么讀操作的總超時的時間計算公式: ReadTotalTimeout = ReadTotalTimeoutMultiplier*50+ReadTotalTimeoutConstant 可以看出,間隔超時與總超時的設置是不相關的,這可以方便通信程序靈活地設置各種超時。 2.3 申請串口通信緩沖區: 除了在DCB中的設置外,程序一般還需要設置I/O緩沖區的大小和超時。Windows用I/O緩沖區來暫存串口的輸入和輸出數據。如果通信的速率較高,則應該設置較大的緩沖區。調用SetCommon()函數可以設置串行口的輸入和輸出緩沖區大小,函數原型如下: <span style="font-size:18px;">BOOL SetupCommon(HANDLE hFile; //通信設備的句柄DWORD dwInQueue; //輸入緩沖區的大小(字節數)DWORD dwOutQueue;//輸出緩沖區的大小 );</span>2.4 清空串口通信緩沖區:
在讀寫串口之前,還要用PurgeCommon()函數清空緩沖區,該函數的原型如下: <span style="font-size:18px;">BOOL PurgeCommon(HANDLE hFile; //串口句柄DWORD dwFlags );</span>參數dwFlags指定要完成的操作,應該選擇下面表中質的組合:
| 值 | 說明 |
| PURGE_RXABORD | 中斷所有讀操作并立即返回,即使讀操作還沒有完成 |
| PURGE_TXABORT | 中斷所有寫操作并立即返回,即使寫操作還沒有完成 |
| PURGE_TXCLEAR | 清除輸出緩沖區 |
| PURGE_RXCLEAR | 清除輸入緩沖區 |
最后,進行一個小結,給出了串口屬性的示例代碼,如下所示: <span style="font-size:18px;">SetComm(HANDLE hCom) {SetupComm( hCom, 1024,1024); //緩沖區大小COMMTIMEOUTS TimeOuts; //設定讀超時TimeOuts.ReadTntervalTimeout = 1000;TimeOuts.ReadTotalTimeoutMultiplier = 500;TimeOuts.ReadTotalTimeoutConstant = 5000; //設定寫超時TimeOuts.WriteTotalTimeoutMultiplier = 500;TimeOuts.WriteTotalTimeoutConstant = 2000; //設置超時SetCommTimeouts( hFile, &TimeOuts);DCB dcb;GetCommState( hCom, &dcb);dcb.BaudRate = CBR_115200; //波特率dcb.ByteSite = 8; //每個字節為8位dcb.Parity = NOPARITY; //無奇偶校驗位dcb.StopBits = TWOSTOPBITS; //兩個停止位SetCommState( hCom, &dcb);PurgeComm( hCom, PURGE_TXCEAR|PURGE_RXCLEAR); }</span> 與50位技術專家面對面20年技術見證,附贈技術全景圖
總結
以上是生活随笔為你收集整理的串口通信模块2:串口通信编程基础(打开、配置)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 飞鸽传书2007绿色版
- 下一篇: 中国企业即时通讯