中文字幕视频在线免费_日韩在线精品_日韩视频免费看_中文字幕在线三区_午夜免费视频_日韩在线大片

用Win32 API實現串行通信

來源:網絡

點擊:2179

A+ A-

所屬頻道:新聞中心

關鍵詞: Win32,串行通信

    用Win32 API實現串行通信

    串口是常用的計算機與外部串行設備之間的數據傳輸通道,由于串行通信方便
    易行,所以應用廣泛。我們可以利用Windows API 提供的通信函數編寫出高可移植性的
    串行通信程序。
        在Win16中,可以利用OpenComm、CloseComm和WriteComm等函數打開、關閉和
    讀寫串口。但在Win32中,串口和其他通信設備均被作為文件處理,串口的打開、關閉
    和讀寫等操作所用的API函數與操作文件的函數相同。可通過CreateFile函數打開串口
    ,通過CloseFile函數關閉串口,通過CommProp、DCB結構、GetCommProperties、
    SetCommProperties、GetCommState及SetCommState等函數設置串口狀態,通過函數
    ReadFile和WritFile讀寫串口。 
    VC++ 6.0是Windows應用程序開發的主流語言之一,它具有良好的圖形設計
    界面并支持面向對象的程序設計方法。本文結合一個實例介紹在VC++ 6.0下如何利用
    Win32 API 實現串行通信程序。 
    實現原理 
        本文的實例來自一個水泥發貨系統,在系統中,需要將通過總量傳感器采集到
    的倉重值傳入到計算機中,以便系統做出相應的處理。這需要使用串行通信來完成采集
    數據的傳遞工作。 
        對于串行通信設備,Win32 API支持同步和異步兩種I/O操作。同步操作方式的
    程序設計相對比較簡單,但I/O操作函數在I/O操作結束前不能返回,這將掛起調用線程
    ,直到I/O操作結束。異步操作方式相對要復雜一些,但它可讓耗時的I/O操作在后臺進
    行,不會掛起調用線程,這在大數據量通信的情況下對改善調用線程的響應速度是相當
    有效的。異步操作方式特別適合同時對多個串行設備進行I/O操作和同時對一個串行設
    備進行讀/寫操作。這兩種操作方式的程序設計基本思想是相似的,本文將針對同步操
    作方式給出具體的通信程序設計,同時簡單說明如何實現異步的I/O操作。 
    串行設備的初始化 
        串行設備的初始化是利用CreateFile函數實現的。該函數獲得串行設備句柄并
    對其進行通信參數設置,包括設置輸出/接收緩沖區大小、超時控制和事件監視等。 
    //串行設備句柄; 
    HANDLE hComDev=0;  
    //串口打開標志; 
    BOOL bOpen=FALSE; 
    //線程同步事件句柄; 
    HANDLE hEvent=0;  
    BOOL SetupSynCom() 
    {  
     DCB dcb; 
     COMMTIMEOUTS timeouts; 
     //設備已打開 
     if(bOpen) return FALSE;   
     //打開COM1 
    if((hComDev=CreateFile(“COM1”,GENERICREAD|GENERICWRITE,0,NULL,OPEN
    EXISTING,FILEATTRIBUTENORMAL,NULL))== 
    INVALIDHANDLEVALUE)  
    return FALSE; 
    //設置超時控制 
    SetCommTimeouts(hComDev,&timeouts);  
     //設置接收緩沖區和輸出緩沖區的大小 
     SetupComm(hComDev,1024,512);  
    //獲取缺省的DCB結構的值 
     GetCommState(hComDev,&dcb);  
    //設定波特率為9600 bps 
     dcb.BaudRate=CBR9600;  
    //設定無奇偶校驗 
     dcb.fParity=NOPARITY;  
    //設定數據位為8 
     dcb.ByteSize=8;  
     //設定一個停止位 
     dcb.StopBits=ONESTOPBIT;  
    //監視串口的錯誤和接收到字符兩種事件 
     SetCommMask(hComDev,EVERR|EVRXCHAR);  
    //設置串行設備控制參數 
     SetCommState(hComDev,&dcb);  
    //設備已打開 
     bOpen=TRUE;  
     //創建人工重設、未發信號的事件 
     hEvent=CreateEvent(NULL,FALSE,FALSE, 
    “WatchEvent”); 
    //創建一個事件監視線程來監視串口事件 
     AfxBeginThread(CommWatchProc,pParam);  

     

    在設置串口DCB結構的參數時,不必設置每一個值。首先讀出DCB缺省的參數設
    置,然后只修改必要的參數,其他參數都取缺省值。由于對串口進行的是同步I/O操作
    ,所以除非指定進行監測的事件發生,否則WaitCommEvent函數不會返回。在串行設備
    初始化的最后要建立一個單獨的監視線程來監視串口事件,以免掛起當前調用線程,其
    中pParam可以是一個對事件進行處理的窗口類指針。 
    如果要進行異步I/O操作,打開設備句柄時,CreateFile的第6個參數應增加FILEFLAG
    OVERLAPPED 標志。 
    數據發送 
            數據發送利用WriteFile函數實現。對于同步I/O操作,它的最后一個參數可為
    NULL;而對異步I/O操作,它的最后一個參數必需是一個指向OVERLAPPED結構的指針,
    通過OVERLAPPED結構來獲得當前的操作狀態。 
    BOOL WriteComm(LPCVOID lpSndBuffer,DWORD  
    dwBytesToWrite) 
    { //lpSndBuffer為發送數據緩沖區指針, 
    dwBytesToWrite為將要發送的字節長度 
    //設備已打開 
     BOOL bWriteState;  
    //實際發送的字節數 
     DWORD dwBytesWritten;  
    //設備未打開 
     if(!bOpen) return FALSE;  
     bWriteState=WriteFile(hComDev,lpSndBuffer, 
    dwBytesToWrite,&dwBytesWritten,NULL); 
     if(!bWriteState || dwBytesToWrite!=dwBytesWritten) 
    //發送失敗 
      return FALSE;  
     else 
    //發送成功 
      return TRUE;  

    數據接收 
        接收數據的任務由ReadFile函數完成。該函數從串口接收緩沖區中讀取數據,
    讀取數據前,先用ClearCommError函數獲得接收緩沖區中的字節數。接收數據時,同步
    和異步讀取的差別同發送數據是一樣的。 
    DWORD ReadComm(LPVOID lpInBuffer,DWORD  
    dwBytesToRead) 
    { //lpInBuffer為接收數據的緩沖區指針, dwBytesToRead為準備讀取的數據長度(字
    節數) 
    //串行設備狀態結構 
     COMSTAT ComStat;  
     DWORD dwBytesRead,dwErrorFlags;  
    //設備未打開 
     if(!bOpen) return 0; 
     //讀取串行設備的當前狀態 
     ClearCommError(hComDev,&dwErrorFlags,&ComStat);  
     //應該讀取的數據長度 
    dwBytesRead=min(dwBytesToRead,ComStat.cbInQue);  
     if(dwBytesRead>0) 
      //讀取數據 
      if(!ReadFile(hComDev,lpInBuffer,dwBytesRead,&dwBytesRead,NULL))  
       dwBytesRead=0; 
     return dwBytesRead; 

    事件監視線程 
        事件監視線程對串口事件進行監視,當監視的事件發生時,監視線程可將這個
    事件發送(SendMessage)或登記(PostMessage)到對事件進行處理的窗口類(由pParam指
    定)中。 
    UINT CommWatchProc(LPVOID pParam) 
    { DWORD dwEventMask=0; //發生的事件; 
     while(bOpen) 
     { //等待監視的事件發生 
    WaitCommEvent(hComDev, &dwEventMask,  
    NULL);  
     if ((dwEventMask & EVRXCHAR) ==  
    EVRXCHAR) 
    ……//接收到字符事件后,可以將此消息登記到由pParam有指定的窗口類中進行處理 
      if(dwEventMask & EVERR)==EVERROR) 
       ……//發生錯誤時的處理 
     } 
     SetEvent(hEvent);  
     //發信號,指示監視線程結束 
     return 0; 

     


    關閉串行設備 
        在整個應用程序結束或不再使用串行設備時,應將串行設備關閉,包括取消事
    件監視,將設備打開標志bOpen置為FALSE以使事件監視線程結束,清除發送/接收緩沖
    區和關閉設備句柄。 
    void CloseSynComm() 
    {  
    if(!bOpen) return; 
    //結束事件監視線程 
     bOpen=FALSE;  
     SetCommMask(hComDev,0);  
     //取消事件監視,此時監視線程中的WaitCommEvent將返回 
     WaitForSingleObject(hEvent,INFINITE); 
     //等待監視線程結束 
     CloseHandle(hEvent); //關閉事件句柄 
     //停止發送和接收數據,并清除發送和接收緩沖區 
    PurgeComm(hComDev,PURGETXABORT| 
    PURGERXABORT|PURGETXCLEAR| 
    PURGERXCLEAR); 
    //關閉設備句柄 
     CloseHandle(hComDev);  

    小 結 
        以上給出了用Win32 API 設計串行通信的基本思路,對這個同步I/O操作的串
    行通信程序稍加改造就可進行異步I/O操作。在實際應用中,我們可以將這些串行通信
    函數和成員變量加到一個已有的CWnd類或其派生類中來實現串行通信,也可設計一個新
    的串行通信類來包含這些成員函數和成員變量。總之,利用Win32 API可以設計出滿足
    各種需要的串行通信程序。
     

     

    (審核編輯: 智匯小新)

    聲明:除特別說明之外,新聞內容及圖片均來自網絡及各大主流媒體。版權歸原作者所有。如認為內容侵權,請聯系我們刪除。

    主站蜘蛛池模板: 亚洲激情久久 | 精品视频在线一区 | 黄版视频在线观看 | 欧美大片免费高清观看 | 精品在线 | 欧美区亚洲区 | 精品福利一区二区三区 | 亚洲国产成人久久 | 韩国成人精品a∨在线观看 欧美精品综合 | 欧美在线观看一区 | 欧美3区 | 天天爱天天草 | 91av国产精品 | 欧美成人久久久免费播放 | 久久精品国产91精品亚洲高清 | 久久久国产一区二区三区 | 久久成人精品 | 国产精品久久久久永久免费观看 | 日本成人一区 | 色偷偷888欧美精品久久久 | 久久久精品综合 | 天天澡天天狠天天天做 | 久久不色| 国产精品美女www爽爽爽软件 | 日本淫片 | 欧美在线a | 一级全黄性色生活片 | 亚洲在线视频 | 日本一区二区三区四区 | 日韩一区精品视频 | 一区视频 | 可以免费看黄的网站 | 欧洲精品码一区二区三区免费看 | 国产一级片免费观看 | 亚洲精品国产区欧美区在线 | 欧美大片免费影院在线观看 | 亚洲专区 中文字幕 | 精品国产欧美一区二区 | 一区在线视频 | 精品视频久久 | 日韩精品一区二区在线观看视频 |