VC2010如何使用串口

点击打开链接


我在VS2010里试过了,也可以实现。

这篇我是转的网友的,我试了一下,出了一点问题,对原文做了些添加说明,文章如下:

前几天需要做一个COM口的通讯程序,主要是要接收一个传感器送来的船舶航行状态参数。过去没有接触过COM口编程,上网查查VC6下有个Communication Control可用,挺方便的,遂研究研究拿来用,整理一下学习笔记存档,并与网友分享。

首先,我用的是VC2005,但在VC2005下没有这个控件,所以要借用一下VC6。控件名是MSCOMM32.OCX,如果安装了VC6或VB6的话,就能在/WINDOWS/System32下找到MSCOMM32.OCX,MSCOMM32.SRG,MSCOMM32.DEP三个文件。如果在开发的机器上没有安装VC6或VB6,同时也没有安装过使用的这个控件,则首先要对这个控件进行注册。注册方法是使用命令regsvr32 MSCOMM32.OCX,比如我就直接把找来的这三个文件放到我的System32下,同时新建一个文本文件,把命令regsvr32 MSCOMM32.OCX写到文本文件中,改扩展名为bat,直接双击这个bat就完成空间注册。另外,为了在VC2005中开发的时候能正常使用这个控件,还需要修改一下注册表,否则会出错。修改方法是将以下内容写到一个文本文件中,扩展名改为reg,然后双击这个文件导入就可以了。(此处注册表修改的内容也可以在MSCOMM32.SRG中找到)

REGEDIT

HKEY_CLASSES_ROOT/Licenses = Licensing: Copying the keys may be a violation of established copyrights.

// Comm Control 6.0 license key

HKEY_CLASSES_ROOT/Licenses/4250E830-6AC2-11cf-8ADB-00AA00C00905 = kjljvjjjoquqmjjjvpqqkqmqykypoqjquoun

完成以上的控件注册和注册表的修改后就可以开始程序的开发了。

另外有个简单的方法就是:

1.下载控件:MSCOMM32.OCX下载地址

http://download.csdn.net/detail/tianhen791/4023983

2.下载完成后解压-》点击setup.bat 即可此控件的安装和注册。

如果注册后,在COM组件中仍然无法找到Microsoft Communications Control,不妨重启一下电脑试试。

另外,有些人可能无法成功注册,提示:无法成功调用DllRegisterServer 错误代码: 0x8002801c

可通过以下步骤实现成功注册:

1、新建一个文本文档输入:NET LOCALGROUP 用户名 administrators /add 

2、另存为.bat文件

       3、再打开组策略(运行:gpedit.msc)windows设置,脚本启动脚本找到刚才新建的bat文件

       4、重新启动您的爱机一工切OK!


 

首先新建一个MFC对话框程序。然后在IDE的右侧打开“工具箱”,鼠标右击,在弹出菜单中点击“选择项”,在COM组件下找到Microsoft Communications Control,在其前面的选择框中打勾,一个黄色电话图标就会出现在工具箱里,用鼠标把这个图标拖进对话框资源编辑器里,控件就被添加到项目的程序中。

另外也可以菜单里“工具(T)”下拉菜单里,选择“选择工具箱”,英文是choose Toolbox Items ,同样可以打开COM组件选项。

为了便于使用,我们可以给这个控件绑定一个控件变量,比如叫做m_mscomm,程序会自动添加一个CMscomm类封装这个控件,而m_mscomm就是这个类的一个对象。接下来就可以以此控件变量来使用控件了。

在正式开始收发数据前,要给控件设置适当的几个参数来初始化。

首先是指定端口号,使用方法m_mscomm.put_CommPort(1);,参数就是端口号,比如此处程序要使用COM1端口。

然后是波特率、奇偶校验、数据位和停止位,使用方法put_Settings(LPCTSTR newValue),参数是一个形如”*,*,*,*”字符串,比如我需要波特率4800,无奇偶校验,8位数据位和1作为停止位就可以如此操作,m_mscomm.put_Settings(_T(“4800, n, 8, 1”))。

m_mscomm.put_RThreshold(1)和m_mscomm.put_SThreshold(0)分别设定接收和发送数据的时候,引发接收数据的OnComm事件时缓冲区中的字符数量,0表示不触发OnComm事件,比如put_RThreshold(1)表示每接收到一个字符就处理OnComm事件。右击电话图标,选择“添加事件处理程序”,即可添加OnComm消息处理函数。

m_mscomm.put_InputLen(0)设定当前接收区数据长度为0,表示全部读取。

m_mscomm.put_InputMode(1)用来设定数据接收模式,1表示二进制,0表示文本。

m_mscomm.put_OutBufferSize(1024)和m_mscomm.put_InBufferSize(1024)分别设定输出和接收的缓冲区大小,单位是字节。

比如,现在要接收数据的话,可以如下初始化程序。

// 函数 BOOL CMSCommDemoDlg::OnInitDialog()  初始化过程
           
        m_Mscomm.put_CommPort(4);     //设定串口为 COM4
        m_Mscomm.put_Settings(_T("9600,n,8,1")); //设定波特率9600,无奇偶校验,8位数据位,1作为停止位
        m_Mscomm.put_InputMode(1);    //设定数据接收模式,1为二进制,0为文本
        m_Mscomm.put_InputLen(0);     //设定当前接收区数据长度
        m_Mscomm.put_InBufferSize(1024);   //设置输入缓冲区大小为1024 byte
        m_Mscomm.put_OutBufferSize(1024);   //设置输出缓冲区大小为1024 byte
        m_Mscomm.put_RThreshold(1);    //每接收到一个字符时,触发OnComm事件
        m_Mscomm.put_SThreshold(0);    //每发送一个字符时,不触发OnComm事件
 
        m_Mscomm.put_PortOpen(true);    //打开串口

初始化完成后就可以用m_mscomm.put_PortOpen(TRUE)来打开端口开始接收数据了。

根据我们在RThreshold中设定的参数,程序会在接收到参数中指定的字符后触发一个OnComm事件,我们就需要处理这个事件来提取接收到的数据。我们需要通过查询m_mscomm.get_CommEvent()来确定具体的事件类型,比如可能是发送也可能接收到了数据,比如在此我们要提取接收数据,事件对应的返回值应当是2。然后获得的数据就可以用m_mscomm.get_Input()来获得,这个函数返回一个VARIANT结构变量,如果我们接收的是字符串数据,那就是保存在bstrVal中,比如下面的代码就是在接收到数据时将接收到的字符串保存在str变量中。


OnComm消息处理部分:
void CMSCommDemoDlg::OnCommMscomm()
{
 // TODO: 在此处添加消息处理程序代码
 VARIANT m_input ;
 char * str ,*str1 ;
 int k , nEvent , i ;
 CString str2 ;
 nEvent = m_Mscomm.get_CommEvent() ;
 switch( nEvent )
 {
 case 2:
  k = m_Mscomm.get_InBufferCount() ;
  if( k > 0 )
  {
       str = (char*)(unsigned char*)m_Mscomm.get_Input().parray->pvData ;
  }
  i = 0;
  str1 = str ;
  while( i<k )
  {
       i++ ;
       str1++ ;
  }
  *str1 = '\0' ;
  str2 = (const char *) str ;
  m_strReceive = str2 ;  //m_strReceive 是关联接收编辑框的CString变量
  break ;
 default:
  break ;
 }
 UpdateData(false);

}

 

如果要发送数据的话,只需调用m_mscomm.put_Output(VARIANT newValue)将保存在newValue中的数据发送出去。在此我们可以使用一个COleVariant类对象来代替直接使用VARIANT类型变量,COleVariant直接提供了将字符串变量转化为兼容VARIANT类型的构造函数,比如我们将数据保存在CString类型的str变量中,然后用COleVariant 包一下送给put_Output ,如m_mscomm.put_Output(COleVariant(str))就可以将str中的字符通过串口发送出去。

发送数据部分:

bool CMSCommDemoDlg::ComSendData(void)
{
 int i , Count ;
 Count = m_strSend.GetLength();    //m_strSend 是关联发送编辑框的CString变量
 CByteArray m_Array ;
 m_Array.RemoveAll();
 m_Array.SetSize(Count);
 for( i=0 ; i<Count ; i++)
          m_Array.SetAt(i,m_strSend[i] );
 m_Mscomm.put_Output( COleVariant(m_Array) );
 
 return false;
}



virtual void OnCancel();
afx_msg void OnButtonToolSelStnLink();
DECLARE_EVENTSINK_MAP()
//}}AFX_MSG
DECLARE_MESSAGE_MAP()

提醒大家注意:
DECLARE_EVENTSINK_MAP() 就是这里,加上这个就好了!!!
//}}AFX_MSG
DECLARE_MESSAGE_MAP()


初学者还会遇到问题:如果是单文档应用程序,怎么添加MScomm控件呢?

很简单,打开“项目-->添加类-->ActiveX控件中的MFC类”然后弹出如下窗口:

 

 然后按图中标号执行,就成功添加控件了。之后利用向导对CView生成消息WM_CREATE响应函数,大家可以在图标托到About对话框中就行,在响应函数里添加初始化过程即可。也就完成了。

注意这里初始化要多加句:m_Mscomm.Create(NULL,WS_VISIBLE,CRect(0,0,0,0),this,IDC_MSCOMM1);  之后和对话框的一样了。

 

 

http://blog.163.com/ymkigeg@yeah/blog/static/823953012012117113820923/

 

VC2010基于MFC对话框的串口通信 采用mscomm控件无法接收:

部分源程序:

  1. void CcommtestDlg::OnBnClickedButtonOpen()  
  2.  {  
  3.  // TODO: 在此添加控件通知处理程序代码  
  4. m_mscomm.put_CommPort(3); //set com3  
  5.  m_mscomm.put_Settings("9600,n,8,1");//设置串口波特率9600,无校验,8位数据,1个停止位,  
  6. m_mscomm.put_InBufferSize(1024); //设置输入缓冲区大小  
  7. m_mscomm.put_OutBufferSize(1024);//设置输出缓冲区大小  
  8. m_mscomm.put_InputMode(1);//选择发送形式为二进制  
  9. m_mscomm.put_RThreshold(1);//当串口输入缓冲区有一个或者一个以上字符时激发ONCOMM事件转入ONCOMm事件处理程序  
  10. if(m_mscomm.get_PortOpen()) //检查串口状态,如果是打开的就把它关掉  
  11. {  
  12. m_mscomm.put_PortOpen(FALSE);  
  13.  }   
  14.  if(!m_mscomm.get_PortOpen())  
  15.  {  
  16.  m_mscomm.put_PortOpen(TRUE);  
  17.  m_mscomm.put_InputLen(0); //读取缓冲区全部内容  
  18. m_mscomm.get_Input();//预读,清空缓冲区  
  19. AfxMessageBox(_T("the com3 is ready"));  
  20.  }  
  21.  else  
  22.  {  
  23.  m_mscomm.put_OutBufferCount(0);  
  24.  AfxMessageBox(_T("the com3 is error"));  
  25.  }  
  26.  }  
  27.   
  28.   
  29.  void CcommtestDlg::OnBnClickedButtonClose()  
  30.  {  
  31.  // TODO: 在此添加控件通知处理程序代码  
  32. m_mscomm.put_PortOpen(FALSE);//关闭串口  
  33. AfxMessageBox(_T("the com3 is close"));  
  34.  }  
  35.   
  36.   
  37.  void CcommtestDlg::OnBnClickedButtonSend()  
  38.  {  
  39.  // TODO: 在此添加控件通知处理程序代码  
  40. UpdateData(true);  
  41.  char TxData[100];  
  42.  int Count = m_EditSend.GetLength();  
  43.   
  44.  for(int i = 0; i < Count; i++)  
  45.  TxData[i] = m_EditSend.GetAt(i);  
  46.   
  47.  CByteArray array;  
  48.  array.RemoveAll();  
  49.  array.SetSize(Count+2);  
  50.   
  51.  for(int i = 0; i < Count; i++)  
  52.  array.SetAt(i, TxData[i]);  
  53.  array.SetAt(Count, '\r');    //在发送的字符后加入\r\n  
  54.  array.SetAt(Count+1, '\n');  
  55.  m_mscomm.put_Output(COleVariant(array));  
  56.  m_EditSend.Empty();//清空编辑框  
  57. UpdateData(false);//更新编辑框内容  
  58. }  
  59. BEGIN_EVENTSINK_MAP(CcommtestDlg, CDialogEx)  
  60.  ON_EVENT(CcommtestDlg, IDC_MSCOMM1, 1, CcommtestDlg::OnCommMscomm1, VTS_NONE)  
  61.  END_EVENTSINK_MAP()  
  62.   
  63.   
  64.  void CcommtestDlg::OnCommMscomm1()  
  65.  {  
  66.  // TODO: 在此处添加消息处理程序代码  
  67. //static unsigned int cnt=0;  
  68.  VARIANT variant_inp;//计算机底层传回的是VARIANT数据类型  
  69. COleSafeArray safearray_inp;//由VARIANT派生的一种数据类型继承了VARIANT的特性  
  70. long len,k;  
  71.  BYTE rxdata[1024]; //定义BYTE数组大小作用类似于单片机的数据缓存区SBUF  
  72.  CString strtemp; //定义CString变量  
  73. if(m_mscomm.get_CommEvent ()==2 )//值为2时骸表括示接收缓冲区存在有效字符  
  74. {  
  75.  // cnt++;  
  76.  variant_inp=m_mscomm.get_Input();//读取缓冲区消息, 取得缓冲区所有内容赋给VARRINT型í变量variant_inp  
  77.  safearray_inp=variant_inp;//变量转换  
  78. len=safearray_inp.GetOneDimSize();//得到有效的数据长度  
  79. for(k=0;k<len;k++)  
  80.  {  
  81.  safearray_inp.GetElement(&k,rxdata+k);//Element元a素  
  82. }  
  83. for(k=0;k<len;k++) //将数组转化为CString型变量  
  84. {  
  85. BYTE bt=*(char*)(rxdata+k);    //字符型  
  86.             strtemp.Format("%c",bt);    //将字符送入临时变量strtemp存放  
  87.             m_EditReseive+=strtemp;  //加入对应字符串data中     
  88. CString temp="\r\n"//换行  
  89. m_EditReseive+=temp;  
  90.  }  
  91.  }  
  92.  UpdateData(FALSE);  
  93.  } 


http://bbs.csdn.net/topics/390750463

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值