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

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


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

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

          ?

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

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

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

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

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

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

          ?

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

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

             2. 具體實(shí)現(xiàn)
            新建一個(gè)工程 Project1 ,把注冊(cè)好的 MSComm 控件加入到窗體中,然后再加入 5 個(gè) ComboBox 用來(lái)設(shè)置串口的屬性, 4 個(gè) Button 分別用來(lái) " 打開(kāi)串口 " " 關(guān)閉串口 "" 發(fā)送數(shù)據(jù) "" 保存數(shù)據(jù) " 2 個(gè) Memo 控件分別用來(lái)顯示接收到的數(shù)據(jù)和發(fā)送的數(shù)據(jù)。再加入一個(gè) Shape 控件用來(lái)標(biāo)明串口是否打開(kāi)。
             ComboBox1 用來(lái)設(shè)置串口號(hào),通過(guò)它的 Items 屬性設(shè)置 1 2 3 4 四個(gè)列表項(xiàng)分別表示 COM1,COM2,COM3,COM4 口。 ComboBox2 用來(lái)設(shè)置波特率, ComboBox3 用來(lái)設(shè)置奇偶校驗(yàn)位, ComboBox4 用來(lái)設(shè)置數(shù)據(jù)位, ComboBox5 用來(lái)設(shè)置停止位。他們的缺省值分別是 9600 n 8 1
             Button1 用來(lái)打開(kāi)串口, Button2 用來(lái)關(guān)閉串口, Button3 用來(lái)發(fā)送數(shù)據(jù), Button4 用來(lái)保存數(shù)據(jù)。 Memo1 用來(lái)顯示發(fā)送的數(shù)據(jù), Memo2 顯示接收的數(shù)據(jù)。 Shape1 Shape 屬性設(shè)置為 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) / /
          打開(kāi)串口
          {?
          ??????if(MSComm1->PortOpen!=true)?
          ??????{?
          ????????????MSComm1->CommPort=StrToInt(ComboBox1->Text);//
          選擇串口號(hào)?
          ????????????MSComm1->Settings=?
          ??????????????????ComboBox2->Text+","+?
          ??????????????????ComboBox3->Text+","+?
          ??????????????????ComboBox4->Text+","+?
          ??????????????????ComboBox5->Text; file://
          設(shè)置串口的屬性波特率、奇偶校驗(yàn)、數(shù)據(jù)位和、 // 停止位。?
          ????????????MSComm1->InputMode=0;//
          設(shè)置傳入數(shù)據(jù)的格式, 0 表示文本形式?
          ????????????MSComm1->PortOpen=true;//
          打開(kāi)串口?
          ????????????Button1->Enabled=false;?
          ????????????Button2->Enabled=true;?
          ????????????Button3->Enabled=true;?
          ????????????Button4->Enabled=true;?
          ????????????Shape1->Brush->Color=clGreen;?
          ??????}
          }

          void __fastcall TForm1::Button2Click(TObject *Sender) / /
          關(guān)閉串口
          {?
          ??????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)境下這兩個(gè)屬性已不在是 VB VC 中的原類型,而是 OleVariant 類型,也就是 Ole 萬(wàn)能變量,這就需要我們?cè)诎l(fā)送接收數(shù)據(jù)時(shí)要把數(shù)據(jù)轉(zhuǎn)換成 Ole 類型。

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

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

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

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

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

            四、結(jié)束語(yǔ)

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

          ?

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

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

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


          網(wǎng)站導(dǎo)航:
           
          淺陋見(jiàn)解,僅供參考。拋磚引玉,多加指教!
          主站蜘蛛池模板: 会泽县| 洞口县| 社旗县| 大邑县| 宜章县| 灵丘县| 望城县| 安图县| 岳阳县| 柳州市| 健康| 东海县| 通城县| 石屏县| 尚义县| 蕉岭县| 钟山县| 双桥区| 北海市| 巨野县| 介休市| 赞皇县| 蒲城县| 通许县| 宁乡县| 宣化县| 仲巴县| 嘉禾县| 宁晋县| 小金县| 塔河县| 泸州市| 东丽区| 高唐县| 永宁县| 军事| 丹阳市| 来宾市| 大渡口区| 略阳县| 海城市|