VC++60实现串口.docx
- 文档编号:15339614
- 上传时间:2023-07-03
- 格式:DOCX
- 页数:57
- 大小:617.02KB
VC++60实现串口.docx
《VC++60实现串口.docx》由会员分享,可在线阅读,更多相关《VC++60实现串口.docx(57页珍藏版)》请在冰点文库上搜索。
VC++60实现串口
第6章VisualC++串口通信程序
设计典型实例
利用VisualC++开发串口通信程序既可以使用MSComm控件也可以调用WindowsAPI函数。
不过,只要MSComm可以被选用,它几乎总是我们推荐的选择。
在本章提供的串口通信程序设计中,PC与单片机、PC与智能仪表、PC与PLC、PC与GSM短信模块等串口通信任务的实现均采用MSComm控件。
6.1PC与PC串口通信程序设计
当两台串口设备通信距离较近时,可以直接连接,最简单的情况,在通信中只需3根线(发送线、接收线、信号地线)便可实现全双工异步串行通信。
本设计通过两台PC串口三线连接,介绍了利用API函数和MSComm控件设计串口通信程序的方法,包括字符与文件的发送与接收。
6.1.1PC与PC串口通信程序设计目的
设计目的有以下两个方面。
(1)掌握PC与PC串口通信的线路连接方法。
(2)利用VisualC++API函数和MSComm控件实现PC与PC串口通信的程序设计方法。
6.1.2PC与PC串口通信程序设计用软、硬件
本设计用到的硬件和软件清单见表6-1。
表6-1设计用软、硬件
序号
名称
数量
1
PC或IPC
1
2
串口通信线(三线制)
1
3
VisualC++6.0
1
6.1.3PC与PC串口通信程序硬件线路
线路说明:
在计算机通电前,如图6-1所示,将两台PC通过串口线连接起来:
PC中A串口COM1端口的TXD与PC中B串口COM1端口的RXD相连;PC中A串口COM1端口的RXD与PC中B串口COM1端口的TXD相连;PC中A串口COM1端口的GND与PC中B串口COM1端口的GND相连。
6.1.4PC与PC串口通信程序设计任务
利用VisualC++API函数和MSComm控件编写程序实现PC与PC串口通信。
(1)两台计算机互发字符并自动接收,如一台计算机输入字符串“Pleasereturnabc123”,执行“发送字符”命令,另一台计算机若收到,就输入字符串“abc123”,执行“发送字符”命令,信息返回到第一组的计算机。
实际上就是编写一个简单的双机聊天程序。
(2)将文本文件或二进制文件通过串口从一台计算机传送到另一台计算机。
图6-1PC与PC串口通信线路
6.1.5任务实现
6.1.5.1利用API函数实现字符发送与接收
1.建立工程
(1)启动VisualC++6.0,执行“文件”菜单中的“新建”命令,显示新建对话框,选择“MFCAppWizard(exe)”工程类型,输入需要创建工程的名称“pc_pc_api”和目录。
图6-2程序界面
(2)按照弹出的应用向导对话框依次填写,第1步选择基于对话框,其他均采用默认。
(3)单击“完成”,将会弹出一个关于新工程信息的对话框。
单击“确定”按钮。
这样MFC向导便自动生成了一个名称为pc_pc_api的工程。
2.资源创建
(1)应用程序中添加了一个对话框资源IDD_PC_PC_API_DIALOG,打开属性对话框,将对话框标题改为“PC与PC串口通信API”。
(2)删除对话框中原来的Static文本,用面板为对话框添加如表6-2所示的控件,并按照图6-2所示放置。
表6-2对话框的控件类型、ID及相关属性
控件类型
ID号
标题
属性
功能
静态文本
默认
显示接收字符区
默认
标签
静态文本
默认
输入发送字符区
默认
标签
编辑框
IDC_receive
——
Horizontalscroll(√)
显示接收字符区
Mutiline(√)
编辑框
IDC_send
——
Horizontalscroll(√)
显示发送字符区
Mutiline(√)
按钮
IDOK
发送
默认
发送字符命令
按钮
IDCANCEL
退出程序
默认
关闭程序命令
(3)添加成员变量,在“查看”菜单中或在对话框上单击鼠标右键,打开“ClassWizard”对话框中的“MemberVariables”标签,选中所需的控件ID号,双击鼠标左键或单击AddVariables按钮,依次为表6-3中所列控件增加成员变量。
表6-3成员变量
控件ID号
变量类型
变量名
IDC_receive
CString
m_strReceive
IDC_send
CString
m_strSend
(4)切换到ClassWizard的MessageMaps标签页或在对话框中双击每一个按钮,为“发送”、“退出”按钮分别添加ON_BN_CLICKED消息响应函数OnOK(),OnCancel()。
3.程序代码设计
窗体模块程序如下:
(1)在pc_pc_apiDlg.cpp文件的开始处,增加全局变量、消息和线程函数,代码如下:
constCM_RECEIVE=WM_USER+100;//自定义一个消息
OVERLAPPEDtOverLaped={0};//线程函数使用的OVERLAPPED结构
OVERLAPPEDwOverLaped={0};//写操作使用的OVERLAPPED结构
OVERLAPPEDrOverLaped={0};//读操作使用的OVERLAPPED结构
BOOLIsFun=True;//线程是否运行
BOOLIsStop=False;//数据是否发送完毕
DWORDThreadFunction(LPVOIDpParam)//线程函数
{
DWORDdwEvtMask,dwResult;
tOverLaped.hEvent=CreateEvent(NULL,True,False,NULL);//创建一个事件
while(IsFun)
{
WaitCommEvent(((CPc_pc_apiDlg*)AfxGetMainWnd())->hCom,&dwEvtMask,&tOverLaped);//等待窗口事件
dwResult=WaitForSingleObject(tOverLaped.hEvent,100);//如果事件没有信号,延时0.1s
switch(dwResult)
{
caseWAIT_OBJECT_0:
//事件对象有信号
switch(dwEvtMask)
{
caseEV_RXCHAR:
//接收到数据
{
if(IsStop)//发送停止
{
IsStop=False;
//发送消息,由消息处理函数接收数据
:
:
PostMessage(AfxGetMainWnd()->m_hWnd,CM_RECEIVE,0,(LPARAM)EV_RXCHAR);
}
break;
}
}
break;
}
}
return0;
}
(2)在BEGIN_MESSAGE_MAP消息映射代码中,添加自定义消息映射,代码如下:
BEGIN_MESSAGE_MAP(CPc_pc_apiDlg,CDialog)
//{{AFX_MSG_MAP(CPc_pc_apiDlg)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_MESSAGE(CM_RECEIVE,OnRecieveData)/添加自定义消息
ON_WM_QUERYDRAGICON()
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
(3)设置初始化函数OnInitDialog(),添加代码实现对话框串口通信的初始化工作,如下:
BOOLCPc_pcDlg:
:
OnInitDialog()
{…//VC自动生成的代码
//TODO:
Addextrainitializationhere
CSeriesPort();
returnTrue;//returnTrueunlessyousetthefocustoacontrol
}
(4)实现发送按钮、退出按钮相应的消息响应函数OnOK(),OnCancel()。
代码如下:
voidCPc_pc_apiDlg:
:
OnOK()
{
//TODO:
Addextravalidationhere
UpdateData(True);
DWORDres;
DWORDfactdata=0;
wOverLaped.hEvent=CreateEvent(NULL,True,False,NULL);//创建一个事件对象
IsStop=False;
if(WriteFile(hCom,m_strSend,m_strSend.GetLength(),&factdata,&wOverLaped))//开始发送数据
{
IsStop=True;
}
else
{
res=WaitForSingleObject(wOverLaped.hEvent,5000);//延时5秒,等待数据发送
if(WAIT_OBJECT_0==res)//如果事件处于有信号状态,表示发送完成
{
IsStop=True;
}
else
IsStop=False;
Sleep(500);//延时500毫秒
}
}
voidCPc_pc_apiDlg:
:
OnCancel()
{
//TODO:
Addextracleanuphere
CloseHandle(hCom);
CDialog:
:
OnCancel();
}
(5)为了实现API函数配置串口并打开串口,在pc_pc_apiDlg.cpp中增加成员函数,具体代码如下:
voidCPc_pc_apiDlg:
:
CSeriesPort()//配置并打开串口
{
hCom=CreateFile("COM1",//打开串口1
GENERIC_READ|GENERIC_WRITE,//允许读和写操作
0,//独占方式
NULL,
OPEN_EXISTING,//打开一个存在的串口
FILE_ATTRIBUTE_NORMAL|FILE_FLAG_OVERLAPPED,//异步方式打开
NULL
);
if(hCom==INVALID_HANDLE_VALUE)
{
MessageBox("端口打开失败.");
return;
}
SetupComm(hCom,1024,1024);//设置发送和接收缓冲区大小
//设置串口信息
DCBdcb;
GetCommState(hCom,&dcb);
dcb.BaudRate=9600;
dcb.fBinary=True;
dcb.fParity=True;
dcb.ByteSize=8;
dcb.Parity=ODDPARITY;
dcb.StopBits=ONESTOPBIT;
if(!
SetCommState(hCom,&dcb))
{
MessageBox("掩码设置失败.","提示");
return;
}
if(!
SetCommMask(hCom,EV_RXCHAR|EV_TXEMPTY))
{
MessageBox("掩码设置失败.","提示");
return;
}
DWORDparam;
hThread=CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ThreadFunction,¶m,0,&dwThreadID);
if(hThread==INVALID_HANDLE_VALUE)
{
MessageBox("线程创建失败.","提示",64);
return;
}
IsFun=True;
}
(6)为了实现API函数自定义消息处理,用于接收消息,在pc_pc_apiDlg.cpp中增加成员函数,具体代码如下:
//自定义消息处理函数,用于接收消息
voidCPc_pc_apiDlg:
:
OnRecieveData(WPARAMwParam,LPARAMlParam)
{
DWORDres,factbyte;
memset(DataBuffer,0,1024);//初始化数据缓冲区
COMSTATrst;
ClearCommError(hCom,&res,&rst);//清空串口错误标志,记录当前通信状态
rOverLaped.hEvent=CreateEvent(NULL,True,False,NULL);//创建一个事件对象
if(ReadFile(hCom,DataBuffer,rst.cbInQue,&factbyte,&rOverLaped))
//读取数据到缓冲区中
{
DataBuffer[rst.cbInQue]=0;
IsStop=False;
}
else
{
res=WaitForSingleObject(rOverLaped.hEvent,5000);
}
IsStop=False;
m_strReceive+=DataBuffer;
UpdateData(false);
}
4.编译运行程序
程序设计、调试完毕,执行菜单中的“启动”命令或单击工具栏中的“启动”快捷按钮,运行程序。
(1)首先在程序窗体中发送字符区输入要发送的字符,单击“发送数据”按钮,发送区的字符串通过COM1口发送出去。
(2)另一台计算机发送数据,本计算机自动读入并显示在接收数据区中。
程序运行界面如图6-3所示。
图6-3程序运行界面
6.1.5.2利用MSComm控件实现文件发送与接收
1.建立工程
(1)启动VisualC++6.0,执行“文件”菜单中的“新建”命令,显示新建对话框,选择“MFCAppWizard(exe)”工程类型,输入需要创建工程的名称“pc_pc”和目录。
(2)按照弹出的应用向导对话框依次填写,第1步选择基于对话框,其他均采用默认。
(3)单击“完成”按钮,将会弹出一个关于新工程信息的对话框,如图6-4所示。
单击“确定”按钮。
这样MFC向导便自动生成了一个名称为pc_pc的工程。
图6-4新建工程信息
2.资源创建
(1)应用程序中添加了一个对话框资源IDD_pc_pc_DIALOG,打开属性对话框,将对话框标题改为“基于MFC的串口通信”。
(2)为了实现计算机与计算机的串口通信,添加MScomm控件。
选择“工程”菜单中的“添加工程”下的“ComponentsandControls”选项,在弹出的对话框中双击“RegisteredActiveXControls”项,选择“MicrosoftCommunicationsControl,version6.0”项,单击“Insert”按钮,在弹出的对话框中单击“OK”按钮,再在弹出的对话框中单击“结束”按钮关闭对话框,所选择的控件就会出现在“控件面板”中,然后将其添加到对话框中相应位置。
(3)删除对话框中原来的Static文本,用面板为对话框添加如表6-4所示的控件,并按照图6-5所示放置。
表6-4对话框的控件类型、ID及相关属性
控件类型
ID号
标题
属性
功能
静态文本
默认
显示接受字符区
默认
标签
静态文本
默认
输入发送字符区
默认
标签
编辑框
IDC_receive
——
Horizontalscroll(√)
显示接受字符区
Mutiline(√)
编辑框
IDC_send
——
Horizontalscroll(√)
显示发送字符区
Mutiline(√)
Wantreturn(√)
MSComm
IDC_MSCOMM1
在程序中设置
默认
串口参数设置
按钮
IDOK
发送
默认
发送字符命令
按钮
IDC_BUTTON1
保存发送字符
默认
保存发送字符命令
按钮
IDC_BUTTON2
选择发送文件
默认
选择发送文件命令
按钮
IDCANCEL
退出程序
默认
关闭程序命令
图6-5程序界面
(4)添加成员变量,在“查看”菜单中或在对话框上单击鼠标右键,打开“ClassWizard”对话框中的“MemberVariables”标签,选中所需的控件ID号,双击鼠标左键或单击AddVariables按钮,依次为表6-5中所列控件增加成员变量。
表6-5成员变量
控件ID号
变量类型
变量名
IDC_MSCOMM1
CMSComm
m_ctrlComm
IDC_receive
CString
m_strReceive
IDC_send
CString
m_strSend
IDC_send
CEdit
m_ctrlSend
(5)切换到ClassWizard的MessageMaps标签页或在对话框中双击每一个按钮,为“发送”,“退出”按钮分别添加ON_BN_CLICKED消息响应函数OnOK(),OnCancel()。
(6)在对话框中双击MSComm控件,为MSComm控件添加OnComm消息响应函数OnOnCommMscomm1()。
3.函数代码实现
(1)在pc_pcDlg.cpp文件的开始处,增加全局变量,代码如下:
CStringstrDirFile;//保存文件路径的变量
(2)在pc_pcDlg.cpp文件中,设置初始化函数OnInitDialog(),添加代码实现对话框各控件的初始化工作,如下:
BOOLCPc_pcDlg:
:
OnInitDialog()
{…//VC自动生成的代码
//TODO:
Addextrainitializationhere
m_ctrlComm.SetCommPort
(1);//选择COM1
m_ctrlComm.SetInputMode
(1);//输入方式为二进制方式
m_ctrlComm.SetInBufferSize(1024);//设置输入缓冲区大小
m_ctrlComm.SetOutBufferSize(512);//设置输出缓冲区大小,波特率9600,无校验,8个数据位,1个停止位
m_ctrlComm.SetSettings("9600,n,8,1");
if(!
m_ctrlComm.GetPortOpen())
m_ctrlComm.SetPortOpen(True);//打开串口
m_ctrlComm.SetRThreshold
(1);//参数1表示每当串口接收缓冲区中有多于或等于1个字符时将引发一个接收数据的OnComm事件
m_ctrlComm.SetInputLen(0);//设置当前接收区数据长度为0
m_ctrlComm.GetInput();//先预读缓冲区以清除残留数据
returnTrue;//returnTrueunlessyousetthefocustoacontrol
}
(3)实现保存发送字符按钮、选择发送文件按钮、发送按钮、退出按钮相应的消息响应函数OnOK(),OnCancel()。
代码如下:
voidCPc_pcDlg:
:
OnButton1()//保存发送字符
{
//TODO:
Addyourcontrolnotificationhandlercodehere
UpdateData(true);
if(m_strSend!
="")
{
CFileDialogdlg(false,"txt",_T("shuju.txt"),NULL,"Text(*.txt)|*.txt|AllFiles(*.*)|*.*||",NULL);
dlg.m_ofn.lpstrTitle=_T("请选择保存路径:
");
if(dlg.DoModal()==IDOK)
{
strDirFile=dlg.GetPathName();
CFilefile
(strDirFile,CFile:
:
modeCreate|CFile:
:
modeReadWrite|CFile:
:
shareExclusive);
file.Write(m_strSend,m_strSend.GetLength());
UpdateData(true);
file.Close();
}
}
else
{
MessageBox("请输入您要发送的字符串!
","保存为文件");
m_ctrlSend.SetFocus();
}
}
voidCPc_pcDlg:
:
OnButton2()//选择发送文件
{
//TODO:
Addyourcontrolnotificationhandlercodehere
CStringstrf;
strf="TxtFiles(*.txt)|*.txt||";
CFileDialogdlg(True,NULL,NULL,OFN_EXPLORER|OFN_HIDEREADONLY|OFN_ENABLESIZING|OFN_FILEMUSTEXIST,strf);
dlg.m_ofn.lStructSize=sizeof(OPENFILENAME);
if(dlg.DoModal()==IDOK)
strDirFile=dlg.GetPathName();
else
return;
UpdateData(false);
CFilefile(strDirFile,CFile:
:
modeReadWrite|CFile:
:
shareExclusive);
UpdateData(true);
file.SeekToEnd();
unsignedlongfileLength=file.GetLength();
char*fileBuff;
fileBuff=newchar[fileLength];
file.SeekToBegin();
if(file.Read(fileBuff,fileLength)<1)//如果读的文件长度小于1,则退出
{
file.Close();
return;
}
else
{
fileBuff[fileLength]='\0';
m_strSend=fileBuff;
}
file.Close();
UpdateData(false);
}
voidCPc_pcDlg:
:
OnOK()//发送按钮
{
//TOD
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- VC 60 实现 串口