VS2010之MFC串口通信的编写教程
- 格式:doc
- 大小:5.86 MB
- 文档页数:32
利用 MFC 实现串行通信吉林大学尚金瑞01-7-30 上午 11:51:21--------------------------------------------------------------------------------在微软公司推出的Visual C++中,不仅可以利用串行通信控件或调用Windows API来进行串行通信,而且可以利用MFC CFile类来实现串行通讯。
这种通信方式与访问磁盘普通文件没有太大不同。
较简单的实现方式是利用VC++中的MFC向导建立一个支持MFC的工作台工程,添入如下相关代码即可。
1)打开一个串口需使用:CFile file;CFileException e;file.Open (portName, //example "COM1","COM2"CFile::modeReadWrite,&e);2)关闭一个串口需使用:file.Close();3)从端口进行读操作,需使用:char m_ReadBuff[UINTn];UINT nByte=file.Read (&m_ReadBuff, //buffer to store byteUINT nCount //number of bytes to read);4)从端口进行写操作,需使用:char m_WriteBuff[UINTn];file.Write (&m_WriteBuff, //buffer to store byteUINT nCount //number of bytes to write);5)配置串口串行端口创建时,必须对其进行设置以匹配与其对话的设备。
虽然可以通过操作系统设置这些参数,但也可以用Windows API 中的SetCommState()函数来设置它们。
一般地,可用如下程序设置它们:DCB dcb;::GetCommState( (HANDLE)file.m_hFile, &dcb );dcb.BaudRate = 1200,…;dcb.ByteSize = 7 or 8;dcb.StopBits = 0,1,2=0,1.5,2;dcb.Parity = 0-4=no,odd,even,mark,space;::SetCommState((HANDLE)file.m_hFile, &dcb );为了更好地控制端口可以利用SetCommTimeouts()函数打开或关闭超时功能,具体程序如下:COMMTIMEOUTS cto;::GetCommTimeouts((HANDLE)file.m_hFile , &cto );cto.ReadIntervalTimeout =0;cto.ReadTotalTimeoutMultiplier =0;cto.ReadTotalTimeoutConstant =0;cto.WriteTotalTimeoutMultiplier=0;cto.WriteTotalTimeoutConstant =0;::SetCommTimeouts((HANDLE)file.m_hFile , &cto );采用上面的程序,利用MFC CFile类进行串行通信,代码简单、编程量小,可应用于在线监测、自动化控制等许多方面,对科研、生产有着广泛的实用价值。
首先,打开VS2010,新建一个MFC 工程,我们命名为SCommT est。
删掉原来的两个按钮和一个静态文本,在标题栏上右键属性,然后更改标题名:串口通信助手1.0 beta。
画程序的界面首先画两个组框,分别为显示区和发送区。
然后在显示区内部画一个编辑框,ID 改为IDC_EDIT_RECV。
样式更改如下:在发送区内画一个编辑框,ID 改为IDC_EDIT_SEND,样式更改如下:最后画一个发送按钮就大功告成啦!按钮ID 改为IDC_BUTTON_SEND。
插入MSComm类添加一个MScomm 控件,就是这个控件为我们完成串口通信的功能。
右键添加变量接下来添加函数首先为MSComm 控件添加一个函数OnComm,主要用于接收串口发送来的消息然后为发送按钮添加一个函数OnButtonSend,主要用于给串口发送消息。
添加的方式是双击控件,修改函数名称,确认即可。
如下两图:首先,要记住,工程中有好几个CPP 文件和H 头文件,但是我们要添加的代码,都是写在SCommT estDlg.CPP 文件中的。
//---------------------------------------------------------------------------//添加的对串口的初始化语句if(m_cComm.get_PortOpen()) //如果发现串口本来是打开的,则关闭串口m_cComm.put_PortOpen(FALSE);m_cComm.put_CommPort(1); //选择COM1端口m_cComm.put_InputMode(1); //输入方式为二进制方式m_cComm.put_InBufferSize(1024); //设置输入缓冲区m_cComm.put_OutBufferSize(512); //设置输出缓冲区m_cComm.put_Settings(TEXT("9600,n,8,1"));//波特率9600,无校验,8个数据位,1个停止位m_cComm.put_Settings(_T("9600,n,8,1"));if(!m_cComm.get_PortOpen()){m_cComm.put_PortOpen(TRUE); //打开串口m_cComm.put_RThreshold(1); //每当接收缓冲区有1个字符则接收串口数据m_cComm.put_InputLen(0); //设置当前缓冲区长度为0m_cComm.get_Input(); //预读缓冲区以清除残留数据}elseAfxMessageBox(TEXT("打开端口失败!"),MB_ICONSTOP,0);AfxMessageBox(_T("打开端口失败!"),MB_ICONSTOP,0);//---------------------------------------------------------------------------void CSCommT estDlg::OnComm(){// TODO: 在此添加命令处理程序代码//---------------------------------------------------------------------------//从串口接收数据并显示在编辑框中VARIANT variant_inp;COleSafeArray safearray_inp;long len,k;byte rxdata[512]; //设置BYTE数组CString strtemp;if(m_cComm.get_CommEvent()==2) //值为2表示接收缓冲区内有字符{variant_inp=m_cComm.get_Input(); //读缓冲区消息safearray_inp=variant_inp; ///变量转换len=safearray_inp.GetOneDimSize(); //得到有效的数据长度for(k=0;k<len;k++)safearray_inp.GetElement(&k,rxdata+k);for(k=0;k<len;k++) //将数组转换为CString型变量{char bt=*(char*)(rxdata+k); //字符型strtemp.Format(TEXT("%c"),bt); //将字符送入临时变量strtemp存放strtemp.Format(_T("%c"),bt);m_strRecvData+=strtemp; //加入接收编辑框对应字符串}}CString temp=(TEXT("\r\n")); //显示完成后要自动换行m_strRecvData+=temp;UpdateData(FALSE); //更新编辑框内容//--------------------------------------------------------------------------- }void CSCommT estDlg::OnButtonSend(){// TODO: 在此添加控件通知处理程序代码//---------------------------------------------------------------------------//单击发送按钮的操作UpdateData(true); //读取编辑框内容m_cComm.put_Output(COleVariant(m_strSendData));//发送数据m_strSendData.Empty(); //发送后清空输入框UpdateData(false); //更新编辑框内容//对发送的数据进行强制类型转换,由CString 字符串数据转换为VARIANT 类型。
mfc 2010 串口例程摘要:1.MFC 2010 简介2.串口通信基本概念3.串口通信例程介绍4.例程功能及应用场景5.总结与展望正文:MFC(Microsoft Foundation Class)2010 是微软提供的一款用于开发Windows 应用程序的类库。
它可以帮助开发者更轻松地创建高质量的Windows 应用程序。
在众多功能中,MFC 2010 也提供了串口通信相关的类和方法,以便开发者能够方便地进行串口通信。
串口通信(Serial Communication)是一种在两个设备之间传输数据的方式。
它通过串行传输数据,即将数据位逐个传输,而非并行传输。
串口通信在电子设备、计算机外设、通信设备等领域有着广泛的应用。
MFC 2010 提供了丰富的串口通信例程,可以帮助开发者轻松实现串口通信功能。
这些例程包括了串口配置、数据发送与接收、异常处理等功能。
通过这些例程,开发者可以快速地搭建起一个串口通信程序,并对其进行调试和优化。
以下是使用MFC 2010 串口例程的一个简单示例:首先,需要创建一个串口对象,并配置串口参数,如波特率、数据位、停止位等。
接着,可以通过打开或关闭串口对象来开启或关闭串口通信。
在通信过程中,可以使用发送和接收数据的方法,将数据从串口发送到其他设备,或从其他设备接收数据。
同时,需要对串口通信过程中的异常情况进行处理,以保证程序的稳定性和可靠性。
MFC 2010 串口例程广泛应用于各种需要进行串口通信的场合,如工业自动化、数据采集、通信设备等。
通过使用这些例程,开发者可以节省大量的开发时间,专注于实现应用程序的核心功能。
总结来说,MFC 2010 提供了强大的串口通信功能,通过例程的方式,帮助开发者快速实现串口通信功能。
VS2010/MFC编程入门之三(VS2010应用程序工程中文件的组成结构)这里将以前面的生成应用程序HelloWorld的文件结构为例,讲解VS2010应用程序工程中文件的组成结构。
用应用程序向导生成框架程序后,我们可以在之前设置的Location下看到以解决方案名命名的文件夹,此文件夹中包含了几个文件和一个以工程名命名的子文件夹,这个子文件夹中又包含了若干个文件和一个res文件夹,创建工程时的选项不同,工程文件夹下的文件可能也会有所不同。
如果已经以Debug方式编译链接过程序,则会在解决方案文件夹下和工程子文件夹下各有一个名为“Debug”的文件夹,而如果是Release方式编译则会有名为“Release”的文件夹。
这两种编译方式将产生两种不同版本的可执行程序:Debug版本和Release 版本。
Debug版本的可执行文件中包含了用于调试的信息和代码,而Release版本则没有调试信息,不能进行调试,但可执行文件比较小。
将所有文件分为6个部分:解决方案相关文件、工程相关文件、应用程序头文件和源文件、资源文件、预编译头文件和编译链接生成文件。
1.解决方案相关文件解决方案相关文件包括解决方案文件夹下的.sdf文件、.sln文件、.suo文件和ipch文件夹。
.sdf文件和ipch目录一般占用空间比较大,几十兆甚至上百兆,与智能提示、错误提示、代码恢复和团队本地仓库等相关。
如果你觉得不需要则可以设置不生成它们,方法是点击菜单栏Tools->Options,弹出Options对话框,选择左侧面板中Text Editor->C/C++->Advanced,右侧列表中第一项Disable Database由False改为True就可以了,最后关闭VS2010再删除.sdf文件和ipch目录以后就不会再产生了。
但关闭此选项以后也会有很多不便,例如写程序时的智能提示没有了。
.sln文件和.suo文件为MFC自动生成的解决方案文件,它包含当前解决方案中的工程信息,存储解决方案的设置。
VS2010之MFC串口通信教程
说明:本人也是刚刚入门MFC,参照一些资料和源代码就实验做了这么一个串口通信工具!资料来源主要有鸡啄米博客网站,里面有详细的学习教程!网上的VS2010源代码都比较少,建议大家先理解一个源代码的构架和结构再深入学习!本文档可以一步一步教你从建立工程到实验调试,是一个非常完整的教程!非常适合新手练习!
——贺州学院大学生创新基地实验室
在制作串口通信所遇到的问题:编辑框的滚动条不会随着数据的更新保持在最后一行!
接下来我们开始讲解MFC串口通信的制作:
一、打开VS2010软件,然后新建一个项目,如下图所示;
我们要用到就是对话框模块,所以选择如下图所示
最大化框最好别选,因为本人现在也没搞出来;
点击完成就新建好一个工程了,等资源就绪之后我们就可以进行制作了;
我们可以看到就绪之后的界面如下图所示,按照步骤把原来的静态文本框和确定按钮、取消按钮删掉;
二、为我们的对话框添加控件添加两个组合边框,并放置好位置;
修改组合边框显示的名称;
在组合边框里面添加编辑文本框;
在这一步一定要小心选择右边的属性;
这一步是把串口控件添加到对话框中来;选择我们需要的串口控件如下图所示;
三、为编辑框,Combox框,串口控件添加变量;
四、为按钮和串口控件添加程序函数
void C串口V2Dlg::OnBnClickedButtonOpen()//打开串口按钮程序
{
// TODO: 在此添加控件通知处理程序代码?
CString str,str1,n; //定义字符串
GetDlgItemText(IDC_BUTTON_OPEN,str);
CWnd *h1;
h1=GetDlgItem(IDC_BUTTON_OPEN); //指向控件的caption
if(!m_mscom.get_PortOpen())
{
m_comb2.GetLBText(m_comb2.GetCurSel(),str1);//取得所选的字符串,并存放在str1里面
str1=str1+','+'n'+','+'8'+','+'1'; //这句话很关键
m_mscom.put_CommPort((m_comb1.GetCurSel()+1)); //选择串口
m_mscom.put_InputMode(1); //设置输入方式为二进制方式
m_mscom.put_Settings(str1); //波特率为(波特率组Á合框)无校验,8数据位,1个停止位m_mscom.put_InputLen(1024); //设置当前接收区数据长度为1024
m_mscom.put_RThreshold(1); //缓冲区一个字符引发事件
m_mscom.put_RTSEnable(1); //设置RT允许
m_mscom.put_PortOpen(true); //打开串口
if(m_mscom.get_PortOpen())
{
str=_T("关闭串口");
UpdateData(true);
h1->SetWindowText(str); //改变按钮名称为‘’关闭串口”
}
}
else
{
m_mscom.put_PortOpen(false);
if(str!=_T("打开串口))
{
str=_T("打开串口");
UpdateData(true);
h1->SetWindowText(str); //改变按钮名称为打开串口}
}
}
void C串口V2Dlg::OnBnClickedButtonSend()//发送数据按钮程
{
// TODO: 在此添加控件通知处理程序代码?
UpdateData(true); //更新控件数据
m_mscom.put_Output(COleVariant(m_Editsend));//把发送编辑框的数据发送出去}
void C串口V2Dlg::OnBnClickedButtonClean()//清除数据按钮程序{
// TODO: 在此添加控件通知处理程序代码
m_EditReceive=_T(""); //给接收编辑框发送空格符
UpdateData(false); //更新数据
}
void C串口V2Dlg::OnBnClickedButtonClose()//退出按钮程序{
// TODO: 在此添加控件通知处理程序代码
if(m_mscom.get_PortOpen())
m_mscom.put_PortOpen(false);
CDialogEx::OnCancel();
}
void C串口V2Dlg::OnCommMscomm1()//串口控件程序
{
// TODO: 在此处添加消息处理程序代码
if(m_mscom.get_CommEvent()==2)
{
char str[1024]={0};
long k;
VARIANT InputData=m_mscom.get_Input(); //读缓冲区
COleSafeArray fs;
fs=InputData; //VARIANT型变À量转换为COleSafeArray型变量
for(k=0;k<fs.GetOneDimSize();k++)
fs.GetElement(&k,str+k); //转换为BYTE型数组
m_EditReceive+=str; // 接收到编辑框里面
//SetTimer(1,10,NULL); //延时10ms
UpdateData(false);
}
}
// 串口选择组合框
CString str;
int i;
for(i=0;i<15;i++)
{
str.Format(_T("com %d"),i+1);
m_comb1.InsertString(i,str);
}
m_comb1.SetCurSel(0);//预置COM口
//波特率选择组合框
CString str1[]={_T("300"),_T("600"),_T("1200"),_T("2400"),_T("4800"),_T("9600"), _T("19200"),_T("38400"),_T("43000"),_T("56000"),_T("57600"),_T("115200")};
for(int i=0;i<12;i++)
{
int judge_tf=m_comb2.AddString(str1[i]);
if((judge_tf==CB_ERR)||(judge_tf==CB_ERRSPACE))
MessageBox(_T("build baud error!"));
}
m_comb2.SetCurSel(5);//预置波特率为"9600"
写完之后编译程序
五、调试我们写好的串口工具
我们下面用51单片机调试一下,结果也是成功的;
m_Edit.SetSel(-1, -1);
this->SetDlgItemTextW(IDC_EDIT1,m_EditReceive);//将m_EditReceive内容显示到ID为IDC_EDIT1的编辑框的最后位置
m_Edit.LineScroll(m_Edit.GetLineCount()-1,0);//将垂直滚动条滚动到最后一
修改一下接收编辑框的属性,发送编辑框不用做修改;再调试一下发现问题解决了!
六、修改图标和软件信息
我们去到项目所在的文件夹中,如下图所示;
The End!
作者:刘小二
2014年5月2日星期五。