浅陋见解,仅供参考。抛砖引玉,多加指教!
石正
一个计算机技术爱好者! 虽然我拥有了系统分析师的证书,但我仍然是一个计算机技术爱好者!
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 石正 阅读(1298) 评论(1)  编辑  收藏

FeedBack:
# re: 在 C++ Builder中利用串行通信控件编程
2006-07-05 18:02 | 尘不落
呵呵,你的儿子怎么样了?记得给我发张照片.  回复  更多评论
  

只有注册用户登录后才能发表评论。


网站导航:
 
浅陋见解,仅供参考。抛砖引玉,多加指教!