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

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


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

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

          ?

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

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

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

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

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

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

          ?

           三、程序的實現

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

             2. 具體實現
            新建一個工程 Project1 ,把注冊好的 MSComm 控件加入到窗體中,然后再加入 5 ComboBox 用來設置串口的屬性, 4 Button 分別用來 " 打開串口 " " 關閉串口 "" 發送數據 "" 保存數據 " 2 Memo 控件分別用來顯示接收到的數據和發送的數據。再加入一個 Shape 控件用來標明串口是否打開。
             ComboBox1 用來設置串口號,通過它的 Items 屬性設置 1 2 3 4 四個列表項分別表示 COM1,COM2,COM3,COM4 口。 ComboBox2 用來設置波特率, ComboBox3 用來設置奇偶校驗位, ComboBox4 用來設置數據位, ComboBox5 用來設置停止位。他們的缺省值分別是 9600 n 8 1
             Button1 用來打開串口, Button2 用來關閉串口, Button3 用來發送數據, Button4 用來保存數據。 Memo1 用來顯示發送的數據, Memo2 顯示接收的數據。 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://
          設置串口的屬性波特率、奇偶校驗、數據位和、 // 停止位。?
          ????????????MSComm1->InputMode=0;//
          設置傳入數據的格式, 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 環境下這兩個屬性已不在是 VB VC 中的原類型,而是 OleVariant 類型,也就是 Ole 萬能變量,這就需要我們在發送接收數據時要把數據轉換成 Ole 類型。

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

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

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

            要保存數據應該再加入一個 SaveDialog 模塊

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

            四、結束語

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

          ?

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

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

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


          網站導航:
           
          淺陋見解,僅供參考。拋磚引玉,多加指教!
          主站蜘蛛池模板: 吉安市| 孙吴县| 钟祥市| 建德市| 治多县| 万荣县| 鄂伦春自治旗| 彭泽县| 建始县| 河池市| 英山县| 项城市| 信丰县| 温宿县| 东莞市| 原平市| 德钦县| 宜宾县| 宁城县| 遂宁市| 尚义县| 桓台县| 南溪县| 尖扎县| 米泉市| 闽侯县| 南木林县| 泉州市| 浙江省| 海丰县| 望城县| 平远县| 洛宁县| 绿春县| 双流县| 溆浦县| 溧阳市| 安图县| 平定县| 宾川县| 五河县|