<nobr id="zkazv"></nobr>

      午夜精品一区二区三区成人,中文字幕av一区二区,亚洲AVAV天堂AV在线网阿V,肥臀浪妇太爽了快点再快点,国产网友愉拍精品视频手机,国产精品无码a∨麻豆,久久中文字幕一区二区,a级国产乱理伦片在线观看al
      您現在所在的是:

      串口通信

      回帖:1個,閱讀:1712 [上一頁] [1] [下一頁]
      986
      ya5751
      文章數:4
      年度積分:50
      歷史總積分:986
      注冊時間:2006/8/5
      發站內信
      發表于:2008/11/25 22:21:00
      #0樓

      串口數據接收方式


      1、 在oncomm 事件中接收數據:


      這種方式能充分mscomm控件的特性。oncomm 事件還可以檢查和處理通訊錯誤;可以通過檢查 commevent 屬性的值來查詢事件和錯誤;對于不定長數據以及對數據進行處理比較復雜的情況,此法不是很方便。


      private sub mscomm_oncomm ()


      select case mscomm1.commevent


      錯誤


      case comeventbreak  收到 break。


      case comeventcdto  cd (rlsd) 超時。


      case comeventctsto  cts timeout。


      case comeventdsrto  dsr timeout。


      case comeventframe  framing error


      case comeventoverrun 數據丟失。


      case comeventrxover接收緩沖區溢出。


      case comeventrxparity parity 錯誤。


      case comeventtxfull 傳輸緩沖區已滿。


      case comeventdcb 獲取 dcb] 時意外錯誤


      事件


      case comevcd  cd 線狀態變化。


      case comevcts  cts 線狀態變化。


      case comevdsr  dsr 線狀態變化。


      case comevring  ring indicator 變化。


      case comevreceive  收到 rthreshold # of chars.


      case comevsend  傳輸緩沖區有 sthreshold 個字符


      case comeveof  輸入數據流中發現 eof 字符


      end select


      end sub


      2.輪循法采集數據:


      a、定時器輪循法


      對于數據包方式收發數據以及不需即時響應情況,用輪循法更好些。實際上輪循法最大的好處在于集中處理數據而且不太占用cpu。輪循法要注意定時采集的時間片段大小;這里用二進制收發模式;使屬性rthreshold、sthreshold為0,屏蔽oncomm事件。


      inputmode = cominputmodebinary


      rthreshold = 0


      sthreshold = 0


      private sub tmrcomm_timer()


      采用輪循法采集數據


      dim rx_buff() as byte


      dim okstring as string


      dim receivedlen as integer


      on error goto errorhandler


      tmrcomm.enabled = false 關閉定時器


      if commport.inbuffercount > 0 then


      receivedlen = commport.inbuffercount


      rx_buff = commport.input


      okstring = strconv(tempbyte, vbunicode)


      if receivedlen = 6 then


      if chr(tempbyte(0)) = : and tempbyte(3) = &h0a then


      ....


      end if


      if instr(okstring ,:@end*,vbbinarycompare) then


      ....


      end if


      end if


      tmrcomm.enabled = true 打開定時器


      end sub


      b、直接輪循法


      此法用于接收少量控制命令字;


      保存輸入子串的緩沖區


      dim instring as string


      使用 com1。


      mscomm1.commport = 1


      9600 波特,無奇偶校驗,8 位數據,一個停止位。


      mscomm1.settings = 9600,n,8,1


      當輸入占用時,


      告訴控件讀入整個緩沖區。


      mscomm1.inputlen = 0


      打開端口。


      mscomm1.portopen = true


      將 attention 命令送到調制解調器。


      mscomm1.output = atv1q0 & chr$(13)


      確保


      調制解調器以ok響應。


      等待數據返回到串行端口。


      do


      doevents


      buffer$ = buffer$ & mscomm1.input


      loop until instr(buffer$, ok & vbcrlf)


      從串行端口讀 ok 響應。


      關閉串行端口。


      mscomm1.portopen = false


      如何處理不定長數據的接收


      在處理串口通訊時,經常會遇到不定長數據的接收。由于通訊任務不同及編程要求的差異所以采用的方法也有所不同。本文就此問題進行探討。不定長數據從數據格式上分,可分為有格式和無格式。


      一、無格式不定長數據的接收


      這種格式在實際串口通訊中用得不多,一般只用傳送字符串數據。問題在于怎么判斷接收結束。一般用時間延遲的方法解決。


      a、對于非握手式通訊,可用一個定時器定時輪循接收,并假定每個輪循接收完成。用oncomm事件接收也可,只是不如定時器定時輪循接收簡便。


      b、對于握手方式通訊,可用直接輪循法提高接收的準確性。下面是實現此法的函數:


      function scomm(scommand as string, comreceive as mscomm) as string


      dim nreceivecount as integer


      if comreceive.portopen = false then


      comreceive.portopen = true


      end if


      comreceive.output = scommand


      do


      nreceivecount = comreceive.inbuffercount


      sleep (2) api 函數,掛起當前進程一段時間


      loop until comreceive.inbuffercount = nreceivecount


      if comreceive.portopen = true then


      scomm = comreceive.input


      end if


      end function


      注:此函數參照了xth一文。


      此法一般是能確保數據接收的正確,但由于windows是多任務操作系統,當有耗時的進程運行時會丟失數據。如果系統會出現這種情況,可增大函數sleep()的參數值。


      二、不定長格式數據的接收


      對于不定長數據接收最好的方法是制定通訊協議,比如定義開始字符和結束字符。由于單片機系統通訊一般不太復雜,沒必要去制定一套象通用計算機間通訊的協議,而根據單片機系統的大小和性能要求制定通訊協議。實際上為便于交流、維護以及一致性,可制定一套可伸縮的通訊協議。定義了開始字符和結束字符就容易實現不定長格式數據通訊,但在實際通訊編程還是容易出現一些比較隱蔽的通訊錯誤。下面就常用方法分別進行分析。


      a、定時器輪循法。


      假定每個輪循期數據接收完畢,并在每個輪循期處理數據,由于有開始字符和結束字符很容易確定接收數據的完整性。好象合理設定輪循時間值就萬無一失了,但被動接收數據時無論如何也找不合適的輪循時間值,因為啟動定時器和數據到來基本不同步,這就會出現一次發送的數據被分在兩個輪循期接收,所以被動接收數據時不能假定每個輪循期數據接收完畢。在接收到結束字符后才確定一次數據接收完畢就可解決此問題。


      b、oncomm事件法。


      方法和定時器輪循法基本相同,因為每次oncommg事件也只能接收到一部分數據。在vb的在線幫助中這樣注解“設置 rthreshold 為 1,接收緩沖區收到每一個字符都會使 mscomm 控件產生 oncomm 事件。”。但實際上oncomm事件并不是每收到一個字符便觸發一次 oncomm 事件。oncomm事件是在緩沖區收到幾個甚至幾十個字節數據后才被觸發的。版主認為這是windows多任務使操作系統不能實時響應造成的。如果要在每次oncomm事件接收一個字符似乎可設inputlen屬性為1,但實際行不通。vb在線幫助中“有該屬性在從輸出格式為定長數據的機器讀取數據時非常有用”的注解,好象在說對定長字符有效,但版主發現inputlen設為16,接收16個字符定長數據時卻被當作兩次接收了,一次12個,一次4個。建議在oncomm事件中接收數據要定義通訊協議并檢測數據的完整性。 對于不定長格式數據的接收程序員更喜歡定時器輪循法,也許oncomm事件不好控制吧。


      對于不定長數據的接收,最佳方法可能是在oncomm事件中啟動定時器輪循接收,并同時停止oncomm事件的觸發,接收完畢后或超時開啟oncomm事件。


      用字符方式收發碼值大于127的字符數據


      vb的通訊控件友好、功能強大,編程速度快是眾人皆知的。加上vb的易學、易用,快速開發等特點,數據通訊量不是很大時,在單片機通訊領域廣泛地使用vb開發pc上層通訊軟件。實際開發時會有不少問題,這里就用字符方式收發碼值大127的字符數據進行討論。


      在實際開發中經常遇到通訊只是用來發送一些控制字符命令和少量數據。在vb的中文在線幫助中有“若數據只用 ansi 字符集,則用 cominputmodetext”的表述。 ansi字符集是0-127這容易使人誤解為&h88也可用“inputmide=cominputmodetext”方式收發。我剛開始用vb編通訊模塊時就為此迷惑過,網上不少網友也時常問及這種問題。實際上在vb中0-127是可以正常收發的,大于127即&h7f的只有&h80和&hff能夠收發,其余ansi字符都被過濾為0。由于串口通訊是以字節收發的,數據如以cominputmodetext模式收發則非字符串數據會被過濾。在vb中用“inputmide = cominputmodebinary” 就可以解決這個問題,只是收發都必須用動態數組來完成。用cominputmodebinary模式編程稍有點復雜,調試也不直觀,對于初學者不易掌握。另外軟件完成后,在實際應用時會增加工程維護難度,因為對于二進制代碼不是易于理解的。比如下端機發送現場統計數據233,cominputmodebinary模式下串口監測到“:a &h233;,它代表a探針的溫度。一般串口監測軟件要么用ascii方式顯示,要么用二進制方式顯示。用ascii方式則不能看到&h233,而二進制方式則示不好理解,如果顯示58 65 233 59,我想沒有人喜歡這種方式(如果有更好的方式的話)。但如果顯示“:a 2 3 3 ;”不就解決問題了!用cominputmodetext方式就可完成任務了,只是多了一段數據分離程序。對于一般通訊要求這種方法不為是一種好方法。由于通訊任務是多種多樣的,有時候這種方法就有點力不從心了,如傳送較多的的數據時,這會顯著地增加通訊量,通訊變得復雜了,對于單片機系統就不太合適了;還有一些特殊要求,如數據包的識別符也不適此法,但能確定傳送數據碼值范圍也可用此法。下面介紹另一種方法,此法適用比較廣,傳送二進制數據通訊量增加也不大。


      這種方法實際上很簡單,實際運用中有不少采用此法。原理是一碼分為二碼。如設7e為臨界字符,對于7e則分為7e和0兩個ascii碼,依此類推,8f分為7e和11。接收合并時遇到7e則將7e和后一個ascii碼相加為下字符。下面給出c語言函數,vb轉換一下便可。


      由于c語言不能返回兩個參數,所以用數組指針。


      void filt(char code[],char c)


      {


      if(c==f)


      {


      if(code[0]>=0x7e)


      {


      code[1]=code[0]-0x7e;


      code[0]=0x7e;


      }


      else


      {


      code[1]=0xff; /*0xff作為標記code[1]不可能產生0xff*/


      }


      }


      else if(c==h)


      {


      if(code[0]!=0x7e)


      {


      code[1]=0xfe; /*轉換完成標記*/


      }


      else


      {


      if(code[1]==0xfe)


      {


      code[1]=0xff; /*接收下一個碼的標記*/


      }


      else


      {


      code[0]=code[0]+code[1];


      code[1]=0xfe;


      }


      }


      }


      發送時:


      char sendchar[2]; /*存儲發送的值*/


      ....


      sendchar[0]=c; /*c為待發ascii碼*/


      filt(sendchar,f);


      if(sendchar(1)==0xff)


      {


      ..... /*發送sendchar[0]*/


      }


      else


      {


      ...... /*發送sendchar[0],sendchar[1]*/


      }


      接收時:


      char receivechar[2]; /*存儲接收的值*/


      .....


      receivechar[0]=c0; /*c0接收的ascii碼*/


      filt(receivechar,h);


      if(receivechar[1]==0xff)


      {


      receivechar[1]=c1; /*c1為下一個*/


      filt(receivechar,h);


      }


      else if(receivechar[1]==0xfe)


      {


      ...... /*存儲轉換后的receivechar[0]*/


      }


      以上代碼僅提供一種思路,實際情況視編程需要而定。


      串口通訊問答錄


      1、q:各位vb高手:我有一個問題想請教一下。我從com口用bin方式接收到數據(一串漢字),存入一byte數組,但無法還原為一串漢字,我認為是ansi和unicode的轉換,請問如何轉換。


      例:字符串“我”,按bin方式接收成一byte數組,其值為“206,210”,如用“chr(206)+chr(210)”卻無法得到“我”,實際上“我”=chr(-12860)請問如何能實現byte數組(206,210)與字符串“我”之間的轉換?萬分感謝!!!


      jy


      1999.10


      a:經chr(206)+chr(210)轉換后實際上變成了兩個unicode字符,四個字節了。漢字的收發必須用binary方式。下面的程序能實現漢字收發。


      發:


      dim ytemp() as byte


      dim stemp as string


      stemp = 你好!


      ytemp = strconv(stemp, vbfromunicode)


      debug.print ubound(ytemp)


      mscomm1.output = ytemp


      收:


      private sub msctest_oncomm()


      中文收發


      dim ytemp() as byte


      dim stemp as string


      dim i as integer


      if msctest.inbuffercount > 0 then


      i = msctest.inbuffercount


      ytemp = msctest.input


      stemp = strconv(ytemp, vbunicode)


      txttest1.text = stemp


      end if


      end sub


      deson


      1999-10-16


      --------------------------------------------------------------------------------


      2、q:各位大俠,在下被兩個問題困擾多時,實在無法找到答案,請各位多多指教。


      1、在用mscomm控件設計通訊程序時,我始終無法將asc碼大于127的值發送出去,查閱了vb論壇以前的文章,按部就班也不行,部分 vb 程序如下,請指教:


      private sub okbtn_click()


      dim data() as byte


      dim temp as variant


      redim data(10)


      for i = 0 to 10


      data(i) = int(rnd()*256)


      next


      temp = data


      mscomm.output = temp


      end sub


      a:接收方式使用了文本方式,用二進制方式即可。

      ----------------------------------------------
      此篇文章從博客轉發
      原文地址: Http://blog.gkong.com/more.asp?id=69123&Name=yangyongxiang
      17578
      ahljj
      文章數:3386
      年度積分:50
      歷史總積分:17578
      注冊時間:2002/3/23
      發站內信
      發表于:2010/3/18 13:44:23
      #1樓
      再學習

      關于我們 | 聯系我們 | 廣告服務 | 本站動態 | 友情鏈接 | 法律聲明 | 非法和不良信息舉報

      工控網客服熱線:0755-86369299
      版權所有 工控網 Copyright©2025 Gkong.com, All Rights Reserved

      78.0005
      主站蜘蛛池模板: 亚洲自拍偷拍激情视频| 久草热久草热线频97精品| 丁香五月亚洲综合在线国内自拍 | 亚洲人妻系列中文字幕| 国产69精品久久久久99尤物 | 99在线精品视频观看免费| 亚洲av不卡电影在线网址最新| 色婷婷久久综合中文久久一本 | 久久精品国产99精品亚洲| 亚洲午夜av一区二区| 亚洲综合国产成人丁香五| 国产在线精品福利91香蕉| 国产又黄又爽又不遮挡视频| 日本欧美大码a在线观看| 精品国产一区二区三区大| 又爽又黄又无遮挡的激情视频| 2020国产欧洲精品网站| 国产不卡一区二区四区| 亚洲gay片在线gv网站| 亚洲精品一区二区区别| 四虎永久精品免费视频| 亚洲 一区二区 在线| 国精偷拍一区二区三区| 精品亚洲精品日韩精品| 骚虎三级在线免费播放| 日本中文字幕一区二区三| 亚洲一级片一区二区三区| 免费一区二三区三区蜜桃| 久久精品国产福利亚洲av| 亚洲精品综合久久国产二区| 国产在线视频不卡一区二区 | 中国美女a级毛片| 精品一区二区三区四区五区| 无码内射中文字幕岛国片| 永久免费av无码网站直播| 国产免费久久精品99reswag| 久久综合精品国产一区二区三区无| 樱花草在线社区www| 最近免费中文字幕mv在线视频3| 日韩成人一区二区三区在线观看| 亚洲人成电影在线天堂色|