淺陋見解,僅供參考。拋磚引玉,多加指教!
          石正
          一個計算機技術愛好者! 雖然我擁有了系統(tǒng)分析師的證書,但我仍然是一個計算機技術愛好者!
          posts - 119,comments - 73,trackbacks - 0

          C++ Builder 中利用串行通信控件編程


          轉發(fā)別人的文章,閱讀時可以使用IE的,查看--字體大小--最大;這樣可以看到大字體的文章。
          ?

          摘要:串口是常用的計算機與外部串行設備之間的數(shù)據(jù)傳輸通道,由于串行通信方便易行,所以應用廣泛。本文介紹了在 C++ Builder 中如何利用串行通信控件進行串行通信編程。

          ?

            一、引言
            目前,在用計算機進行數(shù)據(jù)傳輸時,常用的是串行通信方式。用 C ++ Builder 來編寫串行通信程序時,可以調(diào)用 Windows API 函數(shù),也可以利用 VB 中的 MSComm 控件。 利用 API 函數(shù)編寫實際應用程序時,往往要考慮多線程的問題,這樣編出來的程序不但十分龐大,而且結構比較復雜,繼承性差,維護困難。但是使用串行通信控件就相對簡單一些,而且功能強大,性能安全可靠。本文就簡單的介紹一下在 C++ Builder 中利用 MSComm 控件進行編程。

            二、 MSComm 控件的常用屬性和事件
             MSComm 控件通過串行端口傳輸和接收數(shù)據(jù),為應用程序提供串行通訊功能。具體的來說,它提供了兩種處理通信問題的方法:一是事件驅(qū)動 (Event driven) 方法,一是查詢法。

            事件驅(qū)動方式
            在使用事件驅(qū)動法設計程序時,每當有新字符到達,或端口狀態(tài)改變,或發(fā)生錯誤時, MSComm 控件將解發(fā) OnComm 事件,而應用程序在捕獲該事件后,通過檢查 MSComm 控件的 CommEvent 屬性可以獲知所發(fā)生的事件或錯誤,從而采取相應的操作。這種方法的優(yōu)點是程序響應及時,可靠性高。

            查詢方式
            查詢方式實質(zhì)上還是事件驅(qū)動,但在有些情況下,這種方式顯得更為便捷。在程序的每個關鍵功能之后,可以通過檢查 CommEvent 屬性的值來查詢事件和錯誤。如果應用程序較小,并且是自保持的,這種方法可能是更可取的。

             1.MSComm 控件的常用屬性
             CommPort 屬性:設置或返回通訊端口號,可以設置為 1 16 之間的任何值,本系統(tǒng)采用缺省值 2
             Settings 屬性:以字符串形式設置或返回波特率、奇偶校驗、數(shù)據(jù)位和停止位,本系統(tǒng)采用缺省值 "9600 n 8 1";
             PortOpen 屬性:設置或返回通訊口的狀態(tài)以及打開和關閉端口,可通過把該屬性設置為 true 或者 false 來打開或者關閉端口;
             InBufferSize OutBufferSize 屬性:分別設置接收和發(fā)送緩沖區(qū)分配的內(nèi)存數(shù)量,單位為字節(jié),缺省值分別為 1024byte 512byte
             InputLen 屬性:確定希望從接收緩沖區(qū)移出的字符數(shù)量,當 InputLen 0 時,一次把接收緩沖區(qū)的字符全部移出;
             Input 屬性:從接收緩沖區(qū)中讀出數(shù)據(jù),然后將該數(shù)據(jù)從緩沖區(qū)移走。
             OutPut 屬性:向發(fā)送緩沖區(qū)傳遞待發(fā)送的數(shù)據(jù)。
             InBufferCount OutBufferCount 屬性:分別確定當前駐留在接收緩沖區(qū)等待被取出和發(fā)送緩沖區(qū)準備發(fā)送的字符數(shù)量,這兩個屬性設置為 0 ,接收和發(fā)送緩沖區(qū)的內(nèi)容將被清除;
             InputMode 屬性:設置接收傳入數(shù)據(jù)的格式,設置為 0 采用文本形式,設置為 1 采用二進制格式,本系統(tǒng)設置為二進制格式進行發(fā)送和接收;
             SThreshold 屬性:保存一個產(chǎn)生發(fā)送 OnComm 事件的界限值,本系統(tǒng)設置該屬性為 0 ,發(fā)送數(shù)據(jù)時不產(chǎn)生 OnComm 事件;
             RThreshold 屬性:設定當接收幾個字符時觸發(fā) OnComm 事件,本系統(tǒng)設置該屬性為 1 ,每接收一個字符就產(chǎn)生一個 OnComm 事件;

             2 MSComm 控件的事件
          MSCOMM
          控件只使用一個事件 OnComm ,用屬性 CommEvent 的十七個值來區(qū)分不同的觸發(fā)時機。主要有以下幾個:
             (1)CommEvent=1 時:傳輸緩沖區(qū)中的字符個數(shù)已少于 Sthreshold( 可設置的屬性值 ) 個。
             (2)CommEvent=2 時:接收緩沖區(qū)中收到 Rthreshold( 可設置的屬性值 ) 個字符,利用此事件可編寫接收數(shù)據(jù)的過程。
             (3)CommEvent=3 時: CTS 線發(fā)生變化。
             (4)CommEvent=4 時: DSR 線發(fā)生變化。
             (5)CommEvent=5 時: CD 線發(fā)生變化。
             (6)CommEvent=6 時:檢測到振鈴信號。
            另外十種情況是通信錯誤時產(chǎn)生,即錯誤代碼。

          ?

           三、程序的實現(xiàn)

             1. 注冊 MSComm 控件
            眾所周知, C++Builder 本身并不提供串行通訊控件 MSComm ,但我們卻可以通過注冊后直接使用它。啟動 C++Builder5.0 后,然后選擇 C++Builder 主菜單中的 Component 菜單項,單擊 Import Active Control 命令,彈出 Import Active 窗口,選擇 Microsoft Comm Control6.0 ,再選擇 Install 按鈕執(zhí)行安裝命令 , 系統(tǒng)將自動進行編譯 , 編譯完成后即完成 MSComm 控件在 C++Builder 中的注冊 , 系統(tǒng)默認安裝在控件板的 Active , 接下來我們就可以像使用 C++Builder 本身提供的控件那樣使用新注冊的 MSComm 控件了。(前提條件是你的機子上安裝了 Visual Basic ,或者有它的庫)

             2. 具體實現(xiàn)
            新建一個工程 Project1 ,把注冊好的 MSComm 控件加入到窗體中,然后再加入 5 ComboBox 用來設置串口的屬性, 4 Button 分別用來 " 打開串口 " " 關閉串口 "" 發(fā)送數(shù)據(jù) "" 保存數(shù)據(jù) " 2 Memo 控件分別用來顯示接收到的數(shù)據(jù)和發(fā)送的數(shù)據(jù)。再加入一個 Shape 控件用來標明串口是否打開。
             ComboBox1 用來設置串口號,通過它的 Items 屬性設置 1 2 3 4 四個列表項分別表示 COM1,COM2,COM3,COM4 口。 ComboBox2 用來設置波特率, ComboBox3 用來設置奇偶校驗位, ComboBox4 用來設置數(shù)據(jù)位, ComboBox5 用來設置停止位。他們的缺省值分別是 9600 n 8 1
             Button1 用來打開串口, Button2 用來關閉串口, Button3 用來發(fā)送數(shù)據(jù), Button4 用來保存數(shù)據(jù)。 Memo1 用來顯示發(fā)送的數(shù)據(jù), Memo2 顯示接收的數(shù)據(jù)。 Shape1 Shape 屬性設置為 stCircle

          下面給出部分源碼:
          __fastcall TForm1::TForm1(TComponent* Owner)
          : TForm(Owner)
          {?
          ??????if(MSComm1->PortOpen==true)?
          ??????{?
          ????????????Button1->Enabled=false;?
          ????????????Button2->Enabled=true;?
          ????????????Button3->Enabled=true;?
          ????????????Button4->Enabled=true;?
          ????????????Shape1->Brush->Color=clGreen;
          ??????}
          ??????else
          ??????{?
          ????????????Button2->Enabled=true;?
          ????????????Button2->Enabled=false;?
          ????????????Button3->Enabled=false;?
          ????????????Button4->Enabled=false;?
          ????????????Shape1->Brush->Color=clRed;
          ??????}
          }

          void __fastcall TForm1::Button1Click(TObject *Sender) / /
          打開串口
          {?
          ??????if(MSComm1->PortOpen!=true)?
          ??????{?
          ????????????MSComm1->CommPort=StrToInt(ComboBox1->Text);//
          選擇串口號?
          ????????????MSComm1->Settings=?
          ??????????????????ComboBox2->Text+","+?
          ??????????????????ComboBox3->Text+","+?
          ??????????????????ComboBox4->Text+","+?
          ??????????????????ComboBox5->Text; file://
          設置串口的屬性波特率、奇偶校驗、數(shù)據(jù)位和、 // 停止位。?
          ????????????MSComm1->InputMode=0;//
          設置傳入數(shù)據(jù)的格式, 0 表示文本形式?
          ????????????MSComm1->PortOpen=true;//
          打開串口?
          ????????????Button1->Enabled=false;?
          ????????????Button2->Enabled=true;?
          ????????????Button3->Enabled=true;?
          ????????????Button4->Enabled=true;?
          ????????????Shape1->Brush->Color=clGreen;?
          ??????}
          }

          void __fastcall TForm1::Button2Click(TObject *Sender) / /
          關閉串口
          {?
          ??????if(MSComm1->PortOpen!=false)?
          ??????{?
          ????????????MSComm1->PortOpen=false;?
          ????????????Button1->Enabled=true;?
          ????????????Button2->Enabled=false;?
          ????????????Button3->Enabled=false;?
          ????????????Button4->Enabled=false;?
          ????????????Shape1->Brush->Color=clRed;?
          ??????}?
          ??????else?
          ??????{?
          ????????????Button1->Enabled=false;?
          ????????????Button2->Enabled=true;?
          ????????????Shape1->Brush->Color=clRed;?
          ??????}
          }

             MSComm 控件的 Input Output 屬性在 Object Inspector 中是看不到的,而且在 C++Builder 環(huán)境下這兩個屬性已不在是 VB VC 中的原類型,而是 OleVariant 類型,也就是 Ole 萬能變量,這就需要我們在發(fā)送接收數(shù)據(jù)時要把數(shù)據(jù)轉換成 Ole 類型。

          void __fastcall TForm1::Button3Click(TObject *Sender) file://
          發(fā)送 Memo2 中的數(shù)據(jù)
          {?
          ??????MSComm1->Output=StringToOleStr(Memo2->Text); file://
          AnsiString 型轉化成 //Ole 形式。
          }

            通過 OnComm 事件接收數(shù)據(jù),必須把 MSComm RThreshold 屬性設置為大于 0 ,只有這樣在接收到字符時才會產(chǎn)生一個 OnComm 事件。

          void __fastcall TForm1::MSComm1Comm(TObject *Sender)
          {?
          ??????AnsiString str; file://
          聲明一個 AnsiString 類型的變量?
          ??????OleVariant s; file://
          聲明一個用于接收數(shù)據(jù)的 OleVariant 變量。?
          ??????if(MSComm1->CommEvent==comEvReceive)?
          ??????//
          接收緩沖區(qū)中是否收到 Rthreshold 個字符。?
          ??????{?
          ????????????if(MSComm1->InBufferCount)//
          是否有字符駐留在接收緩沖區(qū)等待被取出?
          ????????????{?
          ??????????????????s=MSComm1->Input;//
          接收數(shù)據(jù)?
          ??????????????????str=s.AsType(varString); file://
          把接收到的 OleVariant 變量轉換成 AnsiString 類型?
          ??????????????????Memo1->Text=Memo1->Text+str;//
          把接收到的數(shù)據(jù)顯示在 Memo1 中。?
          ????????????}?
          ??????}
          }

            要保存數(shù)據(jù)應該再加入一個 SaveDialog 模塊

          void __fastcall TForm1::Button4Click(TObject *Sender)
          file://
          Memo1 中的數(shù)據(jù)保存在指定的文件中
          {?
          ??????AnsiString filename1;?
          ??????SaveDialog1->Filter="Text files (*.txt)|*.txt|All files (*.*)|*.*";//
          文件類型過濾器?
          ??????SaveDialog1->FilterIndex=2;?
          ??????if(SaveDialog1->Execute())?
          ??????{?
          ????????????filename1=SaveDialog1->FileName;?
          ????????????Memo1->Lines->SaveToFile(filename1);//
          把收到的數(shù)據(jù)保存在文件 filename1 ?
          ??????}
          }

            四、結束語

            上面給出了 C++ Builder 中利用 MSComm 控件進行串行通信編程的實現(xiàn)和部分源碼,有了上面的參照讀者可以根據(jù)實際需要編寫出具有發(fā)送文件和接收文件功能的程序。

          ?

          posted on 2006-07-05 16:22 石正 閱讀(1305) 評論(1)  編輯  收藏

          FeedBack:
          # re: 在 C++ Builder中利用串行通信控件編程
          2006-07-05 18:02 | 塵不落
          呵呵,你的兒子怎么樣了?記得給我發(fā)張照片.  回復  更多評論
            

          只有注冊用戶登錄后才能發(fā)表評論。


          網(wǎng)站導航:
           
          淺陋見解,僅供參考。拋磚引玉,多加指教!
          主站蜘蛛池模板: 彭阳县| 岚皋县| 贵溪市| 浑源县| 涞源县| 柞水县| 宁阳县| 平江县| 鲁甸县| 阿瓦提县| 广元市| 额敏县| 彰化县| 阿荣旗| 沛县| 怀来县| 沙湾县| 古蔺县| 民乐县| 从江县| 息烽县| 冕宁县| 邳州市| 南投市| 珠海市| 沭阳县| 班玛县| 泗水县| 博客| 周宁县| 长白| 东台市| 夏河县| 宁安市| 什邡市| 商都县| 常熟市| 方城县| 京山县| 四川省| 永寿县|