串口程序在仪器研发中被广泛使用,常用的上位机串口程序编写有三种方法:一、采用MSComm控件,这种方法简单,但不适用于太复杂的系统;二、用Windows API函数实现串口通信,这种方法应用广泛但比较复杂;三、用CSerial等串口类实现,CSerial类是专门针对串口通信的,也较简单(这个可以看《用VC++实现单片机与PC机串口通信的三种方法》西安石油大学:曾自强)。
我这里完成的串口程序主要参考了百度文库中的《在VS(VC)2010中使用MSComm控件实现串口通信的详细步骤》(链接)、《解决WIN7系统中VS2010不能使用MSCOMM控件的问题》(链接),不过一些地方有些问题,所以自己写一个。
首先,最基本的,你得安装并破解好VS2010,并且有向PC发送串口信息的下位机(或者是另外一台电脑),然后我们就开始正文了。
一、解决WIN7系统VS2010中MSComm的安装问题
VS2010到底有没有自带的MSCOMM控件?两篇文章中说法各异,但是我在自己电脑上安装的VS2010里是没发现的。
如果你电脑里面已经有MSComm控件,就可以跳过这部分,直接看第二部分(“二、串口程序编写”),如果你不知道自己的电脑里面是否有该控件,你可以先按第二部分进行,直到发现没有时再过来安装控件。
1.下载控件并保存到指定位置
MSComm控件下载(链接)后,将解压的四个文件(MSCOMM.SRG、MSCOMM32.DEP、MSCOMM32.oca、mscomm32.ocx)拷贝到C:\Windows\System32(WIN7系统);C:\WINDOWS\system32(XP系统)。
2.注册
如果是WIN7系统,找到C:\Windows\System32(也就是控件文件保存位置)下的cmd.exe,右键”以管理员身份运行”(或者点”开始”,在”搜索程序和文件”中输入”cmd”,可以看到”cmd.exe”,右键”以管理员身份运行”);如果是XP系统,只能是在C:\Windows\System32里找到cmd.exe,右键打开(见下图)。
然后,WIN7输入:regsvr32 C:\Windows\System32\mscomm32.ocx XP输入:regsvr32C:\WINDOWS\system32\mscomm32.ocx 。会提示注册成功(见下图)。
3.查看注册结果
WIN7:点开始—>所有程序—>附件—>运行,XP:点开始—>运行。输入regedit启动注册表管理器,在其中找到HKEY_CLASSES_ROOT项下的Licenses项,在其中找到“4250E830-6AC2-11cf-8ADB-00AA00C00905”,双击看到键值为“kjljvjjjoquqmjjjvpqqkqmqykypoqjquoun”。(见下图)
4.在VS2010中查看控件是否可用
接下来启动VS2010,随便新建任意一个MFC工程,点开“ResourceView”—>“**.rc”—>“Dialog”,双击打开“ABOUTBOX”,在对话框上右键选择“Insert ActiveX Control”,在列表中查找是否有“Microsoft Communications Control,version 6.0”一项,若有,则说明控件注册成功。(如下图)
二、串口程序编写
1. 建立一个基于对话框的MFC工程。(见图)
2. 删除默认的“ok”“cancel”“TODO:在此放置对话框控件”,添加如下控件:
A.“打开串口”按钮: 从右侧的“Toolbox”拖放一个“Button”到对话框,并对该按钮右击,选择“properties”,将“Caption”改为“打开串口”,“ID”改为“IDC_BUTTON_OPEN”;
B.“关闭串口”按钮:方法同上,“Caption”改为“关闭串口”“ID”改为“IDC_BUTTON_CLOSE”;
C.“发送”按钮:方法同上,“Caption”改为“发送”“ID”改为“IDC_BUTTON_SEND”;
D.“发送编辑框”:从Toolbox中拖放一个“Editcontrol”,调整大小;
E.“接收编辑框”:同上。
F.“接收显示区”:相似地,从Toolbos中拖出一个Static Text,“Caption”改为“接收显示区”。
3. 添加串口通信控件
在对话框上右击选择“InsertActiveX Control”,滑动选择“Microsoft Communications Control,version 6.0”。添加控件后,对话框的左上角就会出现一个电话形状的图标。
4. 给控件添加变量
在控件(电话图标)上右键,选择“添加变量”,将变量命名为m_mscomm,点击完成,工程中会自动添加“mscomm.h”和“mscomm.cpp”两个文件。(如图)
5. 给两个编辑框添加变量
6. 添加三个按钮的事件
直接“双击”三个按钮,在UARTTestDlg.cpp文件中会自动增加如下几个函数,并自动关联消息映射。
void CSerial_programDlg::OnBnClickedButtonSend()
{
// TODO: Addyour control notification handler code here
}
void CSerial_programDlg::OnBnClickedButtonOpen()
{
// TODO: Addyour control notification handler code here
}
void CSerial_programDlg::OnBnClickedButtonClose()
{
// TODO: Addyour control notification handler code here
}
7. 添加串口控件的事件处理程序
右击控件(电话图标),选择“AddEvent Handle”,如图。
然后点击“Add and Edit”即可,在UARTDlg.cpp文件中会增加函数:
void CSerial_programDlg::OnCommMscomm1()
{
// TODO: Add your message handler code here
}
数据接收将在此函数中进行。
8. 打开串口及串口设置
voidCSerial_programDlg::OnBnClickedButtonOpen()
{
// TODO: Add your control notification handler code here
if (m_mscomm.get_PortOpen())//如果串口是打开的,则关闭串口
{
m_mscomm.put_PortOpen(FALSE);
}
m_mscomm.put__CommPort(3);//选择COM3,我笔记本本身没串口,usb转出来的串口号为3,可根据实际选择,但串口关闭等也要做相应更改
m_mscomm.put_InBufferSize(1024);//接收缓冲区
m_mscomm.put_OutBufferSize(1024);//发送缓冲区
m_mscomm.put_InputLen(0);//设置当前接收区数据长度为0,表示全部读取
m_mscomm.put_InputMode(1);//以二进制方式读写数据
m_mscomm.put_RThreshold(1);//接收缓冲区有1个及1个以上字符时,将引发接收数据的OnComm事件
m_mscomm.put_Settings(_T("9600,n,8,1"));//波特率9600,无校验,8个数据位,1个停止1位
if (!m_mscomm.get_PortOpen())//如果串口没有打开
{
m_mscomm.put_PortOpen(TRUE);//打开串口
AfxMessageBox(_T("串口3打开成功"));
}
else
{
m_mscomm.put_OutBufferCount(0);//
AfxMessageBox(_T("串口3打开失败!"));
}
}
9. 添加关闭串口按钮的消息响应函数
void CSerial_programDlg::OnBnClickedButtonClose()
{
// TODO: Add your control notification handler code here
m_mscomm.put_PortOpen(FALSE);
AfxMessageBox(_T("串口3已关闭!"));
}
10. 添加发送按钮消息响应函数
11. 接收数据
void CSerial_programDlg::OnCommMscomm1()
{
// TODO: Add your message handler code here
static unsigned int cnt=0;
VARIANTvariant_inp;
COleSafeArraysafearray_inp;
long len,k;
unsigned intdata[1024]={0};
byterxdata[1024];//设置BYTE数组
CStringstrtemp;
if (m_mscomm.get_CommEvent()==2)//值为2表示接收缓冲区内有字符
{
cnt++;
variant_inp= m_mscomm.get_Input();//读取缓冲区
safearray_inp= variant_inp;//变量转换
len= safearray_inp.GetOneDimSize();//得到有效的数据长度
for (k=0;k<len;k++)
{
safearray_inp.GetElement(&k,rxdata+k);
}
char c_char;
for (k=0;k<len;k++)
{
strtemp.Format(_T("%c"),*(rxdata+k));
m_EditReceive+=strtemp;
}
//CString temp=_T("\r\r\n");//换行
//m_EditReceive+=temp;
}
UpdateData(FALSE);
}
三、 程序运行效果及其他
程序运行效果略。
其他:如果是在单文档程序中,添加MSComm控件的方法为:打开“project”—>”MFC”—>”MFC Class From ActiveX Control”。