青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

開源之路

憶往昔, 項羽不過江. 江東好風(fēng)光! 今振臂一呼,率甲三千, 試問天!
posts - 86, comments - 55, trackbacks - 0, articles - 0
  C++博客 :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理

Win32串口編程

Posted on 2006-07-18 13:03 江邊之鳥 閱讀(981) 評論(0)  編輯 收藏 引用
一、基本知識

   Win32下串口通信與16位串口通信有很大的區(qū)別。在Win32下,可以使用兩種編程方式實現(xiàn)串口通信,其一是調(diào)用的Windows的API函數(shù),其二是使用ActiveX控件。使用API 調(diào)用,可以清楚地掌握串口通信的機制,熟悉各種配置和自由靈活采用不同的流控進行串口通信。下面介紹串口操作的基本知識。

  打開串口:使用CreateFile()函數(shù),可以打開串口。有兩種方法可以打開串口,一種是同步方式(NonOverlapped),另外一種異步方式(Overlapped)。使用Overlapped打開時,適當?shù)姆椒ㄊ牵?

HANDLE hComm;
hComm = CreateFile( gszPort,
GENERIC_READ | GENERIC_WRITE,
0,
0,
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED,
0);
if (hComm == INVALID_HANDLE_value)
// error opening port; abort
  配置串口:

  1.DCB配置

   DCB(Device Control Block)結(jié)構(gòu)定義了串口通信設(shè)備的控制設(shè)置。許多重要設(shè)置都是在DCB結(jié)構(gòu)中設(shè)置的,有三種方式可以初始化DCB。

  (1)通過GetCommState()函數(shù)得DCB的初始值,其使用方式為:

DCB dcb = {0};
if (!GetCommState(hComm, &dcb))
// Error getting current DCB settings
else
// DCB is ready for use.

  (2)用BuildCommDCB()函數(shù)初始化DCB結(jié)構(gòu),該函數(shù)填充 DCB的波特率、奇偶校驗類型、數(shù)據(jù)位、停止位。對于流控成員函數(shù)設(shè)置了缺省值。其用法是:

DCB dcb;
FillMemory(&dcb, sizeof(dcb), 0);
dcb.DCBlength = sizeof(dcb);
if (!BuildCommDCB(“9600,n,8,1", &dcb)) {
// Couldn't build the DCB. Usually a problem
// with the communications specification string.
return FALSE;
}
else
// DCB is ready for use.

  (3)用SetCommState()函數(shù)手動設(shè)置DCB初值。用法如下:

DCB dcb;
FillMemory(&dcb, sizeof(dcb), 0);
if (!GetCommState(hComm, &dcb)) // get current DCB
// Error in GetCommState
return FALSE;
// Update DCB rate.
dcb.BaudRate = CBR_9600 ;
// Set new state.
if (!SetCommState(hComm, &dcb))
// Error in SetCommState.
Possibly a problem with the communications
// port handle or a problem with the DCB structure itself.

  手動設(shè)置DCB值時,DCB的結(jié)構(gòu)的各成員的含義,可以參看MSDN幫助。

   2.流控設(shè)置

  硬件流控:串口通信中的硬件流控有兩種,DTE/DSR方式和RTS/CTS方式,這與DCB結(jié)構(gòu)的初始化有關(guān)系,DCB結(jié)構(gòu)中的OutxCtsFlow、 fOutxDsrFlow、fDsrSensitivity、fRtsControl、fDtrControl幾個成員的初始值很關(guān)鍵,不同的值代表不同流控,也可以自己設(shè)置流控,但建議采用標準流行的流控方式。采用硬件流控時,DTE、DSR、RTS、CTS的邏輯位直接影響到數(shù)據(jù)的讀寫及收發(fā)數(shù)據(jù)的緩沖區(qū)控制。

   軟件流控:串口通信中采用特殊字符XON和XOFF作為控制串口數(shù)據(jù)的收發(fā)。與此相關(guān)的DCB成員是:fOut、fInX、XoffChar、XonChar、 XoffLim和XonLim。具體含義參見MSDN幫助。

   串口讀寫操作:串口讀寫有兩種方式:同步方式(NonOverlapped)和異步方式(Overlapped)。同步方式是指必須完成了讀寫操作,函數(shù)才返回,這可能造成程序死掉,因為如果在讀寫時發(fā)生了錯誤,永遠不返回就會出錯,可能線程將永遠等待在那兒。而異步方式則靈活得多,一旦讀寫不成功,就將讀寫掛起,函數(shù)直接返回,可以通過GetLastError函數(shù)得知讀寫未成功的原因,所以常常采用異步方式操作。

   讀操作:ReadFile()函數(shù)用于完成讀操作。異步方式的讀操作為:

DWORD dwRead;
BOOL fWaitingOnRead = FALSE;
OVERLAPPED osReader = {0};
// Create the overlapped event. Must be closed before exiting
// to avoid a handle leak.
osReader.hEvent = CreateEvent
(NULL, TRUE, FALSE, NULL);
if (osReader.hEvent == NULL)
// Error creating overlapped event; abort.
if (!fWaitingOnRead) {
// Issue read operation.
if (!ReadFile(hComm, lpBuf, READ_BUF_SIZE,
 &dwRead, &osReader)) {
if (GetLastError() != ERROR_IO_PENDING)
?,?/ read not delayed?
// Error in communications; report it.
else
fWaitingOnRead = TRUE;
}
else {
// read completed immediately
HandleASuccessfulRead(lpBuf, dwRead);
}
}

   如果讀操作被掛起,可以調(diào)用WaitForSingleObject()函數(shù)或WaitForMuntilpleObjects()函數(shù)等待讀操作完成或者超時發(fā)生,再調(diào)用 GetOverlappedResult()得到想要的信息。

   寫操作:與讀操作相似,故不詳述,調(diào)用的API函數(shù)是: WriteFile函數(shù)。

   串口狀態(tài):

 ?。?)通信事件:用SetCommMask()函數(shù)設(shè)置想要得到的通信事件的掩碼,再調(diào)用WaitCommEvent()函數(shù)檢測通信事件的發(fā)生??稍O(shè)置的通信事件標志(即SetCommMask()函數(shù)所設(shè)置的掩碼)可以有EV_BREAK、EV_CTS、EV_DSR、 EV_ERR、EV_RING、EV_RLSD、EV_RXCHAR、EV_RXFLAG、EV_TXEMPTY。

   注意:1對于EV_RING標志的設(shè)置,WIN95是不會返回EV_RING事件的,因為WIN95不檢測該事件。2設(shè)置EV_RXCHAR,可以檢測到字符到達,但是在綁定此事件和ReadFile()函數(shù)一起讀取串口接收數(shù)據(jù)時,可能會出現(xiàn)錯誤,造成少讀字節(jié)數(shù),具體原因查看MSDN幫助??梢圆捎醚h(huán)讀的辦法,另外一個比較好的解決辦法是調(diào)用ClearCommError()函數(shù),確定在一次讀操作中在緩沖區(qū)中等待被讀的字節(jié)數(shù)。

 ?。?)錯誤處理和通信狀態(tài):在串口通信中,可能會產(chǎn)生很多的錯誤,使用ClearCommError()函數(shù)可以檢測錯誤并且清除錯誤條件。

   (3)Modem狀態(tài):用SetcommMask()可以包含很多事件標志,但是這些事件標志只指示在串口線路上的電壓變化情況。而調(diào)用 GetCommModemStatus()函數(shù)可以獲得線路上真正的電壓狀態(tài)。

   擴展函數(shù):如果應(yīng)用程序想用自己的流控,可以使用 EscapeCommFunction()函數(shù)設(shè)置DTR和RTS線路的電平。

   通信超時:在通信中,超時是個很重要的考慮因素,因為如果在數(shù)據(jù)接收過程中由于某種原因突然中斷或停止,如果不采取超時控制機制,將會使得I/O線程被掛起或無限阻塞。串口通信中的超時設(shè)置分為兩步,首先設(shè)置 COMMTIMEOUTS結(jié)構(gòu)的五個變量,然后調(diào)用SetcommTimeouts()設(shè)置超時值。對于使用異步方式讀寫的操作,如果操作掛起后,異步成功完成了讀寫,WaitForSingleObject()或 WaitForMultipleObjects()函數(shù)將返回WAIT_OBJECT_0,GetOverlappedResult()返回TRUE。其實還可以用GetCommTimeouts()得到系統(tǒng)初始值。

   關(guān)閉串口:程序結(jié)束或需要釋放串口資源時,應(yīng)該正確關(guān)閉串口,關(guān)閉串口比較簡單,使用API調(diào)用CloseHandle()關(guān)閉串口的句柄就可以了。

  調(diào)用方法為:CloseHandle(hComm);

   但是值得注意的是在關(guān)閉串口之前必須保證讀寫串口線程已經(jīng)退出,否則會引起誤操作,一般采用的辦法是使用事件驅(qū)動機制,啟動一事件,通知串口讀寫線程強制退出,在線程退出之前,通知主線程可以關(guān)閉串口。

二、實現(xiàn)

  1.程序設(shè)計思路

   對于不同的應(yīng)用程序,雖然界面不同,但是如果采用串口與主機之間的通信,對串口的處理方式大致相似,無非就是通過串口收發(fā)數(shù)據(jù),對于通過串口接收到的數(shù)據(jù),交給上層軟件處理顯示,對于上層要發(fā)給串口的數(shù)據(jù),進行轉(zhuǎn)發(fā)。但在實際編程中,由于采用的通信方式和流控不同,串口設(shè)置也不同,這就涉及到 DCB的初始化問題和讀寫串口等細節(jié)問題。串口通信應(yīng)用程序設(shè)計的總體思路(即操作過程)是:首先,確定要打開的串口名、波特率、奇偶校驗方式、數(shù)據(jù)位、停止位,傳遞給CreateFile()函數(shù)打開特定串口;其次,為了保護系統(tǒng)對串口的初始設(shè)置,調(diào)用 GetCommTimeouts()得到串口的原始超時設(shè)置;然后,初始化DCB對象,調(diào)用SetCommState() 設(shè)置DCB,調(diào)用SetCommTimeouts()設(shè)置串口超時控制;再次,調(diào)用SetupComm()設(shè)置串口接收發(fā)送數(shù)據(jù)的緩沖區(qū)大小,串口的設(shè)置就基本完成,之后就可以啟動讀寫線程了。

  一般來說,串口的讀寫由串口讀寫線程完成,這樣可以避免讀寫阻塞時主程序死鎖。對于全雙工的串口讀寫,應(yīng)該分別開啟讀線程和寫線程;對于半雙工和單工的,建議只需開啟一個線程即可。在線程中,按照預(yù)定好的通信握手方式,正確檢測串口狀態(tài),讀取發(fā)送串口數(shù)據(jù)。

  2.實現(xiàn)細節(jié)

  在半雙工的情況下,首先完成必要的串口配置,成功打開串口、DCB設(shè)置、超時設(shè)置;然后開啟線程,如: CwinThread hSerialThread = (CWinThread*) AfxBeginThread(SerialOperation,hWnd,THREAD_PRIORITY_NORMAL); 其中開啟之線程為SerialOperation,優(yōu)先級為普通。

   全雙工情況下的串口編程,與單工差不多,區(qū)別僅僅在于啟動雙線程,分別為讀線程和寫線程,讀線程根據(jù)不同的事件或消息,通過不斷查詢串口所收到的有效數(shù)據(jù),完成讀操作;寫線程通過接收主線程的發(fā)送數(shù)據(jù)事件和要發(fā)送的數(shù)據(jù),向串口發(fā)送。
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            欧美成人中文| 久久久久国产精品一区| 国内精品美女av在线播放| 久久男人资源视频| 91久久久久久| 亚洲欧美日韩直播| 亚洲制服av| 一本色道久久综合狠狠躁篇的优点| 国内精品一区二区| 亚洲欧美日本精品| 亚洲国产高清一区| 午夜精品久久久久久久白皮肤| 欧美母乳在线| 久久九九99视频| 亚洲欧洲视频| 韩国欧美一区| 亚洲小视频在线| 欧美激情黄色片| 麻豆国产va免费精品高清在线| 亚洲精品欧美日韩| 激情综合激情| 亚洲精品一区二区三区蜜桃久 | 亚洲欧美一区二区三区久久| 久久久.com| 女同一区二区| 午夜精品久久久久| 亚洲午夜久久久久久尤物| 欧美精品乱码久久久久久按摩| 亚洲一区二区精品视频| 欧美freesex8一10精品| 国产精品久久一卡二卡| 亚洲另类自拍| 亚洲人成在线影院| 亚洲激情网址| 亚洲精选久久| 99视频一区二区| 亚洲欧美日韩在线综合| 欧美三级视频在线观看| 亚洲一级片在线看| 新狼窝色av性久久久久久| 欧美成人中文| 欧美一区激情视频在线观看| 91久久精品国产91久久| 欧美一区二区三区四区视频| 午夜精品视频网站| 欧美freesex交免费视频| 欧美成人一区二区三区在线观看 | 国产欧美日韩一区| 亚洲国产另类久久精品| 亚洲国产精品精华液2区45| 久久一区二区三区av| 久久久久国产精品人| 亚洲国产欧美一区二区三区丁香婷| 黄色成人片子| 亚洲国产精品小视频| 亚洲欧美色婷婷| 亚洲女性喷水在线观看一区| 亚洲国产日韩欧美在线99| 国产精品久久精品日日| 欧美一区二区三区免费在线看| 亚洲精品一区二区三区婷婷月| 欧美va天堂| 午夜精品国产精品大乳美女| 久久久另类综合| 99视频在线观看一区三区| 亚洲看片一区| 欧美一级欧美一级在线播放| 亚洲第一黄网| 欧美日韩国产在线播放| 亚洲小说春色综合另类电影| 欧美午夜电影在线| 欧美激情中文字幕乱码免费| 免费在线一区二区| 韩国成人福利片在线播放| 久久一区国产| 亚洲国产高清高潮精品美女| 欧美在线首页| 麻豆精品在线播放| 亚洲一区免费| 国产精品va在线播放| 亚洲女同在线| 午夜在线成人av| 一区福利视频| 国产精品午夜电影| 99在线精品观看| 亚洲电影激情视频网站| 国产精品久久久久免费a∨大胸| 欧美区高清在线| 久久久久久色| 国产女人18毛片水18精品| 国产日韩欧美a| 国产伦理一区| 亚洲欧美日韩精品综合在线观看 | 日韩一级黄色大片| 一本大道久久a久久精品综合| 欧美激情免费在线| 亚洲图片激情小说| 亚洲视频成人| 午夜精品久久久久| 亚洲三级色网| 国产精品视频你懂的| 欧美激情按摩| 欧美日韩亚洲一区二| 在线观看欧美激情| 亚洲嫩草精品久久| 久久黄色网页| 性亚洲最疯狂xxxx高清| 欧美一区二区三区视频在线| 久久黄色级2电影| 国产精品久久久久久久久久直播 | 亚洲国产专区| 欧美日韩第一区| 欧美日韩免费一区二区三区| 国产噜噜噜噜噜久久久久久久久| 一区二区三区回区在观看免费视频| 欧美亚洲综合久久| 99亚洲一区二区| 国产一级一区二区| 亚洲性视频网站| 久久aⅴ乱码一区二区三区| 久久精品首页| 国产日韩在线播放| 国产精品成人久久久久| 一区二区三区导航| 欧美日韩国内| 欧美日韩专区| 国产一区二三区| 一区二区不卡在线视频 午夜欧美不卡'| 亚洲性xxxx| 欧美激情一区二区三区成人| 欧美日韩亚洲三区| 亚洲一区二区欧美| 久久久人成影片一区二区三区| 一本色道久久综合亚洲精品不 | 久久香蕉国产线看观看av| 久久综合精品国产一区二区三区| 亚洲欧美久久| 国产精品人成在线观看免费 | 国产亚洲精品久久久久久| 亚洲黄色毛片| 亚洲福利国产| 亚洲一区二区三区乱码aⅴ| 免费日韩av片| 欧美成人一区二区三区| 国产视频欧美视频| 午夜视频一区| 免费欧美网站| 美女脱光内衣内裤视频久久影院| 日韩视频一区二区三区在线播放| aa级大片欧美| 欧美精品99| 91久久精品美女高潮| 一区二区三区国产在线观看| 欧美不卡一区| 欧美成人午夜免费视在线看片| 午夜精品福利一区二区三区av| 欧美激情在线免费观看| 国产精品女主播在线观看| 久久久精品国产免费观看同学| 免费观看在线综合| 欧美永久精品| 国产精品色婷婷久久58| 亚洲美女性视频| 免费在线观看成人av| 久久综合给合久久狠狠色 | 国产欧美日韩亚洲精品| 欧美国产日韩在线| 亚洲人久久久| 亚洲欧美在线磁力| 久久伊人一区二区| 欧美一级视频一区二区| 美女精品视频一区| 欧美韩日一区二区| 国产综合亚洲精品一区二| 一区二区av在线| 男女av一区三区二区色多| 国产午夜精品久久久久久免费视 | 亚洲国产高清在线观看视频| 国产视频一区在线| 久久久之久亚州精品露出| 午夜精品久久久久久久99黑人| 国产精品久久久久久久久婷婷| 性欧美长视频| 国产毛片一区二区| 亚洲一区二区三区在线视频| 欧美有码视频| 亚洲国产美女| 欧美成年人视频网站| 欧美电影在线观看| 黄色在线一区| 国产精品九九久久久久久久| 亚洲午夜一区二区三区| 久久国产精品一区二区三区四区| 国产综合色产在线精品| 国产精品美女主播在线观看纯欲| 亚洲一区二区三区成人在线视频精品| 久久综合给合| 一区二区三区精密机械公司| 伊人久久亚洲美女图片| 一区二区三区精品|