本人从来没有接触过MFC编程,由于项目的需要,在网上查阅相关资料,实现上位机串行通信。 因为网上资料还不详细,所以我决定写文字和文章两方面的详细教程。 我是初学者,如果有错误的话,请指出来。
开发环境为VC 6.0
串行编程方法: 32位控制
参考资料: http://leadtheway.iteye.com/blog/705760
第一步:建工程
VC 6.0,文件- >新建,选择MFC应用程序向导(exe ),项目名称: CommTest。 确认
进入MFC APP应用程序向导-步骤1
选择基本对话框后,其他将成为默认设置,可以直接单击完成。
这样工程就完成了。
第二步:控件布局与设置
创建项目后,将显示以下对话框:
删除上面的静态文本和两个按钮。 从控件工具栏拖动到两个静态文本、两个编辑框、两个按钮和一个组框。 如果没有控件工具栏,则可以右键单击菜单栏的空白区域并选择控件。 布局后的效果:
开始设定下一个显示的文字和ID编号。
按钮1,右键- >选择属性。 ID号设置为IDC_BtnOpen,标题为on。 打开串行端口
按钮2,右键单击- >选择属性。 ID号码为IDC_BtnSend,标题为发送。 用于发送数据。
选择第一个编辑框,然后选择右键单击-属性,将ID更改为IDC_EditRxData并查看接收到的数据。
同样,选择第二个编辑框,将ID更改为IDC_EditTxData。 输入要发送的数据。
分别选择静态文本和组框,然后更改标题。 不需要更改ID号码。
最终效果如下。
首先编译并运行,以免发生错误影响以后的操作。
下一步是重要的步骤:
在对话框中单击鼠标右键- (选择“插入-(ActiveX控件”。 选择Microsoft通信控制,ver . 确认
然后,显示电话控件。 右键单击此控件以显示“选择类向导”……以下对话框:
首先设置每个控件的变量,然后选择Member Variables、IDC_BtnOpen和Add Variable。
您可以自由定义变量名称,方法是将变量名称设置为m_BtnOpen,并确保名称与ID号相似。 其他默认值。 同样,如果添加其他控件的变量,则在添加MSCOMM1变量时会出现提示,并选择“是”。
添加完成后:
添加变量后,返回到消息映射,然后选择IDC _ BTN open-bn _ clicked-add function。 默认的函数名称比较好。 好的。
同样,分别添加IDC_BtnSend-BN_CLICKED和IDC_MSCOMM1-OnComm函数。 确定。
编译并运行,避免错误。 发生错误时,详细检查有无误操作。 一般没错。
第三步:添加代码
选择左侧信息栏中的File View,双击打开CommTestDlg.cpp,可以看到刚添加到文件末尾的三个函数。
要向OnBtnOpen ()函数添加代码:
voidccommtestdlg :3360 onbtnopen (
{
//todo : addyourcontrolnotificationhandlercodehere
if(m_comm1.getportopen ) )
m_comm1.setportopen(false );
m_comm1.setcommport(1; 选择com1后,可以根据情况进行变更
m_comm1.setinbuffersize(1024; //设定输入缓冲区的大小,Bytes
m_comm1.setoutbuffersize(1024; //设置输入缓冲区的大小,然后单击Bytes//
m_comm1.setsettings(9600,n,8,1 ); //波特率9600、无检查、8数据位、1停止位
m_comm1.setinputmode(1; //1 :表示用二进制检查数据
m_comm1.setRthreshold(1;
//参数1表示串行端口每次收到缓冲区时
中有多于或等于1个字符时将引发一个接收数据的OnComm事件m_Comm1.SetInputLen(0); //设置当前接收区数据长度为0
if( !m_Comm1.GetPortOpen())
m_Comm1.SetPortOpen(TRUE);//打开串口
else
AfxMessageBox("cannot open serial port");
m_Comm1.GetInput();//先预读缓冲区以清除残留数据
UpdateData(false);
}
编译运行。
在OnOnCommMscomm1()函数添加代码:
void CCommTestDlg::OnOnCommMscomm1()
{
// TODO: Add your control notification handler code here
VARIANT variant_inp;
COleSafeArray safearray_inp;
LONG len,k;
BYTE rxdata[2048]; //设置BYTE数组 An 8-bit integerthat is not signed.
CString strtemp;
if(m_Comm1.GetCommEvent()==2) //事件值为2表示接收缓冲区内有字符
{ 以下你可以根据自己的通信协议加入处理代码
variant_inp=m_Comm1.GetInput(); //读缓冲区
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型变量
{
BYTE bt=*(char*)(rxdata+k); //字符型
strtemp.Format("%c",bt); //将字符送入临时变量strtemp存放
m_EditRxData+=strtemp; //加入接收编辑框对应字符串
}
}
//UpdateData(FALSE); //更新编辑框内容
SetDlgItemText(IDC_EditRxData,m_EditRxData);//不使用UpdateData(FALSE);的原因是该函数会
//刷新整个对话框的数据,而SetDlgItemText()
//只更新接收编辑框的数据。
}
现在可以接上串口做测试了。我是用单片机做串口发送,上位机做串口接收。单片机持续发送字符' D '.上位机正常接收:
接着添加发送功能,
void CCommTestDlg::OnBtnSend()
{
// TODO: Add your control notification handler code here
UpdateData(TRUE); //读取编辑框内容
m_Comm1.SetOutput(COleVariant(m_EditTxData));//发送数据
}
发送大写字母N,在单片机用LED显示。‘N’对应的ASCII码的二进制是0100 1110。实物结果如图:
由于晚上灯光不足,拍出来效果不明显。懂单片机的童鞋应该能看明白。
本教程仅仅实现非常简单的串口收发功能。在数据显示,串口参数选择等功能都没实现,问问谷歌度娘都能找到你要的答案。