日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

串口通讯编程一日通1(整合资料) .

發布時間:2023/12/10 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 串口通讯编程一日通1(整合资料) . 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

本文以VC++為平臺進行串口通信編程

串口通訊在VC++下實現方式有很多,控件自然是最簡單話的方式了,但由于控件只支持對話框程序,有些場合又不需要對話框,所以用Windows API實現是比較好的方式

串行通信的操作方式

1.同步方式

同步方式中,讀串口的函數試圖在串口的接收緩沖區中讀取規定數目的數據,直到規定數目的數據全部被讀出或設定的超時時間已到時才返回

[cpp] view plaincopyprint?
  • COMMTIMEOUTS?timeOver;//COMMTIMEOUTS結構用于設置讀寫函數的等待時間。??
  • memset(&&timeOver,0,sizeof(timeOver));??
  • DWORD?timeMultiplier,timeConstant;??
  • timeOver.ReadTotalTimeoutMultiplier=timeMultiplier;??
  • timeOver.ReadTotalTimeoutConstant=timeConstant;??
  • SetCommTimeouts(hComport,&&timeOver);??
  • ……??
  • ReadFile(hComport,//串口句柄 ??
  • ???????????inBuffer,//緩沖 ??
  • ???????????nWantRead,//每次調用ReadFile時,函數試圖讀出的字節數 ??
  • ???????????&&nRealRead,//實際讀出的字節數 ??
  • ?????????????NULL);//代表ReadFile將采用同步文件讀寫的方式??
  • COMMTIMEOUTS timeOver;//COMMTIMEOUTS結構用于設置讀寫函數的等待時間。 memset(&&timeOver,0,sizeof(timeOver)); DWORD timeMultiplier,timeConstant; timeOver.ReadTotalTimeoutMultiplier=timeMultiplier; timeOver.ReadTotalTimeoutConstant=timeConstant; SetCommTimeouts(hComport,&&timeOver); …… ReadFile(hComport,//串口句柄inBuffer,//緩沖nWantRead,//每次調用ReadFile時,函數試圖讀出的字節數&&nRealRead,//實際讀出的字節數NULL);//代表ReadFile將采用同步文件讀寫的方式

    如果所規定的待讀取數據的數目nWantRead較大且設定的超時時間也較長,而接收緩沖區中數據較少,則可能引起線程阻塞。解決這一問題的方法是檢查COMSTAT結構的cbInQue成員,該成員的大小即為接收緩沖區中處于等待狀態的數據的實際個數。如果令nWantRead的值等于COMSTAT.cbInQue,就能較好地防止線程阻塞。

    ?

    2.查詢方式

    查詢方式,即一個進程中的某一線程定時地查詢串口的接收緩沖區,如果緩沖區中有數據,就讀取數據;若緩沖區中沒有數據,該線程將繼續執行,因此會占用大量的CPU時間,它實際上是同步方式的一種派生。

    [cpp] view plaincopyprint?
  • COMMTIMEOUTS?timeOver;??
  • memset(&&timeOver,0,sizeof(timeOver));??
  • timeOver.ReadIntervalTimeout=MAXWORD;//注意和同步方式不同的地方??
  • SetCommTimeouts(hComport.&&timeOver);??
  • ……??
  • ReadFile(hComport.??
  • ????????inBuffer.??
  • ????????nWantRead.??
  • ?????????&&nRealRead,??
  • ??????????NULL);//代表ReadFile將采用同步文件讀寫的方式??
  • COMMTIMEOUTS timeOver; memset(&&timeOver,0,sizeof(timeOver)); timeOver.ReadIntervalTimeout=MAXWORD;//注意和同步方式不同的地方 SetCommTimeouts(hComport.&&timeOver); …… ReadFile(hComport.inBuffer.nWantRead.&&nRealRead,NULL);//代表ReadFile將采用同步文件讀寫的方式

    除了COMMTIMEOUTS結構的變量timeOver設置不同外,查詢方式與同步方式在程序代碼方面很類似,但二者的工作方式卻差別很大。盡管ReadFile采用的也是同步文件讀寫方式,但由于timeOver的區間超過時間設置為MAXWORD,所以ReadFile每次將讀出接收隊列中的所有處于等待狀態的數據,一次最多可讀出nWantRead個字節的數據。

    ?

    3.異步方式

    異步方式中,利用Windows的多線程結構,可以讓串口的讀寫操作在后臺進行,而應用程序的其他部分在前臺執行。

    [cpp] view plaincopyprint?
  • OVERLAPPED?wrOverlapped;??
  • COMMTIMEOUTS?timeOver;??
  • memset(&&timeOver.0.sizeof(timeOver));??
  • DWORDtimeMultiplier,timeConstant;??
  • timeOver.ReadTotalTimeoutMultiplier=timeMultiplier;??
  • timeOver.ReadTotalTimeoutConstant=timeConstant;??
  • SetCommTimeouts(hComport,&&timeOver);??
  • wrOverlapped.hEvent=CreateEvent(NULL.TRUE,FALSE,NULL);//創建事件句柄??
  • ……??
  • ReadFile(hComport,??
  • ???????????nBuffer,??
  • ???????????nWantRead,??
  • ???????????&&nRealRead,??
  • ???????????&&wrOverlapped);//異步方式并且與事件聯系上 ??
  • /*由于采用了異步方式,所以它只返回數據是否已開始讀入的狀態,并不返回實際的讀入數據,即ReadFile中的nRealRead無效*/??
  • ??
  • //實際讀入的數據是由GetOverlappedResult函數返回的 ??
  • GetOverlappedResult(hComport,??
  • ????????????????&&wrOverlapped,??
  • ????????????????&&?nRealRead,??
  • ????????????????????TRUE);??
  • /*表示它等待異步操作結束后才返回到應用程序,此時,GetOverlappedResult函數與WaitForSingleObject函數等效。*/??
  • ……??
  • ResetEvent(wrOverlapped.hEvent);//釋放事件句柄??
  • OVERLAPPED wrOverlapped; COMMTIMEOUTS timeOver; memset(&&timeOver.0.sizeof(timeOver)); DWORDtimeMultiplier,timeConstant; timeOver.ReadTotalTimeoutMultiplier=timeMultiplier; timeOver.ReadTotalTimeoutConstant=timeConstant; SetCommTimeouts(hComport,&&timeOver); wrOverlapped.hEvent=CreateEvent(NULL.TRUE,FALSE,NULL);//創建事件句柄 …… ReadFile(hComport,nBuffer,nWantRead,&&nRealRead,&&wrOverlapped);//異步方式并且與事件聯系上 /*由于采用了異步方式,所以它只返回數據是否已開始讀入的狀態,并不返回實際的讀入數據,即ReadFile中的nRealRead無效*///實際讀入的數據是由GetOverlappedResult函數返回的 GetOverlappedResult(hComport,&&wrOverlapped,&& nRealRead,TRUE); /*表示它等待異步操作結束后才返回到應用程序,此時,GetOverlappedResult函數與WaitForSingleObject函數等效。*/ …… ResetEvent(wrOverlapped.hEvent);//釋放事件句柄

    當采用異步方式時,在用CreateFile打開串口設備時,CreateFile函數的參數fdwAttrsAndFlags必須設為FILE_FLAG_ OVERLAPPED。在Windows中,只有在串行設備上才支持異步文件讀寫,并且,GetOverlappedResult函數也只支持串行設備或用DeviceloControl函數打開的文件。

    4.事件驅動
    若對端口數據的響應時間要求較嚴格,可采用事件驅動方式。事件驅動方式通過設置事件通知,當所希望的事件發生時,Windows發出該事件已發生的通知,這與DOS環境下的中斷方式很相似。Windows定義了9種串口通信事件,較常用的有以下三種:

    EV_RXCHAR:接收到一個字節,并放入輸入緩沖區;

    EV_TXEMPTY:輸出緩沖區中的最后一個字符,發送出去;

    EV_RXFLAG:接收到事件字符(DCB結構中EvtChar成員),放入輸入緩沖區。

    在用SetCommMask()指定了有用的事件后,應用程序可調用WaitCommEvent()來等待事件的發生。SetCommMask(hComm,0)可使WaitCommEvent()中止。

    ?

    [cpp] view plaincopyprint?
  • COMSTAT?comStat;??
  • DWORD?dwEvent;??
  • SetCommMask(hComport,EV_RXCHAR);//設置事件代碼 ??
  • /*EV_RXCHAR,表示接收到一個字符時觸發這一事件,然后調用WaitCommEvent函數等待該事件的發生。*/??
  • ……??
  • if(WaitCommEvent(hComport,&&dwEvent,NULL))??
  •  if((dwEvent&&EV_RXCHAR)&&&&comstat.cbInQue)??
  •    ReadFile(hComport,??
  • ??????????????inBuffer,??
  • ???????????????comstat.cbInQue,??
  • ??????????????&&nRealRead,??
  • ????????????????NULL);//表示該函數是同步的??
  • 總結

    以上是生活随笔為你收集整理的串口通讯编程一日通1(整合资料) .的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。