串口通信方法

版权信息: 本文来自internet,转载这里供网络编程爱好者学习和研究使用,请尊重作者的劳动成果。未经授权而在商业上使用原作者的文章属侵权行为,后果由使用者自负,本人不承担任何法律责任 串口通信方法: (1)利用Windows API通信函数;(2)利用Visual C++的标准通信函数_inp、_inpw、_inpd、_outp、_outpw、_outpd等直接对串口进行操作;(3)通过Microsoft Visual C++的通信控件(MSComm);(4)利用第3方编写的通信类,比如MuMega Technologies公司提供的CSerail类。 采用微软MSComm控件编程: ON_EVENT(CModemConnetDlg, ID_COMMCTRL, 1, OnCommMscomm, VTS_NONE) MSComm控件什么时候触发消息函数? 通过 m_Comm.SetRThreshold(1); //为1表示有一个字符引发一个事件 只要串口接收到数据就触发OnCommMscomm消息函数。 MSComm 控件的 Modem 通讯 MSComm 控件通过串行端口(serial port)传送和接收数据,为应用程序提供了串行通讯功能。而且在可视化编程盛行的今天,可以很方便的在Visual Basic(VB)、Visual C++(VC)、Delphi等语言及开发平台中应用。 MSComm 是 Microsoft 公司为简化Windows下串行端口编程而提供的ActiveX控件,它提供了一系列标准通讯命令的使用接口,为应用程序提供了通过串行口收发数据的简洁方法。处理数据的方式有事件驱动(Event-driver)、查询法(Inquire)两种。 1. 事件驱动法 在使用事件驱动法设计程序时,每当有新字符到达、端口状态变化或发生错误时,MSComm控件将解发OnComm事件,而应用程序在捕获该事件后,通过检查MSComm控件的CommEvent属性可以获知所发生的事件或错误,从而采取相应的操作。这种方法的优点是程序响应及时,可靠性高。 2. 查询法 这种方法适合于较小的应用程序。在这种情况下,每当应用程序执行完某一串行口操作后,将不断检查MSComm控件的CommEvent属性以检查执行结果或者检查某一事件是否发生。例如,当程序向串行设备发送了某个命令后,可能只是在等待收到一个特定的响应字符串,而不是对收到的每一个字符都立刻响应并处理。 在VC中添加?MSComm控件非常简单。在打开的工程中,选择菜单Project->Add To Project->Component and Controls,在弹出的对话框“Component and Controls Gallery”中选中“Microsoft Communication Controls Version 6.0”,单击“Insert”按钮即可完成添加MSComm控件操作。 本工程应用采用事件驱动法,具体实现如下: 一. 串口信息配置 按上述方法完成在基于对话框的应用程序中添加MSComm控件操作并增加相应成员变量m_comm。在对话框模板上右键单击MSComm控件,选择Property菜单项,即可设置MSComm控件各项属性。在此调制解调器通讯的程序中,设置“Control”属性页中Handshaking项为“2-comRTS”,否则国内部分厂家modem不能正常通讯。其它接受缺省设置。 另外亦可通过修改对话框类的OnInitDialog()函数来设置控件的属性。具体参考MSDN中的关于Comm Control的详细说明。 if(m_comm.GetPortOpen()) { m_comm.SetPortOpen(FALSE); //设置串口配置信息前先要关闭串口 } m_comm.SetCommPort(1); //Com1串行口 m_comm.SetSettings("9600,n,8,1");//设置波特率为9600bps,无奇偶校验位,数据位8位,停止位1位 m_comm.SetInputMode(1); //设置数据通讯格式为二进制数组格式 m_comm.SetRThreshold(1); //设置为每次接到一个字节数据就触发OnComm事件 if(!m_comm.GetPortOpen()) { m_comm.SetPortOpen(TRUE); } m_comm.GetInput(); //清除串口输入缓冲区中残留数据 m_SendData="ATZ/r/n"; //调制解调器初始化 m_comm.SetOutput(COleVariant(m_SendData)); 二. 接收数据 添加接收数据函数,在对话框中双击Comm Control,接受默认函数,则对话框类的成员函数为OnCommMscomm(),添加代码如下: Sleep(500); //视各厂家modem而定。不加则数据接受不全 VARIANT m_input; char *str,*str1; int k,nEvent,i,len,m; CString str2; m_ReceiveData=""; nEvent=m_comm.GetCommEvent(); switch(nEvent) { case 2: //收到大于RTHresshold个字符 k=m_comm.GetInBufferCount(); //接收缓冲区的字符数目 if(k>0) { m_input=m_comm.GetInput(); str=(char*)(unsigned char*)m_input.parray->pvData; } ?i=0; str1=str; while(i  以上是在做工程之余写下的一点东西。VC我是初学者,有错误的地方,还请各位批评指正。例子在VC 6.0+Win2000下调试通过。Win98下测试数据接收不全。 (2)mscomm控件串口通讯 摘要:串口是常用的计算机与外部串行设备之间的数据传输通道,由于串行通信方便易行,所以应用广泛。本文介绍了在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控件进行串行通信编程的实现和部分源码,有了上面的参照读者可以根据实际需要编写出具有发送文件和接收文件功能的程序。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值