CBuilder中使用MSCOMM进行串口编程
mscomm控件的使用和安装
一、引言目前,在用计算机进行数据传输时,常用的是串行通信方式。
用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属性:从接收缓冲区中读出数据,然后将该数据从缓冲区移走。
Delphi的MSCOMM实现上位机与PLC间的串行通信
一上位机与PLC间的串行通信随着现代信息技术的发展以及计算机网络的广泛应用,计算机通信技术已经日趋成熟。
作为传统的计算机通信方式的串行通信,由于具有线路简单、应用灵活、可靠性高等一系列优点长期以来获得了广泛的应用。
计算机串行通信在数据财经、数据通信、故障检测、计算机远程监控等方面有广泛的实用价值,特别在Windows下的串口通信可以充分利用Windows下的软件资源优势,实现多任务条件下对外部的数据传输、信息收集和处理。
在本系统中,我们采用了性能/价格比较高的计算机构成厂级的监控工作站。
在PLC与上位计算机之间采用RS-485和RS-232C标准通信接口进行通信。
在两级计算机控制系统中,最不稳定的环节就是上位机。
为了保证系统的稳定性,避免因上位机的故障导致系统控制失灵,所有采集到的信号都反馈到PLC当中。
上位机需要通过串行通信取得所需的数据信息,并通过串行通信将必要的控制信息和参数设置信息写入PLC的数据存储区。
因此,串行通信作为上位机和下位机联系的唯一方式,在整个系统中具有非常重要的作用。
1.1上位机与PLC间的串行通信计算机与计算机或计算机与外部设备之间的数据传输和交换的方式主要有串行通信和并行通信两种方式,其中串行通信指的是数据逐位传输的方式。
由于串行通信方式具有使用线路少、成本低,特别是在远程传输时,避免了多条线路特性的不一致而被广泛采用。
1.1.1串行通信串行通信方式又可分为两种:同步串行通信方式和异步串行通信方式。
1.同步串行通信方式:同步串行通信是以数据块(字符块)为信息单位传送,每帧信息可以包含很多字符。
同步通信要求通信双方以相同的速率进行,而且要准证确协调,通常通过共享一个时钟或定时脉冲源保发送方和接收方准确同步。
这种通信方式的效率较高,但是对时钟同步要求非常严格,成本较高。
2.异步串行通信方式:异步串行通信以字符为信息单位传送。
双方需要遵守异步通信协议,以字符为数据单位,发送方传送字符的时间间隔不确定。
C_builder5中基于MSComm控件串口通信的编程与实现
收稿日期:2001-09-17作者简介:罗日成(1970-),男,湖南隆回人,硕士,长沙电力学院讲师,主要从事遗传算法及控制软件方面的设计开发。
C ++builder5中基于MSC omm 控件串口通信的编程与实现罗日成,李卫国(长沙电力学院电力系,湖南长沙 410077)摘 要:由于串行接口具有连接简单、使用方便、数据传递可靠等优点,在工业实时控制系统中得到了广泛应用。
本文探讨了基于Windows98平台上利用Micros oft C ommunications C ontrol 控件编写串行通信程序的方法,并结合开发实践,阐述了用C ++builder5语言实现了基于ActiveX 技术的串行通信编程的一般步骤。
实践表明,该方法简单、可靠,从而大大缩短实时控制软件的开发周期,减少程序员的工作量。
关 键 词:串行通信;Windows98;C ++builder5;ActiveX 控件;数据采集中图分类号:TP319; 文献标识码:A 文章编号:1001-4551(2002)01-0024-04The Programming and R ealization of Serial Communicationin C ++builder 5B ased MSComm ControlLUO Ri 2cheng ,LI Wei 2guo(Department o f Electr.Power Eng.,Changsha Univer sity o f Electr.Power.,Changsha 410077)Abstract :Serial inter face possesses the g ood qualities of connecting sim ply ,using conveniently and data trans fering credibly ,s o it has gained abroad appliance in real 2time control system.In this paper ,the method of serial communication ’s programming with M icros oft C ommunication C ontrol in the Windows 98platform is discussed ,the approach of serial communication ’s programming which is based on the technique of ActiveX in C ++Builder5.0is expatiated.The method is sim pleness and credibility.I t can shorten programming period greatly and reduce the w ork of the programmer.K ey w ords :serial communication ;Windows98;C ++Builder5;ActiveX control ;data collection1 引 言目前,计算机的串行通信应用十分广泛,串行接口已成为计算机的必需部件和接口之一。
在C++ Builder中利用串行通信控件编程
在C++ Builder中利用串行通信控件编程摘要:串口是常用的计算机与外部串行设备之间的数据传输通道,由于串行通信方便易行,所以应用广泛。
本文介绍了在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属性:从接收缓冲区中读出数据,然后将该数据从缓冲区移走。
vc 使用mscomm控件实现串口通讯
vc 使用mscomm控件实现串口通讯2009-07-07 08:34mscomm控件是微软发布的串口通讯控件,可以被多种开发工具使用,本章简单介绍vc环境下该控件的使用情况.1、控件的装载。
新建一个mfc工程,选择project-add to project-components and controls打开components and controls gallery对话框,双击 registered actives controls ,做出如下图的选择:点插入按钮后,就可把把该控件安装到controls面板上,同时创建串口类,我们从controls面板上把该控件添加到应用程序对话框就可以使用该控件设计通讯程序了。
2、初始化并打开串口。
m_ctrlComm.SetCommPort(1); //选择串口1if(!m_ctrlComm.GetPortOpen())//如果串口没有打开,则打开串口m_ctrlComm.SetPortOpen(TRUE);m_ctrlComm.SetSettings("38400,n,8,1");//波特率38400,无校验,8个数据位,1个停止位m_ctrlComm.SetInputMode(1);//以二进制方法检取数据m_ctrlComm.SetRThreshold(1);//参数为1表示当串口接收缓冲区有多于或等于1个字符时,将出发一个//接收数据的OnComm事件m_ctrlComm.SetInputLen(0);//设置当前接收缓冲区的数据长度为0m_ctrlComm.GetInput();//先预读缓冲区以清除残留数据3、串口关闭。
m_ctrlComm.SetPortOpen(FALSE);4、数据发送strSendFrame = "10 40 01 41 16 ";CStringToCByteArray(strSendFrame,cbaSendBuf);//转换为字节流cbaLastSendFrameBuf.Copy(cbaSendBuf);ucLastSendCtlCode = cbaSendBuf[1];pView->m_ctrlComm.SetOutput((COleVariant)cbaSendBuf);//串口发送5、数据接收响应mscomm控件的oncomm事件处理接收到的数据。
C++Builder中串口通讯的经验之谈
C++Builder中串⼝通讯的经验之谈 经验。
(串⼝部分),相信不少的⼈都知道在VB中有⼀个控件MSComm(图标是⼀个⼩黄电话),它可以帮你完成普通的串⼝传输功能(⽐如字符串什么的,但有的却实现起来⽐较烦琐), 在BCB中要⽤VB的控件,我想很多⼈都知道怎么办,在菜单中点Component——>Import ActiveX Control在打开的框中找到你想要的Microsoft Comm Control6.0然后直接安装就可以了,注意,前提是你必须要装了VB或者有它的库,否则你可找不到的然后你就可以在组件板的Activex中看到⼀个⼩黄电话的图标了。
它是不可见的控件,它有不少属性,不过我认为最关键的⼏个属性就是 CommPort---设置或返回通讯端⼝号。
Settings---以字符串形式设置或返回波特率、奇偶校验、数据位和停⽌位。
PortOpen---设置或返回通讯端⼝的状态,以及打开和关闭端⼝(BOOL型)。
Input---从接收缓冲区返回和删除字符。
Output---向缓冲区写⼀个字符串。
这五个属性就可以帮你完成简单的串⼝传送接收(当然,你要保证你的传、收的可靠性,你还需要借助其他的属性,这些属性可以在VB中得到)下边我将介绍⼀下怎么来⽤这个控件,以及在程序中怎么组织程序。
⾸先,你要建⽴⼀个新的⼯程,然后把MSComm控件放到窗体上,别忘了再放⼀个Button控件(Name属性就是Button1)。
好了,双击Button1,得到如下:(请注意:本例的⼯程⽂件为Project1.bpr窗体⽂件为Unit.cpp头⽂件为Unit.h)#include <vcl.h>#pragma hdrstop#include "Unit1.h"//---------------------------------------------------------------------------#pragma package(smart_init)#pragma resource "*.dfm"TForm1 *Form1;AnsiString buff[10]; //****************************声明了⼀个缓冲,请注意,⼀定要设置为全局变量//---------------------------------------------------------------------------__fastcall TForm1::TForm1(TComponent* Owner): TForm(Owner){}//---------------------------------------------------------------------------void __fastcall TForm1::Button1Click(TObject *Sender) 在此加⼊程序代码{ MSComm1->CommPort=1; MSComm1->Settings="9600,N,8,1"; MSComm1->PortOpen=true; for(int i=0;i<=9;i++) { buff[i]=i; MSComm1->Output=buff[i]; } MSComm1->PortOpen=false;}//---------------------------------------------------------------------------运⾏此程序,当你点击按钮后,会发送数据(你可以在⽹上下载⼀个测试串⼝通讯的软件)下⾯,我来解释⼀下上边的程序: MSComm1->CommPort=1;这句程序是⽤来确定你将⽤哪⼀个串⼝实⾏你的通讯传输,我在这⾥选择是串⼝1(你也可以选择串⼝2,不过如果串⼝2不能⽤的话,系统会给你提⽰) MSComm1->Settings="9600,N,8,1";这句程序是⽤来设置污七杂⼋的东东的,我在程序中设置的波特率为9600,N为⽆奇偶校验,数据位为8,停⽌位为1。
MFC下的MSCOMM控件用于串口通信的几个例子
MFC下的MSCOMM控件用于串口通信的几个例子MFC下的MSCOMM控件用于串口通信的几个例子VC基于MSCOMM控件串口通讯(转)/hanhaitianyu/blog/item/0c4cc0ef5d344 ef7b3fb9526.html在mfc中进行串口通讯最简单的方法莫过于在对话框中使用MSCOMM控件了,MSComm通信控件提供了一系列标准通信命令的接口,它允许建立串口连接,可以连接到其他通信设备(如Modem).还可以发送命令、进行数据交换以及监视和响应在通信过程中可能发生的各种错误和事件,从而可以用它创建全双工、事件驱动的、高效实用的通信程序。
一、用MSComm控件通信1.串口通信基础知识一般悦来,计算机都有一个或多个串行端口,它们依次为com1、Com2、…,这些串口还提供了外部设备与pC进行数据传输和通信的通道。
这些串口在CPU和外设之间充当解释器的角色。
当字符数据从CPU发送给外设时,这些字符数据将被转换成串行比特流数据;当接收数据时,比特流数据被转换为字符数据传递给CPU,再进一步说,在操作系统方面,Windows用通信驱动程序(COMM.DRV)调用API函数发送和接收数据,当用通信控件或声明调用API函数时,它门由COMM. DRV解释并传递给设备驱动程序,作为一个程序员,要编写通信程序.只需知道通信控件提供给Windows通信AP1函数的接口即可.换句话说,只需设定和监视通信控件的属性和事件即可。
2.使用Mscomm控件在开始使用MSComm控件之前。
需要先了解其属性、事件或错误属性描述CommPort 设置或返回通信端口号Settings 以字符串的形式设置或返回波特率、奇偶校验、数据位和停止位PortOpen 设置或返回通信端口的状态。
也可以打开和关闭端口Input 返回和删除接收缓冲区中的字符Output 将字符串写入发送缓冲区CommEvent属性为通信事件或错误返回下列值之一。
C++Builder5.0使用MSComm控件进行串行通讯的开发
C++Builder5.0使用MSComm控件进行串行通讯的开发王庆元;林辉
【期刊名称】《智能计算机与应用》
【年(卷),期】2002(000)006
【摘要】介绍了通过向C++Builder环境中添加MSComm控件,实现计算机与单片机之间的串行通讯的方法,并结合防污闪监测系统给出了程序实例.
【总页数】2页(P23-24)
【作者】王庆元;林辉
【作者单位】西北工业大学自动控制系;西北工业大学自动控制系
【正文语种】中文
【中图分类】TP311
【相关文献】
1.MSComm控件实现PC与PLC串行通讯 [J], 杨久红;王小增
2.VB中如何利用MSComm控件实现串行通讯 [J], 张晓红;闫东升
3.利用Visual C++6.0的MSComm控件实现计算机与变频器的串行通讯 [J], 杨玲
4.应用MSComm控件实现计算机与PLC间的串行通讯 [J], 赵晴
5.基于MSComm控件的数字万用表与计算机串行通讯设计及实现 [J], 陈格
因版权原因,仅展示原文概要,查看原文内容请购买。
用C#使用MSComm控件进行串口编程
用C#使用MSComm控件进行串口编程对于从事工控和单片机工作的人来说串口编程是很常用的和很重要的。
事实上在和C#中对串口的操作和VS6里没有大的区别。
你仍然可以直接调用API或者使用MSComm或其他第三方控件。
这里只介绍大家常用的MSComm。
例子使用2、3脚跳过线的串口将COM1和COM2连接。
首先,你必须有MSComm.ocx文件在你的Windows的System32目录下,而且它必须正确的注册。
你可以装VS6来获得,微软也指出这样不会有冲突。
当然我们可以自己注册而不用装庞大的VS6。
先将MSComm.ocx复制到System32目录下,然后使用edit 工具编辑一个以.reg扩展名的文件,在文件里输入以下的文字REGEDITHKEY_CLASSES_ROOTLicenses = Licensing: Copying the keys may be a violation of established copyrights.// The MsComm32 Control License follows:HKEY_CLASSES_ROOTLicenses4250E830-6AC2-11cf-8ADB-00AA00C00905 = kjljvjjjoquqmjjjvpqqkqmqykypoqjquoun 然后,存盘。
双击文件就完成了注册。
现在,我们介绍一下MSComm在和C#中和VS6里的不同和实际的应用。
在或C#中建立一个窗口Form1。
加入两个MSComm控件,你会发现这里MSComm的默认名字是axMSComm,有点奇怪吧。
同时因为命名空间的问题你不能给axMSComm1.InputMode赋0或1这样的值。
你只能这样来做如axMSComm1.InputMode=MSCommLib.InputModeConstants.co mInputModeBinary或者axMSComm1.InputMode=MSCommLib.InputModeConstants.co mInputModeText。
MSComm控件的应用(串口编程)
MSComm控件的应用(串口编程)MSComm控件通过串行端口发送和接收数据,为应用程序提供了串行通讯功能。
在基于对话框的应用程序中加入一个MSComm控件非常简单。
只需打开“Project->AddToProject->Components and Controls->Registered Activex Controls”,然后选择控件:Microsoft Communication Control,version 6.0插入到当前的工程中。
CMS m类的相关文件 mscomm.cpp 和 mscomm.h 就加到工程中了。
从工具箱中把MSComm控件拖到对话框上,给控件关联成员变量m_Comm。
1.初始化串口,一般在OnInitDialog()函数中m_Comm.SetCommPort(1); //选择COM1m_Comm.SetInputMode(1); //设置数据通讯格式为二进制数组格式0.为文本格式//1.为二进制数组格式m_Comm.SetSettings("9600,n,8,1");//设置波特率为9600bps,无奇偶校验位,数据位8//位,停止位1位m_Comm.SetRThreshold(1); //设置为每次接到一个字节数据就触发OnComm事件m_Comm.SetInputLen(0);//设置当前接收区数据长度为0,表示全部读取波特率:110、300、600、1200、2400、4800、9600、14400、19200、28800、38400、115200 奇偶校验:E偶校验、M标号校验、N无校验、O奇校验、S空格校验数据位:4、5、6、7、8停止位:1、1.5、22.打开串口if(!m_Comm.GetPortOpen()) //如果串口是关闭的,则行打开串口{m_Comm.SetPortOpen(true);m_Comm.GetInput(); //清除串口输入缓冲区中残留数据}else{AfxMessageBox("串口打开失败!");}3.关闭串口if(m_Comm.GetPortOpen()){m_Comm.SetPortOpen(false);}4.接受数据,OnComm()函数中,数据保存在RcvData中VARIANT m_input;char *str;int len,nEvent;CString RcvData;nEvent = m_Comm.GetCommEvent();switch(nEvent){case 2:len=m_Comm.GetInBufferCount(); //接收缓冲区的字符数目if(len>0){m_input=m_Comm.GetInput();str=(char*)(unsigned char*)m_input.parray->pvData;}*(str+len) = '\0’;RcvData.Format("%s", str);}5.发送数据,把str数据发送出去int i,Count;Count=str.GetLength();CByteArray m_Array;m_Array.RemoveAll();m_Array.SetSize(Count);for(i=0;i<Count;i++){m_Array.SetAt(i,str[i]);}m_Comm.SetOutput(COleVariant(m_Array));。
VC++下用MSComm控件实现串口通讯
VC++下用MSComm控件实现串口通讯首先,在对话框中创建通信控件,若Control工具栏中缺少该控件,可通过菜单Project --> Add to Project --> Components and Control插入即可,再将该控件从工具箱中拉到对话框中。
此时,你只需要关心控件提供的对Windows 通讯驱动程序的API 函数的接口。
换句话说,只需要设置和监视MSComm控件的属性和事件。
打开所需串口后,需要考虑串口通信的时机。
在接收或发送数据过程中,可能需要监视并响应一些事件和错误,所以事件驱动是处理串行端口交互作用的一种非常有效的方法。
使用OnComm 事件和CommEvent 属性捕捉并检查通讯事件和错误的值。
发生通讯事件或错误时,将触发OnComm 事件,CommEvent 属性的值将被改变,应用程序检查CommEvent 属性值并作出相应的反应// 若是在SDI中使用该控件则要调用下两句,在对话框程序中该语句有MFC自己创建// 所以不用人为添加DWORD style=WS_VISIBLE;m_MSComm.Create(NULL,style,CRect(0,0,0,0),this,IDC_MSCOMM1);// 串口控件的初始化DWORD style=WS_VISIBLE;m_MSComm.Create(NULL,style,CRect(0,0,0,0),this,IDC_MSCOMM1);if(m_MSComm.GetPortOpen()) //如果串口是打开的,则行关闭串口{m_MSComm.SetPortOpen(FALSE);}m_MSComm.SetCommPort(1); //选择COM1m_MSComm.SetInBufferSize(1024); //接收缓冲区m_MSComm.SetOutBufferSize(1024);//发送缓冲区m_MSComm.SetInputLen(0);//设置当前接收区数据长度为0,表示全部读取m_MSComm.SetInputMode(1);//以二进制方式读写数据m_MSComm.SetRThreshold(1);//接收缓冲区有1个及1个以上字符时,将引发接收数据的OnComm事件m_MSComm.SetSettings("9600,n,8,1");//波特率9600无检验位,8个数据位,1个停止位if(!m_MSComm.GetPortOpen())//如果串口没有打开则打开m_MSComm.SetPortOpen(TRUE);//打开串口elsem_MSComm.SetOutBufferCount(0);// 控件事件的响应声明// *.h//{{AFX_MSG(CGolfView)afx_msg BOOL OnComm();DECLARE_EVENTSINK_MAP()//}}AFX_MSG// *.cppBEGIN_EVENTSINK_MAP(CGolfView, CView)//{{AFX_EVENTSINK_MAP(CAboutDlg)ON_EVENT(CGolfView, IDC_MSCOMM1, 1 /* OnComm */, OnComm, VTS_NONE) //}}AFX_EVENTSINK_MAPEND_EVENTSINK_MAP()// 控件事件的响应BOOL CGolfView::OnComm(){VARIANT variant_inp;COleSafeArray safearray_inp;LONG len,k;BYTE rxdata[2048]; //设置BYTE数组An 8-bit integerthat is not signed.CString strtemp;switch(m_MSComm.GetCommEvent()){case 1: // comEvSend发送数据break;case 2: // comEvReceive读取数据// MessageBox(_T("读取数据事件"), _T("TRACE"), MB_OK);variant_inp=m_MSComm.GetInput(); //读缓冲区safearray_inp=variant_inp; //VARIANT型变量转换为ColeSafeArray型变量len=safearray_inp.GetOneDimSize(); //得到有效数据长度// 接受数据for(k=0; k<len; k++){safearray_inp.GetElement(&k,rxdata+k); //转换为BYTE型数组BYTE bt=*(char*)(rxdata+k); //字符型strtemp.Format("%c",bt); //将字符送入临时变量strtemp存放recd+=strtemp;}// UpdateData(TRUE);break;default: // 传输事件出错m_MSComm.SetOutBufferCount(0);break;}UpdateData(FALSE); //更新图象内容return TRUE;}核心代码初始化函数BOOL CSCommTestDlg::OnInitDialog(){CDialog::OnInitDialog();// Add "About..." menu item to system menu. made by lzycsd// IDM_ABOUTBOX must be in the system command range.ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);ASSERT(IDM_ABOUTBOX < 0xF000);CMenu* pSysMenu = GetSystemMenu(FALSE);if (pSysMenu != NULL){CString strAboutMenu;strAboutMenu.LoadString(IDS_ABOUTBOX);if (!strAboutMenu.IsEmpty()){pSysMenu->AppendMenu(MF_SEPARATOR);pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTB OX, strAboutMenu); }}// Set the icon for this dialog. The framework does this automatically// when the application's main window is not a dialogSetIcon(m_hIcon, TRUE); // Set big iconSetIcon(m_hIcon, FALSE); // Set small icon// TODO: Add extra initialization here////////////////////////////////////////////////////其他初始化m_ctrlComboComPort.SetCurSel(0); //初始选择串口1m_ctrlComboBaudRate.SetCurSel(6); //初始选择波特率9600m_ctrlComboParityBit.SetCurSel(0); //初始选择校验位无m_ctrlComboDataBit.SetCurSel(3); //初始选择数据位8位m_ctrlComboStopBit.SetCurSel(0); //初始选择停止位1位m_strSendPeriod="1000"; //初始自动发送周期为1000毫秒UpdateData(FALSE); //修改编辑框内容//GetDlgItem(IDC_EDIT_SENDPERIOD)->SetWindowText("1000");另一种方法设置////其他初始化//////////////////////////////////////////////////串口初始化m_ctrlComm.SetCommPort(m_ctrlComboComPort.GetCurSel()+1); //选择COM1//波特率9600,无校验,8个数据位,1个停止位m_ctrlComm.SetInputMode(1); //输入方式为二进制方式m_ctrlComm.SetInBufferSize(1024); //设置输入缓冲区大小m_ctrlComm.SetOutBufferSize(512); //设置输出缓冲区大小//波特率9600,无校验,8个数据位,1个停止位m_ctrlComm.SetSettings("9600,N,8,1");if(!m_ctrlComm.GetPortOpen())// {m_ctrlComm.SetPortOpen(TRUE); //打开串口SetPortOpen函数返回值为void// m_ctrlOpenCom.EnableWindow(FALSE); //使按钮变灰//if (!m_ctrlComm.GetPortOpen())// 如果串口已经打开(打开串口失败),会走到这里来,加上你的判断就可以了……// AfxMessageBox("没有发现此串口或被其他程序占用");//m_ctrlCloseCom.EnableWindow(FALSE); //打开串口失败// m_ctrlOpenCom.EnableWindow(TRUE);// }// else// {// m_ctrlOpenCom.EnableWindow(FALSE);// }m_ctrlComm.SetRThreshold(1); //参数1表示每当串口接受缓冲区中有多于或等于1个字符时将引发一个接受数据的OnComm事件m_ctrlComm.SetInputLen(0); //设置当前接受区数据长度为0m_ctrlComm.GetInput(); //先预读缓冲区以清除残留数据m_bSerialPortOpened=TRUE; //串口成功打开m_ctrlOpenCom.EnableWindow(!m_bSerialPortOpened); //打开串口按钮失效m_ctrlCloseCom.EnableWindow(m_bSerialPortOpened); //关闭串口按钮有效return TRUE; // return TRUE unless you set the focus to a control}从串口接受数据并显示在接受编辑框中static long rxdatacount=0; //接受字符计数void CSCommTestDlg::OnComm(){// TODO: Add your control notification handler code hereVARIANT variant_inp;COleSafeArray safearray_inp;LONG len,k;BYTE rxdata[2048]; //设置BYTE数组CString strtemp;if(m_ctrlComm.GetCommEvent()==2) //事件值为2表示接受缓冲区内有字符{variant_inp=m_ctrlComm.GetInput(); //读缓冲区safearray_inp=variant_inp; //VARIANT型变量转换为ColeSafeArray型变量len=safearray_inp.GetOneDimSize(); //得到有效数据长度for(k=0;k<len;k++)safearray_inp.GetElement(&k,rxdata+k); //转换为BYTE型数组for(k=0;k<len;k++) //将数组转换为Cstring型变量{BYTE bt=*(char*)(rxdata+k); //字符型strtemp.Format("%c",bt); //将字符送入临时变量strtemp存放m_strEditRXData+=strtemp; //加入接受编辑框对应字符串//////////////////////////////////////////////////////放在这里计数会卡//rxdatacount++; //接受的字节计数//CString temp;//temp.Format("%ld",rxdatacount);//temp="接受:"+temp;//m_ctrlRXCount.SetWindowText(temp); //显示接受计数////////////////////////////////////////////////////}rxdatacount+=len;//m_ctrlRXCount.SetWindowText("接受:"+rxdatacount);CString temp;temp.Format("%ld",rxdatacount);temp="接受:"+temp;m_ctrlRXCount.SetWindowText(temp); //显示接受计数}UpdateData(FALSE); //更新编辑框内容}点击发送按钮处理函数//手工发送数据long TX_count=0;void CSCommTestDlg::OnButtonManualsend(){// TODO: Add your control notification handler code hereUpdateData(TRUE); //读取编辑框内容m_ctrlComm.SetOutput(COleVariant(m_strEditTXData)); //发送数据X_count+=m_strEditTXData.GetLength(); //发送计数CString strTemp;strTemp.Format("发送:%d",TX_count);m_ctrlTXCount.SetWindowText(strTemp); //显示计数GetDlgItem(IDC_BUTTON_MANUALSEND)->EnableWindow(TRUE);}void CSCommTestDlg::OnEditchangeComboComport(){// TODO: Add your control notification handler code here}改变串口时的处理函数void CSCommTestDlg::OnSelchangeComboComport(){// TODO: Add your control notification handler code here//int Cpos=m_ctrlComboComPort.GetCurSel()+1; //获取当前选择的串口号//测试用//CString myString ;//myString.Format("%d",Cpos);//CWnd* pWnd = GetDlgItem(IDC_STATIC1);//pWnd->SetWindowText(_T(myString));//测试用//if(m_ctrlComm)if(m_ctrlComm.GetPortOpen()){m_ctrlComm.SetPortOpen(FALSE); //关闭串口m_bSerialPortOpened=FALSE; //串口成功关闭m_ctrlOpenCom.EnableWindow(!m_bSerialPortOpened); //打开串口按钮有效m_ctrlCloseCom.EnableWindow(m_bSerialPortOpened); //关闭串口按钮失效}//打开串口//选择相应的波特率,校验位,数据位,停止位m_ctrlComm.SetCommPort(m_ctrlComboComPort.GetCurSel()+1);//选择相应的COMm_ctrlComm.SetInputMode(1); //输入方式为二进制方式m_ctrlComm.SetInBufferSize(1024);//设置输入缓冲区大小m_ctrlComm.SetOutBufferSize(512); //设置输出缓冲区大小//选择相应的波特率,校验位,数据位,停止位CString setstr;CString tempstr;m_ctrlComboBaudRate.GetWindowText(tempstr); //获取波特率setstr=tempstr;setstr+=",";m_ctrlComboParityBit.GetWindowText(tempstr); //获取校验位tempstr=tempstr.Left(1); //取第一个单词setstr=setstr+tempstr+",";m_ctrlComboDataBit.GetWindowText(tempstr); //获取数据位setstr=setstr+tempstr+",";m_ctrlComboStopBit.GetWindowText(tempstr); //获取停止位setstr+=tempstr;/*int BaudRate = 9600;char ParityBit = n;int DataBit = 8;int StopBit = 1;setstr.Format( "%d,%c,%d,%d ",BaudRate,ParityBit,DataBite,StopBit);SetSettings(setstr);*///m_ctrlComm.SetSettings("9600,N,8,1");m_ctrlComm.SetSettings(setstr);if(!m_ctrlComm.GetPortOpen())m_ctrlComm.SetPortOpen(TRUE); //打开串口m_ctrlComm.SetRThreshold(1); //参数1表示每当串口接受缓冲区中有多于或等于1个字符时将引发一个接受数据的OnComm事件m_ctrlComm.SetInputLen(0); //设置当前接受区数据长度为0m_ctrlComm.GetInput(); //先预读缓冲区以清除残留数据m_bSerialPortOpened=TRUE; //串口成功打开m_ctrlOpenCom.EnableWindow(!m_bSerialPortOpened); //打开串口按钮失效m_ctrlCloseCom.EnableWindow(m_bSerialPortOpened); //关闭串口按钮有效}打开串口void CSCommTestDlg::OnButtonOpen(){// TODO: Add your control notification handler code hereif(!m_ctrlComm.GetPortOpen()){m_ctrlComm.SetPortOpen(TRUE);m_bSerialPortOpened=TRUE; //串口成功打开m_ctrlOpenCom.EnableWindow(!m_bSerialPortOpened); //打开串口按钮失效m_ctrlCloseCom.EnableWindow(m_bSerialPortOpened); //关闭串口按钮有效}}关闭串口void CSCommTestDlg::OnButtonClose(){// TODO: Add your control notification handler code hereif(m_ctrlComm.GetPortOpen()){m_ctrlComm.SetPortOpen(FALSE);m_bSerialPortOpened=FALSE; //串口成功关闭m_ctrlOpenCom.EnableWindow(!m_bSerialPortOpened); //打开串口按钮有效m_ctrlCloseCom.EnableWindow(m_bSerialPortOpened); //关闭串口按钮失效}}定时器触发后运行的函数void CSCommTestDlg::OnTimer(UINT nIDEvent){// TODO: Add your message handler code here and/or call default//添加你要处理的函数,当定时时间到时自动调用//通过调用SetTimer(1,1000,NULL)启动定时器,通过调用KillTimer(int nIDEvent)关闭定时器OnButtonManualsend();CDialog::OnTimer(nIDEvent);}选择自动发送触发的函数void CSCommTestDlg::OnCheckAutosend(){// TODO: Add your control notification handler code hereif(m_ctrlAutoSend.GetCheck()){ //自动发送int i=atoi(m_strSendPeriod);SetTimer(1,i,NULL);//函数反回值就是第一个参数值1,表示此定时器的ID号。
MSComm控件进行串口编程的基本步骤
MSComm控件进⾏串⼝编程的基本步骤Visual C++为我们提供了⼀种好⽤的ActiveX控件Microsoft Communications Control(即MSComm)来⽀持应⽤程序对串⼝的访问,在应⽤程序中插⼊MSComm控件后就可以较为⽅便地实现对通过计算机串⼝收发数据。
要使⽤ActiveX控件MSComm,程序员必须将其添加⼊⼯程,其⽅法是: (1)单击主菜单project的⼦菜单Add To project的Components and Controls选项; (2)在弹出的"Components and Controls Gallery"对话框中选择Registered ActiveX Controls⽂件夹中的"Microsoft Communications Control,version 6.0"选项 单击其中的"Insert"按钮,MSComm控件就被增加到⼯程中了。
与此同时,类CMSComm的相关⽂件mscomm.h和mscomm.cpp也⼀并被加⼊Project的Header Files和Source Files中。
当然,程序员可以⾃⼰修改⽂件名1在建⽴的⼯程中插⼊MSComm控件2添加MSComm控件ID的控制变量或对象3对串⼝进⾏初始化,设置MSComm控件的属性4添加串⼝事件的消息处理函数OnComm()函数,在函数中根据应⽤需要,编写数据处理代码5编写串⼝发送等其他代码6关闭串⼝⼀个MSComm控件只能对应⼀个串⼝,如果应⽤程序需要访问多个串⼝,必须使⽤多个MSComm控件。
处理通信问题的⽅式:事件驱动⽅式(与中断原理类似,触发⼀个事件处理函数),查询⽅式。
MSComm控件的重要属性中的⼀部分CommPort设置并返回通信端⼝号Settings以字符串的形式设置并返回波特率、奇偶校验、数据位、停⽌位。
串口编程中使用MScommd的注意事项
串口编程中使用MScommd的注意事项串口编程中使用MScommd的注意事项微机能否通过端口检测到电平信号?悬赏分:20 - 解决时间:2006-10-16 11:39我做一个控制系统,需要微机检测到外部发出的信号(比如一个高电初次接触mysql:c++ 连接mysqlC语言链接MySQL, (实例一)用的是mysql自带的LIB包。
#include <windows.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <mysql.h>MYSQL* my_conn(){MYSQL *mysql;/*初始化指针*/mysql = mysql_init(NULL);/*连接数据库*/if(!(mysql = mysql_real_connect(mysql, "localhost", "root", "root", "test", 0, NULL, 0))){printf("error!!%s\n", mysql_error(mysql));exit(1);}printf("连接数据库成功!!\n");return mysql;}/*执行sql语句并返回*/MYSQL_RES* execute_query(MYSQL* mysql, char *sql){MYSQL_RES *res = NULL;printf("sql:%s\n", sql);/*执行SQL语句*/if(mysql_query(mysql,sql)) {fprintf(stderr,"Query failed (%s)\n",mysql_error(mysql));exit(1);}/*返回结果集*/if (!(res=mysql_store_result(mysql))) {fprintf(stderr,"Couldn't get result from %s\n", mysql_error(mysql));exit(1);}/*结果列数*/printf("number of fields returned: %d\n",mysql_num_fields(res));return res;}int main(){MYSQL *mysql;MYSQL_RES *res;MYSQL_ROW row;char *qbuf;mysql = my_conn();qbuf = "select * from test";/* printf("main sql:%s\n", qbuf);*/ res = execute_query(mysql, qbuf);while(row = mysql_fetch_row(res)) {printf("id=%s\t", row[0]);printf("name=%s\t", row[1]);printf("remark=%s\n", row[3]);}puts("query ok!!\n");mysql_free_result(res);mysql_close(mysql);return 1;}C语言链接MYSQL数据库(实例二1#include <mysql.h>/*注意要包含这个头文件*/2#include <string.h>3#include <stdlib.h>4#include <stdio.h>56/*定义了一些数据库连接需要的宏*/7#define HOST "localhost"8#define USERNAME "ABitNo"9#define PASSWORD "ABitNo"10#define DATABASE "abitno"1112/*这个函数用来执行传入的sql語句*/13void exe_sql(char* sql) {1415 MYSQL my_connection; /*这是一个数据库连接*/16int res; /*执行sql語句后的返回标志*/1718/*初始化mysql连接my_connection*/19 mysql_init(&my_connection);2021/*这里就是用了mysql.h里的一个函数,用我们之前定义的那些宏建立mysql连接,并22返回一个值,返回不为空证明连接是成功的*/23if (mysql_real_connect(&my_connection, HOST, USERNA ME, PASSWORD, DATABASE,24 0, NULL, CLIENT_FOUND_ROWS)) {/*连接成功*/2526 printf("数据库执行exe_sql连接成功!\n");2728/*这句话是设置查询编码为utf8,这样支持中文*/29 mysql_query(&my_connection, "set names utf8");3031/*下面这句话就是用mysql_query函数来执行我们刚刚传入的sql語句,32这会返回一个int值,如果为0,证明語句执行成功*/33 res = mysql_query(&my_connection, sql);3435if (res) {/*现在就代表执行失败了*/36 printf("Error: mysql_query !\n");37/*不要忘了关闭连接*/38 mysql_close(&my_connection);39 } else {/*现在就代表执行成功了*/40/*mysql_affected_rows会返回执行sql后影响的行数*/41 printf("%d 行受到影响!\n\n", mysql_affected_rows(&my_connection));42/*不要忘了关闭连接*/43 mysql_close(&my_connection);44 }4546 } else {47/*数据库连接失败*/48 printf("数据库执行exe_sql连接失败!\n");49 }50}5152/*这个函数用来执行传入的sql語句,并打印出查询結果*/53void query_sql(char* sql) {54 MYSQL my_connection; /*这是一个数据库连接*/55int res; /*执行sql語句后的返回标志*/56 MYSQL_RES *res_ptr; /*指向查询结果的指针*/57 MYSQL_FIELD *field; /*字段结构指针*/58 MYSQL_ROW result_row; /*按行返回的查询信息*/5960int row, column; /*查询返回的行数和列数*/61int i, j; /*只是控制循环的两个变量*/6263/*初始化mysql连接my_connection*/64 mysql_init(&my_connection);6566/*这里就是用了mysql.h里的一个函数,用我们之前定义的那些宏建立mysql连接,并67返回一个值,返回不为空证明连接是成功的*/68if (mysql_real_connect(&my_connection, HOST, USERNA ME, PASSWORD, DATABASE,69 0, NULL, CLIENT_FOUND_ROWS)) {/*Connection suc cess*/7071 printf("数据库查询query_sql连接成功!\n");7273/*这句话是设置查询编码为utf8,这样支持中文*/74 mysql_query(&my_connection, "set names utf8");7576/*下面这句话就是用mysql_query函数来执行我们刚刚传入的sql語句,77这会返回一个int值,如果为0,证明語句执行成功*/78 res = mysql_query(&my_connection, sql);7980if (res) { /*现在就代表执行失败了*/81 printf("Error: mysql_query !\n");82/*不要忘了关闭连接*/83 mysql_close(&my_connection);84 } else { /*现在就代表执行成功了*/85/*将查询的結果给res_ptr*/86 res_ptr = mysql_store_result(&my_connection);8788/*如果结果不为空,就把结果print*/89if (res_ptr) {90/*取得結果的行数和*/91 column = mysql_num_fields(res_ptr);92 row = mysql_num_rows(res_ptr) + 1;93 printf("查询到 %lu 行 \n", row);9495/*输出結果的字段名*/96for (i = 0; field = mysql_fetch_field(res_ptr); i++)97 printf("%s\t", field->name);98 printf("\n");100/*按行输出結果*/101for (i = 1; i < row; i++) {102 result_row = mysql_fetch_row(res_ptr); 103for (j = 0; j < column; j++)104 printf("%s\t", result_row[j]);105 printf("\n");106 }107108 }109110/*不要忘了关闭连接*/111 mysql_close(&my_connection);112 }113 }114}115116int main(int argc, char *argv[]) {117/*测试下向里面插入数据*/118char *exe = "insert into abitno values('ABitNo','');"; 119 exe_sql(exe);120121/*测试下查询*/122char *query = "select * from abitno;";123 query_sql(query);124125return 0;C语言链接MYSQL数据库(实例三)对于刚刚接触MySQL的用户,如果想用C语言连接MySQL,往往会是一件很麻烦的事情。
C++builder串口通信设计(一)-串口接收数据
三、建立应用工程
1、设计界面
引入了mscomm32控件,memo1控件,Button1,Button2,RadioBu)其中memo1用于显示串口接收内容
2)Button1用于控制串口的开启和关闭,Button2用于终止应用程序
RadioButton2Click(TObject*Sender);private://Userdeclarationspublic://User
declarations__fastcallTForm1(TComponent*Owner);inttype;//0--字符串,1---二
进制};//---------------------------------------------------------------------------extern
IDE-managedComponentsTMSComm*MSComm1;TMemo*Memo1;TButton
*Button1;TButton*Button2;TGroupBox*GroupBox1;TRadioButton
*RadioButton1;TRadioButton*RadioButton2;void__fastcallButton1Click(TObject
3)RadioButton1和RadioButton2用于选择串口接收方式(类型)
2、unit1.h内容,其中红色为引入的全局变量
#include#include#include“MSCommLib_OCX.h”#include//---------------------------
------------------------------------------------classTForm1:publicTForm{__published://
C++ builder 中如何使用Mscomm控件
要将Mscomm加入C++ builder,分成两种情况:第一种:机子上,装有VC,VB的。
我们就可以直接打开C++ builder 选择component->import activeX control ->选择“Microsoft comm control 6.0[version1.1]”->安装。
然后,我们就可以在控件栏的activeX下找到代表comm的控件了。
第二种情况:机子上没有装VC,VB的。
我们先到其他装有vc或者vb的机子上的目录C:/WINDOWS/system32 下找到Mscomm32.ocx 1个文件。
将他们拷到我们的C:/WINDOWS/system32 下。
然后点击“开始”->cmd->regsvr32 C:/WINDOWS/system32/Mscomm32.ocx->回车。
显示注册成功。
然后就可以按照第一种情况,在C++ builder中加入控件了。
在这注册成功以后,因为你的机子上并没有装有vc或者vb,所以你还需要自己手动添加注册表来给这个控件授权,把下面这段代码写成1.REG文件,然后运行1.reg,注册就可以了:REGEDIT4[HKEY_CLASSES_ROOT\Licenses\4250E830-6AC2-11cf-8ADB-00AA00C00905]@= "kjljvjjjoquqmjjjvpqqkqmqykypoqjquoun"注意最后的kjljvjjjoquqmjjjvpqqkqmqykypoqjquoun字串中,最后没有空格。
以下是参考的一个资料,可以看看,对理解为什么要这么做的原因有帮助。
如何手工注册MSComm控件龚建伟大家知道,当我们安装VC++6.0/VB6.0时,如果选择了ACtiveX控件项(自定义安装),MSComm控件就会自动安装在计算机上了,并在系统文件夹下多了3个文件:Mscomm.srg, Mscomm32.ocx,Mscomm32.dep注意,操作系统不同,则系统文件夹不同:Win98: windows/systemWin2000: winnt/system32那么用了MSComm控件的程序在发布时或者在DELPHI开发环境下如何来注册MSComm控件呢?发布程序时可以用安装程序,我们这里不介绍,只谈谈如何手工来注册安装MSComm控件。
Delphi+MSComm控件串口收发程序
//Delphi+MSComm控件串口收发程序//HotPower@procedure TForm1.FormCreate(Sender: TObject);beginif MSComm1.PortOpen then MSComm1.PortOpen := false;//关闭端口mPort := 2;//设置端口2MSComm1.InBufferSize := 256;//设置接收缓冲区为256个字节MSComm1.OutBufferSize := 256;//设置发送缓冲区为256个字节MSComm1.Settings := '9600,n,8,1';//9600波特率,无校验,8位数据位,1位停止位 MSComm1.InputLen := 0;//读取缓冲区全部内容(32个字节)MSComm1.InBufferCount := 0;// 清除接收缓冲区MSComm1.OutBufferCount:=0;// 清除发送缓冲区MSComm1.RThreshold := 32;//设置接收32个字节产生OnComm 事件// MSComm1.InputMode := comInputModeText;//文本方式MSComm1.InputMode := comInputModeBinary;//二进制方式MSComm1.PortOpen := true;//打开端口end;procedure TForm1.FormCloseQuery(Sender: TObject; var CanClose: Boolean);beginif MSComm1.PortOpen then MSComm1.PortOpen := false;;//关闭端口end;procedure TForm1.MSComm1Comm(Sender: TObject);varbuffer: Olevariant;//MSComm1.InputMode = comInputModeBinarystr: string;//MSComm1.InputMode = comInputModeTexti: integer;begincase mEvent ofcomEvReceive: //串行接收事件处理beginif MSComm1.InputMode = comInputModeText then //字符方式读取str := MSComm1.Input//读出后会自动清除接收缓冲区,str[1]~str[32]else //二进制方式读取buffer := MSComm1.Input;//读出后会自动清除接收缓冲区,buffer[0]~buffer[31] Edit3.Text := '';for i := 0 to MSComm1.RThreshold - 1 do //32字节Hex转换beginif MSComm1.InputMode = comInputModeText then //单行字符转换Edit3.Text := Edit3.Text + inttohex(byte(str[i + 1]), 2) + ' 'else //单行二进制数据转换Edit3.Text := Edit3.Text + inttohex(buffer[i], 2) + ' ';end;Memo2.Lines.Add(Edit3.Text);//加入一行显示end;end;end;procedure TForm1.BitBtn1Click(Sender: TObject);vari: integer;beginEdit4.Text := '';for i := 0 to 31 dobeginMSComm1.Output := char(i);//发送一个字符Edit4.Text := Edit4.Text + inttohex(i, 2);//以十六进制字符显示 end;Memo1.Lines.Add(Edit4.Text);//加入一行显示end;。
Active(MSCOMM)控件到C++Builder+2007,2009中
安装MSCOMM控件到C++Builder 2007、2009中(类似Active X的安装方法)
2008年06月04日星期三12:04
C++Builder 2007安装控件一直是比较麻烦的事情,前段时间要写一个比较简单的串口程序,准备用MSCOMM这个ActiveX控件1. 打开C++Builder,选择Import Component。
3. 找到Microsoft Comm Control 6.0,点Next
4. 按照下图设置好搜索路径等等,Next
5. 创建Unit,会生成一个CPP
6. 接下来,把它保存到C:\My Documents\RAD Studio\5.0\Imports里面去。
7. 接下来,关闭所有的东西,新建一个Package,如下图。
8. 点击OK之后,将Project重命名,取个你喜欢的名字,比如ILOVEZSF,我取的MsCOMM,然后保存下来,建议也保存在C
9. 把第六步保存的那个文件加进这个Project里面来。
10. 快完了,下面把Project来Build一下。
11
成功的话会跳出一个对话框
12. 目前就装好啦,先别高兴,最后还要设置一下程序的Include路径,把C:\My Documents\RAD Studio\5.0\Imports这个路径加
13. 点击OK后,宣的ActiveX就会多了一个MsCOMM组建,随便写个小程序,把它推进来,运行一。
MSComm控件实现串口通信的方法
MSCom控件实现串口通信的方法碧峰晨曦摘要:详细介绍了MSComm控件,并在VC++6.0中利用MSComm控件开发了基于对话框的串口通信实例。
关键词:串口通信,MSComm,VC++图书编号:TP3110•引言串口通信具有实现简单、价格低廉、通信稳定、数据传输可靠等优点,因而广泛应用于各种工业控制系统中。
MSComm控件是微软公司开发的专门用于串口通信的控件。
该控件为开发串口通信程序提供了更加快捷、容易的方法。
在VC++中,对控件属性的操作都是通过特定的函数来实现的,这些函数都是CMSComm类的成员函数。
当声明了一个CMSComm类对象后,就可以通过如下格式调用成员函数来访问控件属性了:<对象名>•<成员函数名>(<参数表〉)或<对象名>-><成员函数名>(<参数表>)1.MSComm控件属性及事件1.1MSComm控件属性MSComm控件有许多属性,最主要的几个属性如下:1)CommPort:设置该属性值可以获取当前程序使用的串口编号。
2)Sett in g:设置或者获取串行通信的通信参数(包括波特率、奇偶校验类型、数据位数及停止位数等)。
3)PortOpen设置该属性可以打开或关闭串口。
4)In put:从接收缓冲区中返回并删除数据。
5)Output:向串口通信输出缓冲区写入数据。
6)CommEvent:当MSComm控件在运行时发生错误或产生各种事件时,向程序返回错误或事件类型。
1.2MSComm控件的事件该控件只有一个事件,即On Comm事件。
当CommEve nt属性值发生变化时就会触发On Comm事件。
根据CommEve nt属性值来分别执行各种情况下的处理程序。
2 MSComm控件实例应用2.1插入MSComm控件在VC++6.0中新建一个基于对话框的工程,命名为Test。
默认情况下,VC++6.0中不会包含MSComm控件,所以需要我们手动将MSComm控件加载到VC++6.0 中。
通过MSComm控件进行WINCC串口通讯总结
通过MSComm控件进行WINCC串口通讯总结目的:通过MSComm控件实现WINCC串口通讯(C脚本和VB脚本两种方式)测试环境:操作系统win7WINCC版本:V7.2帮助工具:串口调试工具ASPD虚拟串口工具测试WINCC组态画面:测试试验过程画面:1、通过VB实现串口通讯画面对象“打开画面”VB大事脚本:Sub OnOpen()Dim objMSComm, tagConnectionSet objMSComm = hmiRuntime.Screens("串口通讯VB版").ScreenItems("COM")Set tagConnection = HMIRuntime.Tags("tagConnection1")If objMSComm.PortOpen = False Then' Assign com port numbermport = 4objMSComm.Settings = "9600,N,8,1"objMSComm.RThreshold = 1objMSComm.SThreshold = 0objMSComm.InBufferCount = 0objMSComm.InputLen = 0objMSComm.PortOpen = TruetagConnection.Write (True)HMIRuntime.Trace("Port open." vbCrLf)ElseHMIRuntime.Trace("Port is already opened." vbCrLf)End IfEnd SubMSComm控件OnComm对象大事:Sub OnOpen()Dim objMSComm, tagConnectionSet objMSComm = HMIRuntime.Screens("串口通讯VB版").ScreenItems("COM")Set tagConnection = HMIRuntime.Tags("tagConnection1")If objMSComm.PortOpen = False Then' Assign com port numbermport = 4objMSComm.Settings = "9600,N,8,1"objMSComm.RThreshold = 1objMSComm.SThreshold = 0objMSComm.InBufferCount = 0objMSComm.InputLen = 0objMSComm.PortOpen = TruetagConnection.Write (True)HMIRuntime.Trace("Port open." vbCrLf)ElseHMIRuntime.Trace("Port is already opened." vbCrLf)End IfEnd Sub“SEND按钮”鼠标左键按下大事:Sub OnLButtonDown(ByVal Item, ByVal Flags, ByVal x, ByVal y)Dim objMSCommDim strTemp,bufferHMIRuntime.Trace("Communication!" vbCrLf)Set objMsComm = HMIRuntime.Screens("串口通讯VB版").ScreenItems("COM")Set buffer = HMIRuntime.Tags("Buffer1")strTemp = buffer.ReadIf objMSComm.PortOpen = True ThenIf strTemp"" thenobjMSComm.Output=strTempEnd IfEnd IfEnd Sub2、通过C脚本实现串口通讯画面对象“打开画面”C大事脚本:#include "apdefap.h"void OnOpenPicture(char* lpszPictureName, char* lpszObjectName, char* lpszPropertyName){#define GetObject GetObject__object *pdl=NULL;__object *pic=NULL;__object *obj=NULL;int i,j;pdl = __object_create("PDLRuntime");if(pdl){printf("portopen get pdl ok ");}pic=pdl-GetPicture("串口通讯C版"); if(pic){printf("portopen get pic ok ");}obj=pic-GetObject("COM");if(obj){printf("portopen get obj ok ");}if(obj-PortOpen==0){obj-Commport = 3;obj-Settings = "9600,N,8,1";obj-RThreshold = 1;obj-SThreshold = 0;obj-InBufferCount = 0;obj-InputLen = 0;obj-PortOpen = 1;}__object_delete(obj);__object_delete(pic);__object_delete(pdl);}MSComm控件OnComm对象大事:#include "apdefap.h"void OnComm(char* lpszPictureName, char* lpszObjectName ) {#define GetObject GetObject__object *pdl=NULL;__object *pic=NULL;__object *obj=NULL;char *data="";pdl = __object_create("PDLRuntime");if(pdl){printf("portopen get pdl ok ");}pic=pdl-GetPicture("串口通讯C版");if(pic){printf("portopen get pic ok ");obj=pic-GetObject("COM");if(obj){printf("portopen get obj ok ");}SetTagChar("BufferTemp",obj-Input);printf("BufferTemp:%s ",GetTagChar("BufferTemp"));if(strcmp(GetTagChar("BufferTemp"),"")){SetTagChar("Buffer1",GetTagChar("BufferTemp"));}__object_delete(obj);__object_delete(pic);__object_delete(pdl);}“SEND按钮”鼠标左键按下大事:#include "apdefap.h"void OnLButtonDown(char* lpszPictureName, char* lpszObjectName, char* lpszPropertyName, UINT nFlags, int x, int y)#define GetObject GetObject__object *pdl=NULL;__object *pic=NULL;__object *obj=NULL;char *data="";pdl = __object_create("PDLRuntime"); if(pdl){printf("portopen get pdl ok ");}pic=pdl-GetPicture("串口通讯C版"); if(pic){printf("portopen get pic ok ");}obj=pic-GetObject("COM");if(obj){printf("portopen get obj ok ");}if(strcmp(GetTagChar("Buffer1"),""))obj-Output=GetTagChar("Buffer1"); }__object_delete(obj);__object_delete(pic);__object_delete(pdl);}MSComm控件.rar。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
一、引言目前,在用计算机进行数据传输时,常用的是串行通信方式。
用C++Builder来编写串行通信程序时,可以调用Windows API函数,也可以利用VB中的MSComm控件。
利用API函数编写实际应用程序时,往往要考虑多线程的问题,这样编出来的程序不但十分庞大,而且结构比较复杂,继承性差,维护困难。
但是使用串行通信控件就相对简单一些,而且功能强大,性能安全可靠。
本文就简单的介绍一下在C++ Builder中利用MSComm控件进行编程。
二、MSComm控件的常用属性和事件MSComm 控件通过串行端口传输和接收数据,为应用程序提供串行通讯功能。
具体的来说,它提供了两种处理通信问题的方法:一是事件驱动(Event-driven)方法,一是查询法。
事件驱动方式在使用事件驱动法设计程序时,每当有新字符到达,或端口状态改变,或发生错误时,MSComm控件将解发OnComm事件,而应用程序在捕获该事件后,通过检查MSCom m控件的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主菜单中的Comp onent菜单项,单击Import Active Control命令,弹出Import Active窗口,选择Microsoft Comm Control6.0,再选择Install按钮执行安装命令,系统将自动进行编译,编译完成后即完成MSComm控件在C++Builder中的注册,系统默认安装在控件板的Active页,接下来我们就可以像使用C++Builder本身提供的控件那样使用新注册的M SComm控件了。
(前提条件是你的机子上安装了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用来发送数据,Butto n4用来保存数据。
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://发送Me mo2中的数据{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中。