作者:xqhrs232
转自:http://blog.youkuaiyun.com/xqhrs232/article/details/16897313
原文地址::http://hi.baidu.com/cahbb/item/5d8ff9aa6d21ac766dd45566
相关网帖
1、在VS2005中使用mscomm控件----http://163n.blog.163.com/blog/static/56035552201011257315995/
2、vs2005 下使用串口控件进行串口通信的示例----http://download.youkuaiyun.com/detail/wq1104/5010988
3、VS2005 VC2005 MSCOMM 控件添加方法----http://hi.baidu.com/yorkbluedream/item/0a49a94b2470740c6dc2f0bd
4、VS2005下可用的mscomm组件----http://download.youkuaiyun.com/detail/xqhrs232/6597241
个人在工作中,需要用到串口和单片机进行通信。以前一点没接触过。这个对于一个熟悉vc的人,估计不是问题的问题。对于我来说,搞了几乎两天。这两天是在找示例,自已是一点也不会呀。
现在将找到的东西收集起来。供其他人参考。
环境是vs2005 +微软自带的串口控件+基于对话框的MFC程序,就是一个小电话样子的东西。
1:先将这个控件参加到工具箱中。
工具箱上面右键-》选择项-》com组件-》找到MICrosoft Communications Control,version 6.0
点击确定,这个组件会出现在工具框中。
将这个组件拖到对话框中。
2:在组件上右键,增加一个控件变量。
3:在窗口中,增加两个按钮,一个是打开串口,一个是发送数据,一个是关闭串口。
4:在窗口中,再增加两个edit 控件,用了写发送的内容,和显示接收的内容。
将2个edit控件,增加两个对应的Cstring 变量。
5:在组件,右键-》增加事件处理-》会自动给出一个处理函数。点编辑,会出现一个空的代码段。
代码如下:
// 以下三行,是增加处理函数时,系统自动自已增加的。
BEGIN_EVENTSINK_MAP(Cusart3Dlg, CDialog)
ON_EVENT(Cusart3Dlg, IDC_MSCOMM1, 1, Cusart3Dlg::OnCommMscomm1, VTS_NONE)
END_EVENTSINK_MAP()
void Cusart3Dlg::OnCommMscomm1()//串口有数据时的,处理函数。
{
// TODO: 在此处添加消息处理程序代码
static UINT cnt=0;
VARIANT variant_inp;
COleSafeArray safearray_inp;
long len,k;
UINT data[1024]={0};
byte rxdata[1024];
CString strtemp;
if(m_com.get_CommEvent()==2)//事件值为2表示接收缓冲区内有字符
{
cnt++;
variant_inp=m_com.get_Input();//读缓冲区
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型变量
{
strtemp.Format(TEXT("%c"),*(rxdata+k));//字符型
m_edit2+=strtemp;
}
}
UpdateData(FALSE);
}
void Cusart3Dlg::OnBnClickedButton2()//串口初始化,打开串口
{
// TODO: 在此添加控件通知处理程序代码
if(m_com.get_PortOpen())
{m_com.put_PortOpen(FALSE);}
m_com.put__CommPort(3);//选择com3
m_com.put_InBufferSize(1024);//接收缓冲区
m_com.put_OutBufferSize(1024);//发送缓冲区
m_com.put_InputLen(0);//设置当前接收区数据长度为0,表示全部读取
m_com.put_InputMode(1);// 以二进制方式检取数据
m_com.put_RThreshold(1);//参数1表示每当串口接收缓冲区中有多于或等
//于1个字符时将引发一个接收数据的OnComm事件
m_com.put_Settings(_T("9600,n,8,1"));//波特率9600,无校验,8个数据位,1个停止位
if(!m_com.get_PortOpen())
{ m_com.put_PortOpen(TRUE);
AfxMessageBox(_T("已打开"));
}
else
{
m_com.put_OutBufferCount(0);
AfxMessageBox(_T("打开失败"));
}
}
void Cusart3Dlg::OnBnClickedButton3()//发送数据
{
// TODO: 在此添加控件通知处理程序代码
UpdateData(TRUE);//读取编辑框内容
m_com.put_Output(COleVariant(m_send));//发送数据
m_send.Empty();//清空edit内容
UpdateData(false);//更新内容
}
void Cusart3Dlg::OnBnClickedButton4()//关闭串口
{
// TODO: 在此添加控件通知处理程序代码
m_com.put_PortOpen(FALSE);//关闭串口
}
//==============以上内容为第一次编写,个人实际使用中发现上面代码存在问题,有内存泄漏问题,找资料,发现如下原因
(1): byte rxdata[1024]; //这个的定义放在if语句的下面定义,不是放在它的前面定义,这要好像可以不让它一直存
CString strtemp;
if(m_com.get_CommEvent()==2)//事件值为2表示接收缓冲区内有字符
{ 将(1):byte rxdata[1024];,放在这个地方。
//-------------------
还有一个地方要改,就是定义的 VARIANT 变量,要进行清除操作,防止它的内存泄漏。
VARIANT variant_inp; //定义语句
VariantInit(&variant_inp);//紧接着就要初始化它。
.................................
VariantClear(&variant_inp); //在使用它之前 ,要清除一下
variant_inp=m_com.get_Input();//读缓冲区,实际使用它
safearray_inp=variant_inp;//VARIANT型变量转换为ColeSafeArray型变量
VariantClear(&variant_inp); //使用后要清除它
//========================================================================================
备注::
1>一般装VS2005没有MSCOMM这个组件,但装VC++6.0应该有这个组件,所以VS2005下要用这个组件最好去下一个MSCOMM组件并注册到系统里面去,这样在VS2005下才可以用
2>MSCOMM这个组件跟VB没有关系,所以即使装了VB这个组件也不一定可以看到!!!