99精品久久这里只有精品,三上悠亚免费一区二区在线,91精品福利一区二区,爱a久久片,无国产精品白浆免费视,中文字幕欧美一区,爽妇网国产精品,国产一级做a爱免费观看,午夜一级在线,国产精品偷伦视频免费手机播放

    <del id="eyo20"><dfn id="eyo20"></dfn></del>
  • <small id="eyo20"><abbr id="eyo20"></abbr></small>
      <strike id="eyo20"><samp id="eyo20"></samp></strike>
    • 小議Windows通信編程思考

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

      小議Windows通信編程思考

      一、windows通信機(jī)制

      Windows與DOS編程的重要差別在于Windows程序是消息驅(qū)動(dòng)和設(shè)備統(tǒng)一管理。體現(xiàn)在通信方面,DOS中的寄存器直接讀寫、BIOS調(diào)用和通信中斷程序等編程方法都不能或不宜采用。Windows通過(guò)通信驅(qū)動(dòng)程序COMM.DRV與硬件接口,向程序員提供了多達(dá)17個(gè)標(biāo)準(zhǔn)函數(shù),功能強(qiáng)大,但也增加了理解和編程的難度。

      Windows3.1通信函數(shù)主要有:

      OpenComm

      打開一通信設(shè)備

      BuildCimmDCB將一設(shè)備定義字符串轉(zhuǎn)變?yōu)镈CB數(shù)據(jù)結(jié)構(gòu)

      EnableCommNotification使能或禁止傳送WM_COMMNOTIFY消

      SetCommState設(shè)置通信設(shè)備狀態(tài)

      SetCommEventMask設(shè)置通信事件掩碼

      ReadComm從通信設(shè)備讀字符

      WriteComm向通信設(shè)備寫字符

      FlushComm清除一發(fā)送或接收隊(duì)列

      GetCommEventMask返回通信事件掩碼

      GetCommState返回設(shè)備控制塊(DCB)

      GetCommError恢復(fù)通信設(shè)備狀態(tài)

      CloseComm關(guān)閉一通信設(shè)備

      DCB數(shù)據(jù)結(jié)構(gòu)、其它通信函數(shù)及各函數(shù)的具體用法請(qǐng)參見(jiàn)有關(guān)資料。

      一般Windows通信編程應(yīng)包括兩部分:設(shè)備初始化及WM_COMMNOTIF

      Y消息處理。

      設(shè)備初始化典型流程如圖1。

      圖1

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

      圖2

      對(duì)于大多數(shù)實(shí)際通信來(lái)說(shuō),可能只需要處理流程圖中的一部分。

      設(shè)備初始化及WM_COMMNOTIFY消息處理兩部分密切相關(guān)。所有類型WM_COMMNOTIFY消息的傳送都是因?yàn)樵诔跏蓟瘮?shù)中進(jìn)行了相應(yīng)的設(shè)置。

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

      二、Windows通信疑難探討

      現(xiàn)將筆者在實(shí)際編程中遇到的疑難和解決辦法描述如下,希望對(duì)遇到類似問(wèn)題的朋友有所啟發(fā)。

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

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

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

      最后的是采用"蒙混過(guò)關(guān)"的辦法解決問(wèn)題的:首先,以任一Windows支持的波特率(例如300bps)構(gòu)造通信參數(shù)字符串,調(diào)用BuildCommDCB產(chǎn)生DCB數(shù)據(jù)結(jié)構(gòu);然后調(diào)用SetCommState設(shè)置通信參數(shù);最后再調(diào)用自編函數(shù)直接修改串口通信寄存器的值。經(jīng)實(shí)驗(yàn),設(shè)置成功,且對(duì)Windows程序運(yùn)行無(wú)任何不良影響。

      2.接收數(shù)據(jù)為何"丟失"?

      通過(guò)設(shè)置EnableCommNotification函數(shù)中的cbWriteNotify參數(shù)(在發(fā)送WM_COMMNOTIFY消息之前,通信設(shè)備驅(qū)動(dòng)程序必須向應(yīng)用程序出入隊(duì)列中寫入的字節(jié)數(shù)),可以使系統(tǒng)每收到固定個(gè)字符發(fā)出一WM_COMMNOTIFY消息,這對(duì)于固定長(zhǎng)度消息型的通信是很方便的。但實(shí)際應(yīng)用時(shí)有時(shí)會(huì)發(fā)生接收數(shù)據(jù)"丟失"現(xiàn)象,即收到WM_COMMNOTIFY消息后從接收隊(duì)列讀出cbNotify個(gè)數(shù)據(jù)時(shí),發(fā)現(xiàn)只有前面部分?jǐn)?shù)據(jù)正確。

      經(jīng)檢查,"丟失"現(xiàn)象是由于接收數(shù)據(jù)超時(shí)引起的,當(dāng)通信對(duì)方時(shí)鐘頻率較低時(shí),規(guī)定時(shí)間內(nèi)收不到cbWriteNotify指定的數(shù)據(jù)量,即所謂"超時(shí)",Windows照樣向應(yīng)用程序發(fā)送帶CN_RECEIVE標(biāo)志的WM_COMMNOTI

      FY消息。然后,在應(yīng)用程序輸入隊(duì)列數(shù)據(jù)讀出之前,Windows不再發(fā)送該類消息。

      解決的方法是減小cbWriteNotify的設(shè)定值直到不再發(fā)生"超時(shí)"現(xiàn)象。

      發(fā)送數(shù)據(jù)時(shí)同樣應(yīng)正確設(shè)定cbOutQue值,以免產(chǎn)生"超時(shí)"現(xiàn)象。

      如果將cbWriteNotify或cbOutQue設(shè)為-1,則Windows不傳送帶CN_RECEIVE或CN_TRANSMIT標(biāo)志的WM_COMMNOTIFY消息。

      3.怎樣合理使用FlushComm與GetCommError函數(shù)?

      FlushComm函數(shù)的功能是清除指定設(shè)備接收或發(fā)送隊(duì)列。GetCommError函數(shù)的功能是返回指定設(shè)備最近錯(cuò)誤碼和當(dāng)前狀態(tài),更重要的是"解鎖"功能:當(dāng)出現(xiàn)通信錯(cuò)誤時(shí),Windows會(huì)鎖死通信端口直到調(diào)用GetCommError。

      調(diào)用FlushComm的時(shí)機(jī)很重要,如果通信端口發(fā)生錯(cuò)誤,不調(diào)用該函數(shù)就有可能會(huì)使接收隊(duì)列包含不期望的數(shù)據(jù);若隨便調(diào)用該函數(shù),也有可能造成尚未讀入或發(fā)出的數(shù)據(jù)丟失??傊?調(diào)用該函數(shù)要做到"心中有數(shù)"。

      為了合理調(diào)用FlushComm和GetCommError函數(shù),建議在事件掩碼中包含EV_ERR與EV_BREAK。

      4.Windows多串口通信

      Windows最多可支持四個(gè)串口的通信,但對(duì)于ISA總線的PC,由于其COM1與COM3、COM2與COM4分別共用IRQ3和IRQ4,所以只能同時(shí)使用兩個(gè)串口。MCA、EISA總線系統(tǒng)沒(méi)有此限制。

      如果需要使用的端口不止四個(gè),可以在PC護(hù)展槽中加插多用戶卡,如美國(guó)的Comtrol、臺(tái)灣的Moxa(摩莎)等,就可以支持幾個(gè)到幾十個(gè)串口,加上隨卡提供的Windows驅(qū)動(dòng)程序,就可以進(jìn)行多串口通信。具體用法請(qǐng)參閱擴(kuò)展卡說(shuō)明書。

      三、Windows通信實(shí)例

      實(shí)例的通信環(huán)境為:本方COMPAQ4/50微機(jī),安裝中文Windows3.2;對(duì)方為8031單片機(jī)。通信參數(shù)設(shè)置:波特率150bps,數(shù)據(jù)位8,停止位1,無(wú)校驗(yàn)。通信協(xié)議是:對(duì)方發(fā)FF,本方收到后回0F,對(duì)方收到0F后發(fā)一條十字節(jié)的消息,本方回0F,結(jié)束一次通信。

      編程環(huán)境為中文Windows3

      2、BorlandC++3.1OWL。

      #include<windows.h>

      #include<owl.h>

      #include<window.h>

      #include<string.h>

      intCOM=1;//串口號(hào)

      unsignedcharReceiveBuff〔11〕;//接收數(shù)據(jù)緩存

      _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();//設(shè)置Windows不支持的波特率

      virtualBOOLWMCommNotify(TMessage&Mg)=〔WM_FIRST+

      WM_COMMNOTIFY〕;

      virtualvoidSetupWindow();

      };

      //該函數(shù)設(shè)置串口2的波特率為150bps,若用Windows提//供的波特率通信,則無(wú)須該函數(shù)

      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;//設(shè)備控制塊

      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://有事件掩碼中定義的事件發(fā)生

      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);//向?qū)Ψ交?x0f

      }

      break;

      caseCN_RECEIVE://接收到了規(guī)定個(gè)字符或超時(shí)

      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);//向?qū)Ψ交?x0f

      FlushComm(id,1);

      }break;

      }

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

      return1;

      }

      voidTCommApp::InitMainWindow()

      {

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

      }

      intPASCALWinMain(HINSTANCEhInstance,HINSTANCEhPrevI

      nstance,LPSTR1pCmdLine,

      intnCmdShow)

      {

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

      mdLine,nCmdShow);

      CommApp.Run();

      returnCommApp.Status;}

      2021国产最新在线视频一区| 久久久久国产精品| 男人激烈吮乳吃奶视频免费| 国内精品大秀视频日韩精品| 亚洲粉嫩av一区二区黑人| 野花视频在线观看免费| 日本护士xxxx视频| 无码毛片aaa在线| 少妇高潮惨叫久久久久电影| 国产一区二区三区青青草| 无码国内精品久久人妻| 欧美老妇与禽交| 少妇av免费在线播放| 日本视频一区二区三区在线观看| 中文字幕av一区二区三区人妻少妇| 欧美日韩在线视频| 高潮迭起av乳颜射后入| 亚洲男人的天堂精品一区二区| 蜜臀aⅴ永久无码一区二区| 日本一区二区高清精品| 亚洲av日韩av卡二| 亚洲春色视频在线观看| 亚洲精品一区二区三区国产| 97成人精品视频在线| 国产免费av片无码永久免费| 四虎国产精品视频免费看| 日韩美女人妻一区二区三区| 久久久熟女一区二区三区| 亚洲乱码国产乱码精品精| 亚洲国产成人精品女人久久久 | 男女男生精精品视频网站| 国产精品亚洲第一区二区三区| 亚洲一线二线三线写真| 99精品视频69v精品视频免费| 久久无人码人妻一区二区三区| 少妇被猛烈进入到喷白浆| 亚洲av无码一区二区三区乱子伦| 就去吻亚洲精品欧美日韩在线| 日本大胆人体亚裔一区二区| 老熟妇乱子伦牲交视频| 少妇寂寞难耐被黑人中出|