mscomm控件_mscomm控件编程 - CSDN
精华内容
参与话题
  • 串口通信-MSComm控件使用详解

    万次阅读 2018-05-10 14:10:28
    MSComm控件在串口编程时非常方便,程序员不必去花时间去了解较为复杂的API函数,而且在VC、VB、Delphi等语言中均可使用。 Microsoft Communications Control(以下简称MSComm)是Microsoft公司提供的简化Windows下...
    MSComm 控件通过串行端口传输和接收数据,为应用程序提供串行通讯功能。MSComm控件在串口编程时非常方便,程序员不必去花时间去了解较为复杂的API函数,而且在VC、VB、Delphi等语言中均可使用。 Microsoft Communications Control(以下简称MSComm)是Microsoft公司提供的简化Windows下串行通信编程的ActiveX控件,它为应用程序提供了通过串行接口收发数据的简便方法。具体的来说,它提供了两种处理通信问题的方法:一是事件驱动(Event-driven)方法,一是查询法。

    1.MSComm控件两种处理通讯的方式 

    1.1 事件驱动方式

    事件驱动通讯是处理串行端口交互作用的一种非常有效的方法。在许多情况下,在事件发生时需要得到通知,例如,在串口接收缓冲区中有字符,或者 Carrier Detect (CD) 或 Request To Send (RTS) 线上一个字符到达或一个变化发生时。在这些情况下,可以利用 MSComm 控件的 OnComm 事件捕获并处理这些通讯事件。OnComm 事件还可以检查和处理通讯错误。所有通讯事件和通讯错误的列表,参阅 CommEvent 属性。在编程过程中,就可以在OnComm事件处理函数中加入自己的处理代码。这种方法的优点是程序响应及时,可靠性高。每个MSComm 控件对应着一个串行端口。如果应用程序需要访问多个串行端口,必须使用多个 MSComm 控件。

    1.2 查询方式 

    查询方式实质上还是事件驱动,但在有些情况下,这种方式显得更为便捷。在程序的每个关键功能之后,可以通过检查 CommEvent 属性的值来查询事件和错误。如果应用程序较小,并且是自保持的,这种方法可能是更可取的。例如,如果写一个简单的电话拨号程序,则没有必要对每接收一个字符都产生事件,因为唯一等待接收的字符是调制解调器的“确定”响应。 

    2.MSComm控件的常用属性

    MSComm1.Settings:=’9600,n,8,1’; //设置波特率 ,校验位,数据位,停止位

    Settings属性: 设置串口的波特率 ,校验位,数据位,停止位, ’9600,n,8,1’表示波特率为9600,无奇偶校           验,数据位为8,1位停止位


    MSComm1.InBufferSize:=1024;    //  接受缓冲区大小 

    InBufferSize 属性:接收缓冲区的大小,默认值为1024,也可以自己设定,比如, MSComm1.InBufferSize:=2000,则接收缓冲区的大小为2000字节


    MSComm1.OutBufferSize:=1024;   //  发送缓冲区大小 

    OutBufferSize属性:发送缓冲区的大小,默认值为1024,也可以自己设定。  

     

    MSComm1.InBufferCount:=0;     //清空接受缓冲区 

    InBufferCount属性:当前接收缓冲区接收到的数据的长度, count:=MSComm1.InBufferCount,

                     count值就是接收缓冲区接收到的数据的长度,InBufferCount赋                         值MSComm1.InBufferCount:=0,可以清空接受缓冲区


    MSComm1.OutBufferCount:=0;    //清空发送缓冲区 

    OutBufferCount属性:当前发送缓冲区中数据的长度,OutBufferCount 赋值 

                      MSComm1. OutBufferCount:=0,可以清空发送缓冲区

     

    MSComm1.InputMode:=comInputModeText;// 以文本方式取回数据 

    MSComm1.InputMode:=comInputModeBinary; //设置接收数据模式为二进制形式 

    InputMode属性:串口接收数据的模式, comInputModeText(0)表示以文本(ASCII)方式取回数据,

                     comInputModeBinary(1)表示以二进制方式取回数据

                     comInputModeText, comInputModeBinary为预定义常量,分别表示0,1


    RcvByte:=MSComm1.Input 

    Input属性:通过Input属性可以读取串口中接收到的数据,RcvByte:=MSComm1.Input表示读取串口接收到的数据 ,其中RcvByte的数据类型为: array of  Byte array of  Variant.在读取之前先设置RcvByte的长度:SetLength(RcvByte,len),如果一次读取所有数据,SetLength(RcvByte, MSComm1.InBufferCount)


    MSComm1.Output:= OutputDat

    Output属性:通过Output属性可以发送数据, MSComm1.Output:=OutputDat,则将OutputDat中的数据发送出去,其中OutputDat数据类型为array of  Byte,发送前要设置OutputDat的长度, SetLength(OutputDat,len),然后向OutputDat中填入数据,再清空发送缓冲区MSComm1.OutBufferCount:=0,然后再发送MSComm1.Output:=OutputDat


    MSComm1.InputLen:=0;   // 一次读取所有数据 

     

    InputLen属性:一次从Input属性中读取数据的长度, MSComm1.InputLen:=1,表示一次读取一个字节,如果MSComm1.InputLen:=0,则表示一次读取全部数据

    MSComm1.SThreshold:=0; //一次发送所有数据 ,发送数据时不产生OnComm 事件

     

    SThreshold属性:通过该属性设置产生OnComm 事件(发送时产生)的阀值,MSComm1.SThreshold:=0, 则一次发送所有数据 ,发送数据时不产生OnComm 事件MSComm1.SThreshold:=5,当发送缓冲区的字节数从5字节减少到4字节时产生OnComm 事件


    MSComm1.RThreshold:=1; //每接收1个字节就产生一个OnComm 事件 

    RThreshold属性: 通过该属性设置产生OnComm 事件(接收时产生)的阀值,MSComm1.RThreshold:=0,不产生OnComm 事件,MSComm1.RThreshold:=5,接收缓冲区每收到5字节时,则产生OnComm 事件


    MSComm1.PortOpen:=True;       //打开串口

    PortOpen属性:设置端口的打开与关闭,打开端口MSComm1.PortOpen:=True,

    关闭端口MSComm1.PortOpen:=False


    MSComm1.CommPort:=CommPort;
     

    CommPort属性:设置端口号, MSComm1.CommPort:=1, 设置端口号为COM1


    CommEvent属性常用的两个comEvReceive, comEvSend

     

    OnComm   常数  

    常数                       描述    
    comEvSend         1      
    发送事件。    
    comEvReceive      2      
    接收事件。    
    comEvCTS          3      clear-to-send   
    线变化。    
    comEvDSR          4      data-set   ready   
    线变化。    
    comEvCD           5      carrier   detect   
    线变化。    
    comEvRing         6      
    振铃检测。    
    comEvEOF          7      
    文件结束。    





    ComPort属性:
    设置并返回通讯端口号。
    语法 object.CommPort[value ] (value 一整型值,说明端口号。) 
    说明 在设计时,value 可以设置成从 1 到 16 的任何数(缺省值为 1)。但是如果用 PortOpen 属性打开一个并不存在的端口时,MSComm 控件会产生错误 68(设备无效)。
    注意:必须在打开端口之前设置 CommPort 属性。

    RThreshold属性:在 MSComm 控件设置 CommEvent 属性为 comEvReceive 并产生 OnComm 之前,设置并返回的要接收的字符数。
    语法 object.Rthreshold [ = value ](value 整型表达式,说明在产生 OnComm 事件之前要接收的字符数。 )
    说明 当接收字符后,若 Rthreshold 属性设置为 0(缺省值)则不产生 OnComm 事件。例如,设置 Rthreshold 为 1,接收缓冲区收到每一个字符都会使 MSComm 控件产生 OnComm 事件。

    CTSHolding属性:确定是否可通过查询 Clear To Send (CTS) 线的状态发送数据。Clear To Send 是调制解调器发送到相联计算机的信号,指示传输可以进行。该属性在设计时无效,在运行时为只读。
    语法: object.CTSHolding(Boolean)

    Mscomm 控件的 CTSHolding 属性设置值:
    True Clear To Send 线为高电平。 
    False Clear To Send 线为低电平。 

    说明:如果 Clear To Send 线为低电平 (CTSHolding = False) 并且超时时,MSComm 控件设置 CommEvent 属性为 comEventCTSTO (Clear To Send Timeout) 并产生 OnComm 事件。

    Clear To Send 线用于 RTS/CTS (Request To Send/Clear To Send) 硬件握手。如果需要确定 Clear To Send 线的状态,CTSHolding 属性给出一种手工查询的方法。

    详细信息 有关握手协议,请参阅 Handshaking 属性。

    SThreshold属性: MSComm 控件设置 CommEvent 属性为 comEvSend 并产生 OnComm 事件之前,设置并返回传输缓冲区中允许的最小字符数。

    语法 object.SThreshold [ = value ]
    value 整形表达式,代表在 OnComm 事件产生之前在传输缓冲区中的最小字符数。 

    说明:若设置 Sthreshold 属性为 0(缺省值),数据传输事件不会产生 OnComm 事件。若设置 Sthreshold 属性为 1,当传输缓冲区完全空时,MSComm 控件产生 OnComm 事件。如果在传输缓冲区中的字符数小于 value,CommEvent 属性设置为 comEvSend,并产生 OnComm 事件。comEvSend 事件仅当字符数与 Sthreshold 交叉时被激活一次。例如,如果 Sthreshold 等于 5,仅当在输出队列中字符数从 5 降到 4 时,comEvSend 才发生。如果在输出队列中从没有比 Sthreshold 多的字符,comEvSend 事件将绝不会发生。


    HandShake 常数
    常数               值           描述 
    comNone            0          无握手。 
    comXonXoff         1          XOn/Xoff 握手。 
    comRTS             2          Request-to-send/clear-to-send 握手。 
    comRTSXOnXOff      3          Request-to-send 和 clear-to-send 握手皆可。 

    OnComm 常数
    常数               值           描述 
    comEvSend          1         发送事件。 
    comEvReceive       2         接收事件。 
    comEvCTS           3         clear-to-send 线变化。 
    comEvDSR           4         data-set ready 线变化。 
    comEvCD            5         carrier detect 线变化。 
    comEvRing          6         振铃检测。 
    comEvEOF           7         文件结束。 


    Error常数
    常数              值             描述 
    comEventBreak    1001        接收到中断信号 
    comEventCTSTO    1002        Clear-to-send 超时 
    comEventDSRTO    1003        Data-set ready 超时 
    comEventFrame    1004        帧错误 
    comEventOverrun  1006        端口超速 
    comEventCDTO     1007        Carrier detect 超时 
    comEventRxOver   1008        接收缓冲区溢出 
    comEventRxParity 1009        Parity 错误 
    comEventTxFull   1010        传输缓冲区满 
    comEventDCB      1011        检索端口 设备控制块 (DCB) 时的意外错误 

    InputMode常数 

    常数                   值                      描述 
    comInputModeText       0           (缺省)通过 Input 属性以文本方式取回数据。 
    comInputModeBinary     1            通过 Input 属性以二进制方式检取回数据。 


    CDHolding属性:通过查询 Carrier Detect (CD) 线的状态确定当前是否有传输。Carrier Detect 是从调制解调器发送到相联计算机的一个信号,指示调制解调器正在联机。该属性在设计时无效,在运行时为只读。

    语法 object.CDHolding
    设置值:CDHolding 属性的设置值为: 
    设置 描述 
    True Carrier Detect 线为高电平 
    False Carrier Detect 线为低电平 
    说明:注意当 Carrier Detect 线为高电平 (CDHolding = True) 且超时时,MSComm 控件设置CommEvent 属性为 comEventCDTO(Carrier Detect 超时错误),并产生 OnComm 事件。
    注意 在主机应用程序中捕获一个丢失的传输是特别重要的,例如一个公告板,因为呼叫者可以随时挂起(放弃传输)。
    Carrier Detect 也被称为 Receive Line Signal Detect (RLSD)。
    数据类型 Boolean

    DSRHolding属性:确定 Data Set Ready (DSR) 线的状态。Data Set Ready 信号由调制解调器发送到相连计算机,指示作好操作准备。该属性在设计时无效,在运行时为只读。
    语法:object.DSRHolding
    object 所在处表示对象表达式,其值是“应用于”列表中的对象。
    DSRHolding 属性返回以下值:
    值 描述 
    True Data Set Ready 线高 
    False Data Set Ready 线低 
    说明:当 Data Set Ready 线为高电平 (DSRHolding = True) 且超时时,MSComm 控件设置 CommEvent 属性为 comEventDSRTO(数据准备超时)并产生 OnComm 事件。
    当为 Data Terminal Equipment (DTE) 机器写 Data Set Ready/Data Terminal Ready 握手例程时该属性是十分有用的。
    数据类型:Boolean


    Setting属性: 设置并返回波特率、奇偶校验、数据位、停止位参数。

    语法: object.Settings[ = value]
    说明:当端口打开时,如果 value 非法,则 MSComm 控件产生错误 380(非法属性值)。
    Value 由四个设置值组成,有如下的格式:
    "BBBB,P,D,S"
    BBBB 为波特率,P 为奇偶校验,D 为数据位数,S 为停止位数。value 的缺省值是:
    "9600,N,8,1"


    InputLen属性:设置并返回 Input 属性从接收缓冲区读取的字符数。

    语法 object.InputLen [ = value]
    InputLen 属性语法包括下列部分:
    value 整型表达式,说明 Input 属性从接收缓冲区中读取的字符数。 
    说明:InputLen 属性的缺省值是 0。设置 InputLen 为 0 时,使用 Input 将使 MSComm 控件读取接收缓冲区中全部的内容。

    若接收缓冲区中 InputLen 字符无效,Input 属性返回一个零长度字符串 ("")。在使用 Input 前,用户可以选择检查 InBufferCount 属性来确定缓冲区中是否已有需要数目的字符。该属性在从输出格式为定长数据的机器读取数据时非常有用。


    EofEnable属性:确定在输入过程中 MSComm 控件是否寻找文件结尾 (EOF) 字符。如果找到 EOF 字符,将停止输入并激活 OnComm 事件,此时 CommEvent 属性设置为 comEvEOF,
    语法:object.EOFEnable [ = value ]
    EOFEnable 属性语法包括下列部分:
    value 布尔表达式,确定当找到 EOF 字符时,OnComm 事件是否被激活,如“设置值”中所描述。 
    value 的设置值:
    True 当 EOF 字符找到时 OnComm 事件被激活。 
    False (缺省)当 EOF 字符找到时 OnComm 事件不被激活。 
    说明:当 EOFEnable 属性设置为 False,OnComm 控件将不在输入流中寻找 EOF 字符。


    错误消息:(MS Comm 控件)


    下表列出 MSComm 控件可以捕获的错误:

    值 描述 
    380 无效属性值 comInvalidPropertyValue
    383 属性为只读 comSetNotSupported
    394 属性为只读 comGetNotSupported 
    8000 端口打开时操作不合法 comPortOpen
    8001 超时值必须大于 0 
    8002 无效端口号 comPortInvalid
    8003 属性只在运行时有效 
    8004 属性在运行时为只读 
    8005 端口已经打开 comPortAlreadyOpen
    8006 设备标识符无效或不支持该标识符 
    8007 不支持设备的波特率 
    8008 指定的字节大小无效 
    8009 缺省参数错误 
    8010 硬件不可用(被其它设备锁定) 
    8011 函数不能分配队列 
    8012 设备没有打开 comNoOpen 
    8013 设备已经打开 
    8014 不能使用 comm 通知 
    8015 不能设置 comm 状态 comSetCommStateFailed
    8016 不能设置 comm 事件屏蔽 
    8018 仅当端口打开时操作才有效 comPortNotOpen 
    8019 设备忙 
    8020 读 comm 设备错误 comReadError
    8021 为该端口检索设备控制块时的内部错误 comDCBError 


    3.使用

    端口初始化设置:

    procedure TFMonitorCenter.SBtnOpenPortClick(Sender: TObject);
    var
     i,CommPort:integer;
     Speed,DataBit,StopBit,CheckBit,SetString:string;
    begin
      CommPort:=1;
      Speed:='115200';
      DataBit:='8';
      CheckBit[1]:='N';
      StopBit:='1';
       if MSComm1.PortOpen=False then
       begin
           MSComm1.CommPort:=CommPort;   //设置端口
           SetString:=Speed+','+CheckBit[1]+','+DataBit+','+StopBit;
           MSComm1.Settings:=SetString;    //设置波特率 ,校验位,数据位,停止位
           MSComm1.InBufferSize:=1024;    //  接受缓冲区大小
           MSComm1.OutBufferSize:=1024;   //  发送缓冲区大小
           MSComm1.InBufferCount:=0;     //清空接受缓冲区
           MSComm1.OutBufferCount:=0;    //清空发送缓冲区
           MSComm1.InputMode:=comInputModeText;// 以文本方式取回数据
           MSComm1.InputMode:=comInputModeBinary; //设置接收数据模式为二进制形式
           MSComm1.InputLen:=0;//  一次读取所有数据 /
           MSComm1.SThreshold:=0;//一次发送所有数据 ,发送数据时不产生OnComm 事件
           MSComm1.RThreshold:=1; 每接收1个字节就产生一个OnComm 事件
           MSComm1.PortOpen:=True;       //打开串口
       end;
    end;

    OnComm  事件
    procedure TFMonitorCenter.MSComm1Comm(Sender: TObject);
    var
     str:string;
     RcvByte: array of  Byte;  // RcvByte存放缓冲区的数据
     i,len,NumOfFlag:integer;  //NumOfFlag  为一次OnComm事件中接收到的字符'~' 的个数
     OldCRCResult,NewCRCResult:WORD;
     CRCByte:array[0..255] of Byte;
    begin
      if(MSComm1.CommEvent=comEvReceive) then //接收事件
      begin                                          //接收缓冲区中是否收到Rthreshold 个字符
         if(MSComm1.InBufferCount<>0)   then     //缓冲区有数据
         begin
              len:=MSComm1.InBufferCount;  //缓冲区数据长度
              SetLength(RcvByte,len);  //设置动态数组的长度
              RcvByte:=MSComm1.Input;
     
              ......
              
    end;
     
    end;
    //*****************************************************//
    if (MSComm1.CommEvent= comEvSend) then//发送事件
    begin
      ......
    end;
     
     
     
    end;


    展开全文
  • mscomm控件下载

    千次下载 热门讨论 2020-07-22 23:34:34
    注册ACTIVE控件用的,是MSCOMM控件
  • 注册MSCOMM控件

    2018-05-23 12:29:29
    1.需要的原料: 2.将上诉文拷贝到C:\Windows\System32\...regsrv32.exe MSCOMM32.OCX 如果注册失败。将上诉文件拷贝到C:\Windows\SysWOW64\文件夹下,运行同样的命令 C:\Windows\SysWOW64&gt;regsvr32.exe...

    1.需要的原料:
    需要的文件

    2.将上诉文拷贝到C:\Windows\System32\文件夹下
    在cmd命令行中,输入以下命令即可
    C:\Windows\System32>regsrv32.exe MSCOMM32.OCX
    如果注册失败。将上诉文件拷贝到C:\Windows\SysWOW64\文件夹下,运行同样的命令
    C:\Windows\SysWOW64>regsvr32.exe MSCOMM32.OCX,注册成功
    这里写图片描述

    展开全文
  • VB中 MSComm控件使用详解

    万次阅读 2015-06-16 11:24:49
    MSComm控件在串口编程时非常方便,程序员不必去花时间去了解较为复杂的API函数,而且在VC、VB、Delphi等语言中均可使用。   Microsoft Communications   Control(以下简称MSComm)是Microsoft公司提供的简化...

     MSComm 
          控件通过串行端口传输和接收数据,为应用程序提供串行通讯功能。MSComm控件在串口编程时非常方便,程序员不必去花时间去了解较为复杂的API函数,而且在VC、VB、Delphi等语言中均可使用。 
          Microsoft Communications 
          Control(以下简称MSComm)是Microsoft公司提供的简化Windows下串行通信编程的ActiveX控件,它为应用程序提供了通过串行接口收发数据的简便方法。具体的来说,它提供了两种处理通信问题的方法:一是事件驱动(Event-driven)方法,一是查询法。

          1.MSComm控件两种处理通讯的方式 
              MSComm控件提供下列两种处理通讯的方式:事件驱动方式和查询方式。

          1.1 事件驱动方式 
              事件驱动通讯是处理串行端口交互作用的一种非常有效的方法。在许多情况下,在事件发生时需要得到通知,例如,在串口接收缓冲区中有字符,或者 
          Carrier Detect (CD) 或 Request To Send (RTS) 线上一个字符到达或一个变化发生时。在这些情况下,可以利用 
          MSComm 控件的 OnComm 事件捕获并处理这些通讯事件。OnComm 事件还可以检查和处理通讯错误。所有通讯事件和通讯错误的列表,参阅 
          CommEvent 
          属性。在编程过程中,就可以在OnComm事件处理函数中加入自己的处理代码。这种方法的优点是程序响应及时,可靠性高。每个MSComm 
          控件对应着一个串行端口。如果应用程序需要访问多个串行端口,必须使用多个 MSComm 控件。

          1.2 查询方式 
              查询方式实质上还是事件驱动,但在有些情况下,这种方式显得更为便捷。在程序的每个关键功能之后,可以通过检查 CommEvent 
          属性的值来查询事件和错误。如果应用程序较小,并且是自保持的,这种方法可能是更可取的。例如,如果写一个简单的电话拨号程序,则没有必要对每接收一个字符都产生事件,因为唯一等待接收的字符是调制解调器的“确定”响应。


          2.MSComm 控件的常用属性 
          MSComm控件有很多重要的属性,但首先必须熟悉几个属性。 
          CommPort 设置并返回通讯端口号。 
          Settings 以字符串的形式设置并返回波特率、奇偶校验、数据位、停止位。 
          PortOpen 设置并返回通讯端口的状态。也可以打开和关闭端口。 
          Input     从接收缓冲区返回和删除字符。 
          Output    向传输缓冲区写一个字符串。 
          下面分别描述:

          CommPort 属性 
              设置并返回通讯端口号。 
          语法 
          object.CommPort[ = value ] 
          CommPort 属性语法包括下列部分: 
          部分 描述 
          object 对象表达式,其值是“应用于”列表中的对象。 
          value 一整型值,说明端口号。 
          说明 
          在设计时,value 可以设置成从 1 到 16 的任何数(缺省值为 1)。但是如果用 PortOpen 属性打开一个并不存在的端口时,MSComm 
          控件会产生错误 68(设备无效)。 
          警告    必须在打开端口之前设置 CommPort 属性。 
          数据类型 
          Integer

          Settings 属性 
              设置并返回波特率、奇偶校验、数据位、停止位参数。 
          语法 
          object.Settings[ = value] 
          Settings 属性语法包括下列部分: 
          部分 描述 
          object 对象表达式,其值是“应用于”列表中的对象。 
          value 字符串表达式,说明通讯端口的设置值,如下所述。 
          说明 
          当端口打开时,如果 value 非法,则 MSComm 控件产生错误 380(非法属性值)。 
          Value 由四个设置值组成,有如下的格式: 
          "BBBB,P,D,S" 
          BBBB 为波特率,P 为奇偶校验,D 为数据位数,S 为停止位数。value 的缺省值是: 
          "9600,N,8,1" 
          下表列出合法的波特率: 
          设置值 
          110 
          300 
          600 
          1200 
          2400 
          9600(缺省) 
          14400 
          19200 
          28800 
          38400 
          56000 
          128000 
          256000

          下表说明合法的奇偶校验值。 
          设置值 描述 
          E 偶数 (Even) 
          M 标记 (Mark) 
          N 缺省 (Default) 
          None 
          O 奇数 (Odd) 
          S 空格 (Space)

          下表列出合法的数据位值。 
          设置值 
          4 
          5 
          6 
          7 
          8 (缺省)

          下表列出合法的停止位值。 
          设置值 
          1 (缺省) 
          1.5 
          2

          数据类型 
          String 
          Settings 示例 
          下面的例子设置控件端口通讯,波特率 9600,无奇偶校验检查,8 个数据位,1 个停止位: 
          MSComm1.Settings = "9600,N,8,1"

          PortOpen 属性 
          设置并返回通讯端口的状态(开或关)。在设计时无效。 
          语法 
          object.PortOpen[ = value] 
          PortOpen 属性语法包括下列部分:

          部分 描述 
          object 对象表达式,其值是“应用于”列表中的对象。 
          value 布尔表达式,说明通讯端口的状态。 
          设置值 
          value 设置值是: 
          设置值 描述 
          True 端口开 
          False 端口关

          说明 
          设置 PortOpen 属性为 True 打开端口。设置为 False 关闭端口并清除接收和传输缓冲区。当应用程序终止时,MSComm 
          控件自动关闭串行端口。 
          在打开端口之前,确定 CommPort 属性设置为一个合法的端口号。如果 CommPort 
          属性设置为一个非法的端口号,则当打开该端口时,MSComm 控件产生错误 68(设备无效)。 
          另外,串行端口设备必须支持 Settings 属性当前的设置值。如果 Settings 属性包含硬件不支持的通讯设置值,那么硬件可能不会正常工作。 
          如果在端口打开之前,DTREnable 或 RTSEnable 属性设置为 True,当关闭端口时,该属性设置为 False。否则,DTR 和 
          RTS 线保持其先前的状态。 
          数据类型 
          Boolean 
          PortOpen 属性示例 
          下例以波特率 9600 打开 1 号通讯端口,没有奇偶检查,8 个数据位,1 个停止位。 
          MSComm1.Settings = "9600,n,8,1" 
          MSComm1.CommPort = 1 
          MSComm1.PortOpen = True

          Input 属性 
              返回并删除接收缓冲区中的数据流。该属性在设计时无效,在运行时为只读。 
          语法 
          object.Input 
          Input 属性语法包括下列部分: 
          部分 描述 
          object 对象表达式,其值是“应用于”列表中的对象。 
          说明 
          InputLen 属性确定被 Input 属性读取的字符数。设置 InputLen 为 0,则 Input 属性读取缓冲区中全部的内容。 
          InputMode 属性确定用 Input 属性读取的数据类型。如果设置 InputMode 为 comInputModeText,Input 
          属性通过一个 Variant 返回文本数据。如果设置 InputMode 为 comInputModeBinary,Input 属性通过一个 
          Variant .返回一二进制数据的数组。 
          数据类型 
          Variant 
          Input 属性示例 
          该例子说明如何从接收缓冲区读取数据。 
          Private Sub Command1_Click() 
          Dim InString as String 
          ' 读取所有可用数据。 
          MSComm1.InputLen = 0

          ' 检查数据。 
          If MSComm1.InBufferCount Then 
              ' Read data. 
              InString = MSComm1.Input 
          End If 
          End Sub

          Output 属性 
              往传输缓冲区写数据流。该属性在设计时无效,在运行时为只读。 
          语法 
          object.Output [ = value ] 
          Output 属性语法包括下列部分: 
          部分 描述 
          object 对象表达式,其值是“应用于”列表中的对象。 
          value 要写到传输缓冲区中的一个字符串。

          说明 
          Output 属性可以传输文本数据或二进制数据。用 Output 属性传输文本数据,必须定义一个包含一个字符串的 
          Variant。发送二进制数据,必须传递一个包含字节数组的 Variant 到 Output 属性。 
          正常情况下,如果发送一个 ANSI 字符串到应用程序,可以以文本数据的形式发送。如果发送包含嵌入控制字符、Null 
          字符等等的数据,要以二进制形式发送。 
          数据类型 
          Variant 
          Output 属性示例 
          下面的例子说明如何将用户键入的每一个字符送到串行端口: 
          Private Sub Form_KeyPress (KeyAscii As Integer) 
              Dim Buffer as Variant 
              ' 设置并打开窗口 
              MSComm1.CommPort = 1 
              MSComm1.PortOpen = True 
              Buffer = Chr$(KeyAscii) 
              MSComm1.Output = Buffer 
          End Sub

          OnComm 事件 
          无论何时当 CommEvent 属性的值变化时,就产生 OnComm 事件,标志发生了一个通讯事件或一个错误。 
          语法 
          Private Sub object_OnComm () 
                OnComm 事件语法包括下列部分: 
                部分 描述 
                object 对象表达式,其值是“应用于”列表中的对象。 
                说明 
                CommEvent 属性包含实际错误或产生 OnComm 事件的数码。注意,设置 Rthreshold 或 Sthreshold 属性为 
                0,分别使捕获 comEvReceive 和 comEvSend 事件无效。 
                OnComm 事件示例 
                下例说明如何处理通讯错误和事件。可以在相关的 Case 语句之后插入代码来处理特定的错误或事件。 
                Private Sub MSComm_OnComm () 
                    Select Case MSComm1.CommEvent 
                    ' Handle each event or error by placing 
                    ' code below each case statement 
                ' 错误 
                       Case comEventBreak    ' 收到 Break。 
                       Case comEventCDTO    ' CD (RLSD) 超时。 
                       Case comEventCTSTO    ' CTS Timeout。 
                       Case comEventDSRTO    ' DSR Timeout。 
                       Case comEventFrame    ' Framing Error 
                       Case comEventOverrun    '数据丢失。 
                       Case comEventRxOver   '接收缓冲区溢出。 
                       Case comEventRxParity    ' Parity 错误。 
                       Case comEventTxFull     '传输缓冲区已满。 
                       Case comEventDCB     '获取 DCB 时意外错误 
                    ' 事件 
                       Case comEvCD    ' CD 线状态变化。 
                       Case comEvCTS    ' CTS 线状态变化。 
                       Case comEvDSR    ' DSR 线状态变化。 
                       Case comEvRing    ' Ring Indicator 变化。 
                       Case comEvReceive    ' 收到 RThreshold # ofchars. 
                       Case comEvSend    ' 传输缓冲区有 Sthreshold 个字符                     
                 ' 
                       Case comEvEof    ' 输入数据流中发现 EOF 字符 
                    End Select 
                End Sub 
                CommEvent 属性 
                返回最近的通讯事件或错误。该属性在设计时无效,在运行时为只读。 
                语法 
                object.CommEvent 
                CommEvent 属性语法包括下列部分: 
                部分 描述 
                object 对象表达式,其值是“应用于”列表中的对象。

                说明 
                只要有通讯错误或事件发生时都会产生 OnComm 事件,CommEvent 属性存有该错误或事件的数值代码。要确定引发 OnComm 
                事件的确切的错误或事件,请参阅 CommEvent 属性。 
                CommEvent 属性返回下列值之一来表示不同的通讯错误或事件。这些常数可以在该控件的对象库中找到。通讯错误包括下列设置值: 
                常数 值 描述 
                comEventBreak 1001 接收到一个中断信号。 
                comEventCTSTO 1002 Clear To Send 超时。在系统规定时间内传输一个字符时,Clear To Send 
                线为低电平。 
                comEventDSRTO 1003 Data Set Ready 超时。在系统规定时间内传输一个字符时,Data Set Ready 
                线为低电平。 
                comEventFrame 1004 帧错误。硬件检测到一帧错误。 
                comEventOverrun 1006 端口超速。没有在下一个字符到达之前从硬件读取字符,该字符丢失。 
                comEventCDTO 1007 载波检测超时。在系统规定时间内传输一个字符时,Carrier Detect 
                线为低电平。Carrier Detect 也称为 Receive Line Signal Detect (RLSD)。 
                comEventRxOver 1008 接受缓冲区溢出。接收缓冲区没有空间。 
                comEventRxParity 1009 奇偶校验。硬件检测到奇偶校验错误 
                comEventTxFull 1010 传输缓冲区已满。传输字符时传输缓冲区已满 
                comEventDCB 1011 检索端口的设备控制块 (DCB) 时的意外错误

                通讯事件包括下列设置值: 
                常数 值 描述 
                comEvSend 1 在传输缓冲区中有比 Sthreshold 数少的字符。 
                comEvReceive 2 收到 Rthreshold 个字符。该事件将持续产生直到用 Input 属性从接收缓冲区中删除数据。 
                comEvCTS 3 Clear To Send 线的状态发生变化。 
                comEvDSR 4 Data Set Ready 线的状态发生变化。该事件只在 DST 从 1 变到 0 时才发生。 
                comEvCD 5 Carrier Detect 线的状态发生变化。 
                comEvRing 6 检测到振铃信号。一些 UART(通用异步接收— 传输)可能不支持该事件。 
                comEvEOF 7 收到文件结束(ASCII 字符为 26)字符。 
                数据类型 
                Integer


                MSComm 控件示例 
                下面这个简单的例子演示了用调制解调器进行基本的串行通讯: 
                Private Sub Form_Load () 
                    ' 保存输入子串的缓冲区 
                    Dim Instring As String 
                    ' 使用 COM1。 
                    MSComm1.CommPort = 1 
                    ' 9600 波特,无奇偶校验,8 位数据,一个停止位。 
                    MSComm1.Settings = "9600,N,8,1" 
                    ' 当输入占用时, 
                    ' 告诉控件读入整个缓冲区。 
                    MSComm1.InputLen = 0 
                    ' 打开端口。 
                    MSComm1.PortOpen = True 
                    ' 将 attention 命令送到调制解调器。 
                ' Chr$函数:返回 String,其中包含有与指定的字符代码相关的字符 。 
                    MSComm1.Output = "ATV1Q0" & Chr$(13) ' 确保 
                    ' 调制解调器以"OK"响应。 
                    ' 等待数据返回到串行端口。 
                    Do 
                       DoEvents 
                    Buffer$ = Buffer$ & MSComm1.Input 
                    Loop Until InStr(Buffer$, "OK" & vbCRLF) 
                    ' 从串行端口读 "OK" 响应。 
                    ' 关闭串行端口。 
                    MSComm1.PortOpen = False 
                End Sub 
                注意    MSComm 控件可以采用轮询或事件驱动的方法从端口获取数据。这个简单的例子使用了轮询方法。

                实例1:计算机拨号 
                在一些实际应用中经常需要使用计算机拨号。下面这个例子利用MSComm控件操作Modem进行拨号,实现串口通信。 
                实现步骤: 
                1.建窗体 
                添加一个MSComm控件,用来建立与串口的连接; 
                添加一个Text控件,Name属性为Txttel,用来输入电话号码; 
                添加3个CommandButton控件,Name属性分别为DialButton、CancellButton、QuitButton,分别用来实现拨 
                号、中止拨号、中止程序; 
                添加一个Label控件,用来显示所有与拨号有关的信息。窗体见图1。 
                2.设置MSComm控件属性 
                InBufferSize=1024;   ’ InBufferSize 是指整个接收缓冲区的大小。缺省值是 1024 字节。 
                Inputlen=0;         ’ InputLen 属性的缺省值是 0。设置 InputLen 为 0 时,使用 Input 
                将使 MSComm 控件读取接收缓冲区中全部的内容。 
                InputMode=0;        ’0---(缺省)数据通过 Input 属性以文本形式取回。 
                                       1--数据通过 Input 属性以二进制形式取回 
                Rthreshold=2;       ’ 当接收字符后,若 Rthreshold 属性设置为 0(缺省值)则不产生 OnComm 
                事件。 
                RTSEnable=True;     ’ 当 RTSEnable 设置为 True,端口打开时,Request To Send 
                线设置为高电平,端口关闭时,设置为低电平。 
                Settings=“9600,N,8,1”; 
                Sthreshold=0。    ’ 若设置 Sthreshold 属性为 0(缺省值),数据传输事件不会产生 OnComm 
                事件。若设置 Sthreshold 属性为 1,当传输缓冲区完全空时,MSComm 控件产生 OnComm 事件。 
                因为每一台计算机的串口使用状态都不会一样。为使程序具有通用性,在窗体的Load方法中首先进行串口测试,找到第一个可用串口后再进行设置。 
                3.程序功能   
                程序根据输入的电话号码进行拨号,Modem正常拨号后,提示用户摘机,准备通话。 
                图1 电话拨号实例 
                4.主要方法与事件代码 
                '设置可用串口 
                Private Sub Form_Load() 
                On Error GoTo error_open 
                For i = 1 To 4 
                MSComm1.CommPort = 1 
                MSComm1.PortOpen = True 
                '设置可用的第一个串口 
                On Error GoTo 0 
                Exit Sub 
                error_resume: 
                Next 
                error_open: 
                Resume error_resume 
                End Sub 
                Private Sub DialButton_Click() 
                Dim Number$, Temp$ 
                Number$ = Trim$(Txttel.Text)     ’ 返回 Variant 
                (String),其中包含指定字符串的拷贝,没有前导空白 (LTrim)、尾随空白 (RTrim) 或前导和尾随空白 (Trim)。 
                If Number$ = “"   Then 
                MsgBox “请输入电话号码" 
                Txttel.SetFocus 
                Exit Sub 
                End If 
                DialButton.Enabled = False 
                QuitButton.Enabled = False 
                DialString$ =“ATDT”+ Number$ + “;” + vbCr
          '清除接收缓冲区 
          MSComm1.InBufferCount =0 
          '拨电话号码 
          MSComm1.Output = DialString$ 
          Lblmessage.Caption = “正在拨号码 -”+Number$ 
          DialButton.Enabled = True 
          QuitButton.Enabled = True 
          End Sub 
          Private Sub MSComm1_OnComm() 
          Select Case MSComm1.CommEvent 
          Case comEvReceive 
          '读取串口数据 
          COMBUF=COMBUF + MSComm1.Input 
          lc = InStr(1, COMBUF, “OK”) 
          If lc = 0 Then Exit Sub 
          'Modem已正常拨号,返回OK 
          Lblmessage.Caption = “请您摘下电话机, 准备通话” 
          Case comEvSend 
          End Select 
          End Sub 
          Private Sub CancelButton_Click() 
          '断开与调制解调器的连接 
          MSComm1.Output = “ATH” + vbCr 
          End Sub

          实例2:实现来电显示 
          在一些实际应用中,需要显示并保存来电号码,并根据电话号码显示相应资料,比如小区物业管理和110报警等系统。 
          实现步骤: 
          1.创建窗体 
          添加一个MSComm控件,用来建立与串口的连接; 
          添加4个Option控件,用来确定使用的串口号; 
          添加4个Label控件,用来显示来电号码及日期时间; 
          添加一个ProgressBar控件,用来显示电话振铃次数; 
          为方便调试程序,添加一个Text控件Text 5,用来显示Modem传来的所有信息。窗体见图2。 
          图2 来电显示窗体 
          2.设置MSComm控件属性 
          InBufferSize=1024; 
          Inputlen=0; 
          InputMode=0; 
          Rthreshold=1; 
          RTSEnable=True; 
          Settings=“9600,N,8,1"; 
          Sthreshold=0。 
          3.程序功能 
          程序首先初始化Modem,然后等待来电。当有来电时,MSComm产生OnComm事件。Modem送出的信息格式为“DATE = 月日回车换行TIME 
          = 时分回车换行NMBR = 
          电话号码回车换行”。在OnComm事件处理程序中对读入信息进行截取,截取电话号码后,以该电话号码为关键字,查询并显示数据库中有关信息。 
          4.主要方法与事件代码 
          '通用声明部分 
          Const DEBFLG = 1 
          Public COMX, BEEPNO, HANGUP,PNLOC As Integer 
          Public COMBUF, COMLIN As String 
          Private Sub Form_Load() 
          '检测串行口 
          Dim I, C As Integer 
          COMX = 0 
          COMBUF = “” 
          COMLIN = “” 
          BEEPNO = 0 
          HANGUP = 0 
          '正常运行程序,关闭右侧Text5 
          If DEBFLG= 0 Then 
          Form1.Width = Form1.Width - Text5.Width 
          Text5.Enabled = False 
          Text5.Visible = False 
          End If 
          On Error GoTo ERROR_FORM_LOAD 
          '检测可用串口 
          For C = 1 To 4 
          If MSComm1.PortOpen Then MSComm1.PortOpen = False 
          MSComm1.CommPort = C 
          If Not MSComm1.PortOpen Then 
          MSComm1.PortOpen = True 
          If MSComm1.PortOpen Then MSComm1.PortOpen = False 
          If COMX = 0 Then COMX = C 
          FORM_LOAD_1: 
          Next C 
          If COMX = 0 Then End 
          On Error GoTo 0 
          Option1(COMX - 1).Value = True 
          Exit Sub 
          ERROR_FORM_LOAD: 
          Option1(C - 1).Enabled = False 
          Resume FORM_LOAD_1 
          End Sub 
          '选择串行口 
          Private Sub Option1_Click(Index As Integer) 
          COMX = Index + 1 
          Call INIT_MODEM 
          End Sub 
          '初试化Modem 
          Private Sub INIT_MODEM() 
          If MSComm1.PortOpen Then MSComm1.PortOpen = False 
          MSComm1.CommPort = COMX 
          If Not MSComm1.PortOpen Then MSComm1. 
          PortOpen = True 
          MSComm1.Output = “AT#CID=1” + vbCr 
          '检查Modem命令是否完成 
          Call CHK_MODEM 
          MSComm1.Output = “ATS0=0” + vbCr 
          End Sub 
          '检查Modem命令是否完成 
          Private Sub CHK_MODEM() 
          Dim T As Single 
          Dim L As Integer 
          T = Timer 
          Do 
          COMBUF = COMBUF + MSComm1.Input 
          L = InStr(1, COMBUF,“OK”) 
          Loop Until L <> 0 Or Timer - T > 1 
          If L = 0 Then 
          Line1.Visible = True 
          Line2.Visible = True 
          Form1.Show 
          MsgBox “MODEM未联机”,vbOKOnly+vbCritical,“测试MODEM” 
          Else 
          Line1.Visible = False 
          Line2.Visible = False 
          End If 
          End Sub 
          '串行口接收事件处理 
          Private Sub MSComm1_OnComm() 
          Dim CH, ST As String 
          Dim LC As Integer 
          Select Case MSComm1.CommEvent 
          '接收到Rthreshold个字符 
          Case comEvReceive 
          COMBUF = COMBUF + MSComm1.Input 
          '读取串口数据 
          Do 
          LC = InStr(1, COMBUF, Chr(10)) 
          If LC = 0 Then Exit Do 
          COMLIN = Left(COMBUF, LC) 
          COMBUF = Mid(COMBUF, LC + 1) 
          CH = Left(COMLIN, 1) 
          If “ ” < CH And CH < Chr(127) And DEBFLG = 1 Then 
          Text5.Text = Text5.Text + COMLIN 
          Text5.SelStart = Len(Text5.Text) 
          End If 
          '截取来电号码,并显示 
          If InStr(1, COMLIN“NMBR=”)<> 0 Then 
          ST = Mid(COMLIN, 8) 
          Text2.Text=“ ”+Left$(ST,Len (ST) -2) + “ ” 
          Form1.WindowState = 0 
          Timer1.Enabled = True 
          Call BEEP_NO 
          '截取来电日期,并显示 
          ElseIf InStr(1, COMLIN, “DATE = ”) <> 0 Then 
          Text3.Text = Str(Year(DATE)) + “.”+ Mid(COMLIN, 8, 2) + “.” + Mid(COMLIN, 
          10, 2) + “ ” 
          '截取来电时间,并显示 
          ElseIf InStr(1, COMLIN, “TIME = ”) <> 0 Then 
          Text4.Text = “ ” + Mid(COMLIN, 8, 2) + “:” + Mid(COMLIN, 10, 2) 
          '检测振铃个数 
          ElseIf InStr(1, COMLIN, “RING”) <> 0 Then 
          Call BEEP_NO 
          If HANGUP = 1 Or BEEPNO = 15 Then Call HANG_UP 
          '检测是否停止振铃 
          ElseIf Left(COMLIN, 3) = “000” Then 
          BEEPNO = 0 
          Timer1.Enabled = False 
          Form1.WindowState = 1 
          ProgressBar1.Value = 0 
          Frame3.Caption = “振铃数” 
          End If 
          Loop 
          '其他事件处理 
          Case comEvCTS 
          Case comEvDSR 
          Case comEvCD 
          Case comEvRing 
          Case comEventBreak 
          Call INIT_MODEM 
          Case Else 
          MsgBox “串口接收事件号:” & MSComm1.CommEvent & “ ”, vbOKOnly + 
          vbCritical, “测试串行口” 
          End Select 
          End Sub 

     

    展开全文
  • win10注册MSCOMM32控件及简单使用

    千次阅读 2019-02-09 16:24:41
    前几天重装了系统,然后之前写的用MsComm控件(Microsoft Communications Control)进行串口通信的程序无法运行了,用VS打开项目进入资源视图,发现打不开包含MsComm控件的对话框资源,提示未在此计算机上注册...

    https://www.jianshu.com/p/5c54338b67b2

    前言 & 吐槽

    前几天重装了系统,然后之前写的用MsComm控件(Microsoft Communications Control)进行串口通信的程序无法运行了,用VS打开项目进入资源视图,发现打不开包含MsComm控件的对话框资源,提示未在此计算机上注册ActiveX控件。而VS工具箱提供的COM组件里也没有MsComm控件。
    根本原因是这个ActiveX控件根本不是win10安装自带的,高版本VS也不会自带的,你要写这种串口通信程序,要么用底层API,要么用微软大力支持的.Net系语言,而不是MFC这个非常非常过时的破东西了,然而就这个破东西,很多时候还是被迫得写,嗯,前几天才看到2018年的二级C/C++上机环境终于从万年不变的VC6变成了VS2010,简直了。

    注册MsComm控件

    首先给下载地址,其实谷歌MsComm.ocx第一条就是
    https://www.ocxme.com/files/mscomm32_ocx
    当然国内用百度的多,一堆文章全部都指向了CSDN花几个积分的下载链接,好点的有百度盘链接,不过天知道过段时间会不会被和谐。还是这种专门的免费下载站更舒心。
    下完解压后就是MSCOMM32.OCX,然后需要注意(我踩了这个坑),对于64位系统需要把它放在C:\Windows\SysWOW64目录下,32位系统才是C:\Windows\system32目录。之前我放在system32目录然后注册出了问题。
    然后右键管理员权限打开cmd窗口,进入对应目录输入指令regsvr32 MSCOMM32.OCX即可(如下图所示)


    网上有些教程还有一步是修改注册表,不过我发现regsvr32命令已经修改了注册表,无需手动修改。

    为何使用MsComm控件?

    其实直接用底层API进行串口编程未尝不可,MSDN也给出了示例,但是事件回调的步骤得自己写,如果不是时间充裕用来学习/练手的情况,没必要重复造轮子。
    网上也可以搜到不少包装好的C++类,但是串口这东西本来就是古老物了,搜到的代码还是很多年前的,代码风格不一定很好。而且有的接口已经和现代C++标准不兼容了。
    比如之前师兄用了一个简单小巧的库(只包含1个头文件和1个源文件,添加进工程即可)提供了这样的接口

        void        WriteToPort(char* string);
    

    然而C++11标准在近几个版本的VS里已经得到了支持,字符串字面值是不能直接转换成char*类型的,也就是说实际调用的时候得像这样 xxx.WriteToPort((char*)"hello")xxx.WriteToPort(const_cast<char*>("hello"))
    然后错误信息字符串操作全都是基于char*的,MFC默认Unicode,而且方便移植的代码应该都对TCHAR*来操作,直接编译会出错的,需要一个个用宏_T()把字符串包含起来。当然,会正则表达式的话起来替换相对会比较轻松。
    我对MsComm控件不甚了解,但是明显这也是古老物了,毕竟还不支持64位程序,VS里用Debug或Release x64来编译的话会失败。
    但是好处在于,这个控件是官方的,值得信赖,不像很多开源库那样缺乏大量测试。

    为何不使用MsComm控件?

    这篇文章是2018-01-17发布的,我在2018-02-01完成课题程序时发现了问题。正如上文所言,MsComm控件是古老物了,只适用于32位的程序。如果程序必须编译成64位的,那么MsComm控件无法派上用场。我的程序里需要用到OpenCV和一个第三方库,两者刚好都只提供了64位的lib和dll,所以只有使用MsComm控件,后来使用了上文提到的CSerialPort,才发现这个古老版本原来国内有不少人进行了维护,现在还是非常好用的,强力推荐。

    添加MsComm控件

    首先需要在VS中添加该控件到工具箱中



    按上述操作点确定即可
    PS:可以看到版本才1.1,还是version 6.0,目测从VC6之后再也没更新过……
    然后在对话框资源编辑框中右键,插入ActiveX控件



    不同于常规的界面控件,MsComm控件不会显示出来,所以随便拖到哪个位置都可以。
    拖了控件之后就是为控件添加变量了

    这一步,VS会自动生成一对.h和.cpp文件,然后在xxxDlg.h中添加成员变量
    CMscomm1 m_comm1;
    并在xxxDlg.cpp中添加数据交换操作

    void CTestDlg::DoDataExchange(CDataExchange* pDX)
    {
        CDialog::DoDataExchange(pDX);
        DDX_Control(pDX, IDC_MSCOMM1, m_comm1);
    }
    

    可以发现和使用其他控件一样的套路。

    从串口发送和接收字节

    文本框/复选框这种自定义参数输入的控件就不祥述了,以我的需求为例

    波特率: 9600 停止位: 1 传送位数: 8位 奇偶校验: 无
    串口协议是7个字节表示1个数据包
    MsComm控件类型为CMscomm_las,变量名为m_commLaser

    1. 打开/关闭串口
            m_commLaser.put_CommPort("COM1");
            m_commLaser.put_InputMode(CMscomm_las::comInputModeBinary);
            m_commLaser.put_InBufferSize(512);  // 接收缓冲区大小
            m_commLaser.put_OutBufferSize(512);  // 发送缓冲区大小
            m_commLaser.put_Settings(_T("9600,n,8,1"));
            if (!m_commLaser.get_PortOpen())
            {
                try {
                    m_commLaser.put_PortOpen(TRUE);  // 打开串口
                }
                catch (CException* e) {
                    TCHAR error_msg[1024];
                    e->GetErrorMessage(error_msg, 1024);
                    MessageBox(error_msg);
                    return;
                }
                m_commLaser.put_RThreshold(7);  // 每当接收缓冲区有7个字符时则接收串口数据
                m_commLaser.put_InputLen(0);
                m_commLaser.get_Input();
            }
            else
            {
                MessageBox(_T("打开端口失败!"));
            }
    

    注意put_Settings的参数,n代表无奇偶校验,是DCB结构的Parity成员的可选取值NOPARITY的缩写,同理,奇校验ODDPARITY是o,偶校验EVENPARITY是e。
    打开串口是put_PortOpen(TRUE),关闭串口自然就是put_PortOpen(FALSE)。

    1. 发送字节序列
      void put_Output(VARIANT newValue)
      直接调用上述方法即可,问题来了,VARIANT类型是什么?这就是ActiveX控件的蛋疼之处,它的数据交换必须用Ole那一套来。
      正常来说,发送给串口的都是字节序列,即uint8_t或BYTE数组。因此这里只需要知道怎么转换成VARIANT类型即可。
      MFC是上古时期的产物,那个时候C++98标准都没确立,因此微软弄了一堆自定义的容器类,虽然除了CString外几乎都被C++标准库的STL取代了。但在这里,MFC的CByteArray刚好能直接用来构造COleVariant对象,COleVariant继承自VARIANT(C结构体的typedef别名),仅仅是增加了若干方法,可以隐式类型转换。
      比如发送3个字节0x01 0x02 0x04给串口的代码如下
        CByteArray m_baSend;
        m_baSend.Add(0x01);
        m_baSend.Add(0x02);
        m_baSend.Add(0x04);
        m_commLaser.put_Output(COleVariant(m_baSend));
    
    1. 接收字节序列
      给MsComm控件添加OnComm事件处理程序即可




      和其他控件一样,MsComm控件也是事件驱动,在后台接收数据,然后处理不同的事件

    enum
    {
        comEvSend = 1,
        comEvReceive = 2,
        comEvCTS = 3,
        comEvDSR = 4,
        comEvCD = 5,
        comEvRing = 6,
        comEvEOF = 7
    }OnCommConstants
    

    接收数据只需要处理comEvReceive事件即可,其他几个事件等真正有需求的时候再去处理。下面给出我接收7个字节的代码

    void CMsCommDemoDlg::OnCommMscommLas()
    {
        if (m_commLaser.get_CommEvent() == CMscomm_las::comEvReceive)
        {
            // 读取串口的接收缓冲区(之前打开串口时设置过缓冲区大小)
            COleSafeArray safearray_obj = m_commLaser.get_Input();
            // 填充数据到自定义缓冲区中
            const int BUFF_SIZE = 7;
            BYTE buffer[BUFF_SIZE];
            for (long i = 0; i < BUFF_SIZE; i++)
            {
                safearray_obj.GetElement(&i, &buffer[i]);
            }
            // TODO: 处理缓冲区buffer[]的数据
        }
    }
    

    这里就和发送数据反过来了,接收的数据类型是VARIANT,需要转换成BYTE数组来处理。套路就是借助COleSafeArray这个中间物及其GetElement方法。

    总结

    其实这个程序是我几周之前写的Demo,最近要重新写了,照着我的代码写下来,自己也梳理了用MsComm控件的步骤。
    控件方面,由于这东西实在太古老了而被抛弃了,而官方也没给C++提供什么替代品,于是得手动引入

    1. 注册MSCOMM32.OCX
    2. 在VS工具箱的COM组件中找到MsComm控件添加进来
    3. 像使用其他MFC控件一样使用它(添加关联的控件变量/事件处理函数)

    代码方面,虽然COM接口的实现看起来非常复杂且蛋疼,但是其实接口很清晰,都是一堆put(设置)和get(获取)方法,注意打开/关闭串口也是通过putxxx来执行的,相当于设置串口的连接状态。
    难点在于数据交换格式都是VARIANT,因此需要借用MFC专门提供的类来转换成方便处理的BYTE数组。大致过程如下

    BYTE[] -> CByteArray -> COleVariant -> VARIANT
    VARIANT -> COleSafeArray -> BYTE[]
    
    展开全文
  • MSComm控件

    2020-07-30 23:32:02
    win7 64位系统下安装的VS2010旗舰版没有MSComm控件,使用MFC编程时,工具箱中无法添加串口通信控件,所以需要自己安装一下MSComm控件。(包含安装说明)
  • vs2017中配置并使用MSCOMM控件

    千次阅读 2019-07-10 10:01:44
    vs2017中配置并使用MSCOMM控件 1.新建一个mfc项目 2.在类视图中,添加类向导 3.使用ActiveX类向导 4.添加CMSCommm 5.打开端口 void BaseBox::OpenPort(CMSComm * cms_comm) { m_MsCommz = cms_comm; int iComN ...
  • MSComm控件使用详解

    千次阅读 2018-12-29 23:09:44
    MSComm控件使用详解 MSComm控件通过串行端口传输和接收数据,为应用程序提供串行通讯功能。MSComm控件在串口编程时非常方便,程序员不必去花时间去了解较为复杂的API函数,而且在VC、VB、Delphi等语言中均可使用。...
  • VS2010如何安装MSComm控件

    万次阅读 多人点赞 2012-10-29 09:37:09
    VS2010在默认情况下是不包含MSComm控件的,MSComm是在VC6.0中的控件,据说MSComm控件有些缺陷,看来微软是打算放弃此控件了。不过对于已经熟悉使用此控件的人来说还是不太方便,我是那种喜欢偷懒的人,所以在网上找了...
  • vba 中引入mscomm控件

    2020-07-30 23:32:55
    vba 中引入mscomm控件 vba 中引入mscomm控件 vba 中引入mscomm控件
  • 问题描述:之前在LabVIEW中使用MSComm控件时,直接使用导入--ActiveX控制至选板就可以看到MSComm控件了,现在换了电脑,重新使用MSComm控件时发现找不到了(原电脑安装VS时选择安装了VB,因此可以直接使用),即现在...
  • MSCOMM控件的手动安装

    2020-07-29 14:20:34
    在没有安装VB6.0企业版或者VC的电脑上使用MSCOMM控件需要手工安装MSCOMM控件,此文件介绍手工安装MSCOMM控件的方法,并附相关安装所需的文件。
  • VB中_MSComm控件使用详解
  • 串口通讯mscomm控件下载

    千次阅读 2010-11-12 08:15:00
    串口通讯mscomm控件下载    大家知道,当我们安装VC++6.0/VB6.0时,如果选择了ACtiveX控件项(自定义安装),MSComm控件就会自动安装在计算机上了,并在系统文件夹下多了3个文件:Mscomm.srg, ...
  • MFC下的MSCOMM控件

    千次阅读 2015-05-12 10:41:14
    在mfc中进行串口通讯最简单的方法莫过于在对话框中使用MSCOMM控件了,MSComm通信控件提供了一系列标准通信命令的接口,它允许建立串口连接,可以连接到其他通信设备(如Modem).还可以发送命令、进行数据交换以及...
  • WINCC注册MSCOMM控件

    2020-07-30 23:30:44
    WINCC注册MSCOMM控件,WINCC串口通讯使用。
  • 线程与mscomm控件问题

    2014-01-08 09:12:52
    我是在做下位机向上位机传递数据,使用的mfc基于对话框的mscomm控件。需要动态实时显示曲线。我采用teechart控件来画曲线。mscomm控件有个Onmscomm()函数用来接收串口通信数据并存储起来。现在开辟了一个线程,在...
  • MSCOMM控件加脚本注册

    2020-07-23 23:30:42
    MSCOMM控件注册使用,文件包含MSCOMM.SRG、MSCOMM32.DEP、MSCOMM32.oca、mscomm32.ocx等控件。并附含了注册脚本,亲测win7\win8\win10可用
  • VS2010如何添加MSCOMM控件

    千次阅读 2016-03-07 15:39:06
    VS2008后,就没有MSCOMM控件了,用户想用只能手动添加 下载MSCOM控件 (百度下载即可)(全名为:mscomm32.ocx) 控件注册 将控件复制到如下路径下: c:\windows\syswow(32为系统) c:\windows\systom32(64位系统...
  • 方法一:电脑装回XP系统,MSCOMM控件就可以加入工程了,不过这对于已经使Win7的用户,为了使用MSCOMM控件装回XP系统,损失有点大!(方法可行,但不推荐) 方法二:对于Win7的用户,可以去安装个虚拟机,虚拟机里头...
1 2 3 4 5 ... 20
收藏数 2,833
精华内容 1,133
关键字:

mscomm控件