• <abbr id="kam3m"><form id="kam3m"></form></abbr>

    <u id="kam3m"><li id="kam3m"></li></u>

  • <table id="kam3m"></table>
    
    

    <u id="kam3m"></u>
    18禁无遮挡啪啪无码网站,真人无码作爱免费视频,2018年亚洲欧美在线v,国产成人午夜一区二区三区 ,亚洲精品毛片一区二区,国产在线亚州精品内射,精品无码国产污污污免费,国内少妇人妻偷人精品
    首頁 > 文章中心 > 正文

    小議Windows通信編程思考

    前言:本站為你精心整理了小議Windows通信編程思考范文,希望能為你的創作提供參考價值,我們的客服老師可以幫助你提供個性化的參考范文,歡迎咨詢。

    小議Windows通信編程思考

    一、windows通信機制

    Windows與DOS編程的重要差別在于Windows程序是消息驅動和設備統一管理。體現在通信方面,DOS中的寄存器直接讀寫、BIOS調用和通信中斷程序等編程方法都不能或不宜采用。Windows通過通信驅動程序COMM.DRV與硬件接口,向程序員提供了多達17個標準函數,功能強大,但也增加了理解和編程的難度。

    Windows3.1通信函數主要有:

    OpenComm

    打開一通信設備

    BuildCimmDCB將一設備定義字符串轉變為DCB數據結構

    EnableCommNotification使能或禁止傳送WM_COMMNOTIFY消

    SetCommState設置通信設備狀態

    SetCommEventMask設置通信事件掩碼

    ReadComm從通信設備讀字符

    WriteComm向通信設備寫字符

    FlushComm清除一發送或接收隊列

    GetCommEventMask返回通信事件掩碼

    GetCommState返回設備控制塊(DCB)

    GetCommError恢復通信設備狀態

    CloseComm關閉一通信設備

    DCB數據結構、其它通信函數及各函數的具體用法請參見有關資料。

    一般Windows通信編程應包括兩部分:設備初始化及WM_COMMNOTIF

    Y消息處理。

    設備初始化典型流程如圖1。

    圖1

    WM_COMMNOTIFY消息處理典型流程如圖2。

    圖2

    對于大多數實際通信來說,可能只需要處理流程圖中的一部分。

    設備初始化及WM_COMMNOTIFY消息處理兩部分密切相關。所有類型WM_COMMNOTIFY消息的傳送都是因為在初始化函數中進行了相應的設置。

    換言之,可以根據通信的實際情況有選擇地設置,控制Windows向應用程序發送的WM_COMMNOTIFY消息的數量和類型,以期達到高效、可靠的通信。例如,對于固定長度消息型的通信可以在EnableCommNotification函數中設置cbWriteNotify和cbOutQueue參數為消息長度;對于以固定字符結尾的消息型通信可以在事件掩碼中包括EV_RXFLAG,將DCB數據結構中的EvtChar變量置為結尾字符,然后調用SetCommState和SetCommEventMask函數;對于遵循V.25bis之類協議的通信,由于用到了大量信號線來作握手信號,則事件掩碼中要包含EV_CTS、EV_DSR、EV_RSLD及EV_RING等;而對于文件傳送型的通信,則宜將OpenComm函數中的cbInQue和cbOutQue變量、EnablecCommNotification中的cbWriteNotify和cbOutQueue變量設置為較大值,以加快文件傳送速度。

    二、Windows通信疑難探討

    現將筆者在實際編程中遇到的疑難和解決辦法描述如下,希望對遇到類似問題的朋友有所啟發。

    1.怎樣用Windows未提供的波特率通信?

    Windows提供了由110bps至256000bps共十三種波特率,一般情況下已足夠使用。但在某種特定情況下,例如通信對方使用150bps、又無法要求對方改變波特率時,Windows通信就比較困難了。

    首先想到的解決方法是直接調用BIOS中斷14H來設置波特率(DOS提供了150bps的波特率)。結果是Windows屏蔽了該中斷,嘗試失敗。

    最后的是采用"蒙混過關"的辦法解決問題的:首先,以任一Windows支持的波特率(例如300bps)構造通信參數字符串,調用BuildCommDCB產生DCB數據結構;然后調用SetCommState設置通信參數;最后再調用自編函數直接修改串口通信寄存器的值。經實驗,設置成功,且對Windows程序運行無任何不良影響。

    2.接收數據為何"丟失"?

    通過設置EnableCommNotification函數中的cbWriteNotify參數(在發送WM_COMMNOTIFY消息之前,通信設備驅動程序必須向應用程序出入隊列中寫入的字節數),可以使系統每收到固定個字符發出一WM_COMMNOTIFY消息,這對于固定長度消息型的通信是很方便的。但實際應用時有時會發生接收數據"丟失"現象,即收到WM_COMMNOTIFY消息后從接收隊列讀出cbNotify個數據時,發現只有前面部分數據正確。

    經檢查,"丟失"現象是由于接收數據超時引起的,當通信對方時鐘頻率較低時,規定時間內收不到cbWriteNotify指定的數據量,即所謂"超時",Windows照樣向應用程序發送帶CN_RECEIVE標志的WM_COMMNOTI

    FY消息。然后,在應用程序輸入隊列數據讀出之前,Windows不再發送該類消息。

    解決的方法是減小cbWriteNotify的設定值直到不再發生"超時"現象。

    發送數據時同樣應正確設定cbOutQue值,以免產生"超時"現象。

    如果將cbWriteNotify或cbOutQue設為-1,則Windows不傳送帶CN_RECEIVE或CN_TRANSMIT標志的WM_COMMNOTIFY消息。

    3.怎樣合理使用FlushComm與GetCommError函數?

    FlushComm函數的功能是清除指定設備接收或發送隊列。GetCommError函數的功能是返回指定設備最近錯誤碼和當前狀態,更重要的是"解鎖"功能:當出現通信錯誤時,Windows會鎖死通信端口直到調用GetCommError。

    調用FlushComm的時機很重要,如果通信端口發生錯誤,不調用該函數就有可能會使接收隊列包含不期望的數據;若隨便調用該函數,也有可能造成尚未讀入或發出的數據丟失。總之,調用該函數要做到"心中有數"。

    為了合理調用FlushComm和GetCommError函數,建議在事件掩碼中包含EV_ERR與EV_BREAK。

    4.Windows多串口通信

    Windows最多可支持四個串口的通信,但對于ISA總線的PC,由于其COM1與COM3、COM2與COM4分別共用IRQ3和IRQ4,所以只能同時使用兩個串口。MCA、EISA總線系統沒有此限制。

    如果需要使用的端口不止四個,可以在PC護展槽中加插多用戶卡,如美國的Comtrol、臺灣的Moxa(摩莎)等,就可以支持幾個到幾十個串口,加上隨卡提供的Windows驅動程序,就可以進行多串口通信。具體用法請參閱擴展卡說明書。

    三、Windows通信實例

    實例的通信環境為:本方COMPAQ4/50微機,安裝中文Windows3.2;對方為8031單片機。通信參數設置:波特率150bps,數據位8,停止位1,無校驗。通信協議是:對方發FF,本方收到后回0F,對方收到0F后發一條十字節的消息,本方回0F,結束一次通信。

    編程環境為中文Windows3

    2、BorlandC++3.1OWL。

    #include<windows.h>

    #include<owl.h>

    #include<window.h>

    #include<string.h>

    intCOM=1;//串口號

    unsignedcharReceiveBuff〔11〕;//接收數據緩存

    _CLASSDEF(TCommApp)

    classTCommApp:publicTapplication

    {

    public:

    TCommApp(LPSTRAName,HINSTANCEhInstance,HINSTANCE

    HPrevInstance,LPSTR1p

    CmdLine,intnCmdshow)

    :TApplication(AName,hInstance,hPrevInstance,1pCmd

    Line,nCmdShow){};

    virtualvoidInitMainWindow();

    };

    _CLASSDEF(TCommWin)//主窗口類

    classTCommWin:publicTWindow

    {

    public:

    TCommWin(PTWindowsObjectAParent,LPSTRATitle):

    TWindow(AParent,Atitle){}

    intInitCom();

    voidSetBaud();//設置Windows不支持的波特率

    virtualBOOLWMCommNotify(TMessage&Mg)=〔WM_FIRST+

    WM_COMMNOTIFY〕;

    virtualvoidSetupWindow();

    };

    //該函數設置串口2的波特率為150bps,若用Windows提//供的波特率通信,則無須該函數

    VoidTCommWin::SetBaud()

    {

    asmcli;

    asmmovdx,2fbh;

    asmmoval,80h;

    asmoutdx,al;

    asmmovdx,2f8h;

    asmmoval,00h;

    asmoutdx,al;

    asmmovdx,2f9h;

    asmmoval,3;

    asmoutdx,al;

    asmmovdx,2fbh;

    asmmoval,03;

    asmoutdx,al;

    asmmovdx,2fch;

    asmmoval,0bh;

    asmoutdx,al;

    asmmovdx,2f9h;

    asmmoval,0fh;

    asmoutdx,al;

    asmmoval,20h;

    asmout21h,al;

    asmsti;

    }

    intTCommWin::InitCom()

    {

    charstr〔20〕,s〔2〕;

    intCOMid,err;

    DCBdcb;//設備控制塊

    UINTMask=EV_BREAK|EV_ERR|EV_RXFLAG;//事件掩碼

    strcpy(str,"COM");

    strcat(str,itoa(COM+1,s,10));

    COMid=OpenComm(str,128,1);

    if(COMid<0)returnCOMid;

    strcat(str,":300,n,8,1");

    err=BuildCommDCB(str,&dcb);

    dcb.EvtChar=-1;//事件字符0xff

    err=SetCommState(&dcb);

    SetBaud();

    if(err>0)returnerr;

    FlushComm(COMid,1);

    if(!EnableComunNotification(COMid,HWindow,10,-1))

    return-1;

    SetCommEventMask(COMid,Mask);

    returnCOMid;

    }

    voidTCommWin::SetupWindow()

    {

    TWindow::SetupWindow();

    InitCom();

    }

    BOOLTCommWin::WMCommNotify(TMessage&Mg)

    {

    UINTflag=0;

    intid;

    COMSTATstat;

    unsignedcharSendChar;

    staticunsignedchar

    *p=ReceiveBuff;

    staticnum=0;

    intret;

    id=Mg.WParam;

    switch(Mg.LP.Lo)

    {

    caseCN_EVENT://有事件掩碼中定義的事件發生

    flag=GetCommEventMask(id,EV_BREAK);

    if(flag&EV_BREAK)

    FlushComm(id,1);

    flag=GetCommEventMask(id,EV_RXFLAG);

    if(flag&EV_ERR)

    FlushComm(id,1);

    flag=GetCommEventMask(id,EV_RXFLAG);

    if(flag&EV_RXFLAG)//收到了事件字符0xff

    {

    SendChar=0x0f;

    WriteComm(id,&SendChar,1);//向對方回0x0f

    }

    break;

    caseCN_RECEIVE://接收到了規定個字符或超時

    do

    {

    ret=ReadComm(id,p,1);

    if(ret>0)

    {

    p++;

    num++;

    }

    }while((ret>0)&(num<10));

    if(num>=10)//接收完一條消息

    {

    num=0;

    //此處處理接收到的消息

    p=ReceiveBuff;

    SendChar=0x0f;

    WriteComm(id,&SendChar,1);//向對方回0x0f

    FlushComm(id,1);

    }break;

    }

    flag=GetCommError(id,&stat);//消除錯誤(若有)

    return1;

    }

    voidTCommApp::InitMainWindow()

    {

    MainWindow=newTCommWin(NULL,"Windows通信示例");

    }

    intPASCALWinMain(HINSTANCEhInstance,HINSTANCEhPrevI

    nstance,LPSTR1pCmdLine,

    intnCmdShow)

    {

    TCommAppCommApp("通信",hInstance,hPrevInstance,1pC

    mdLine,nCmdShow);

    CommApp.Run();

    returnCommApp.Status;}

    主站蜘蛛池模板: 中文国产日韩欧美二视频| 国产成人乱色伦区| 日本最大色倩网站www| 色综合色综合色综合频道| 免费人成视频在线观看网站| 国产高清精品自拍av| 日韩V欧美V中文在线| 国产女同一区二区在线| 亚洲欧美电影在线一区二区| 国产午夜亚洲精品一区| 亚洲一区二区三区国产精品 | 国产老肥熟一区二区三区| 免费高潮了好湿h视频| 99香蕉国产精品偷在线观看 | 黑人av无码一区| 四虎影视一区二区精品| 一本大道东京热无码| 99久久久国产精品免费无卡顿| 99久久久国产精品免费无卡顿| 久久精品国产亚洲αv忘忧草| 成在线人视频免费视频 | 一本久道久久综合中文字幕| 国产国产乱老熟女视频网站97 | 国产无套乱子伦精彩是白视频| 精品自拍偷拍一区二区三区| 亚洲中文字幕无码一区日日添 | 中国熟妇毛多多裸交视频| 日本xxxb孕交| 欧美巨大极度另类| 成人日韩av不卡在线观看| 99国产精品国产精品久久| 国产在线啪| 欧美亚洲h在线一区二区| 国产成人精品高清不卡在线| 久久精品亚洲精品国产色婷| 国产午夜福利小视频合集| 国产h视频免费观看| 欧美乱码伦视频免费| 四季av一区二区三区| 美国又粗又长久久性黄大片| 亚洲成A人片在线观看无码不卡|