MFC 串口编程详细教程 图文并茂

南楼画角 提交于 2020-02-29 17:55:14

 

http://blog.csdn.net/a_runing_man/article/details/9947343

 

本人之前从未接触MFC编程,由于项目需要,所以上网查阅了相关资料,并实现了上位机串口通信。由于网上的资料还不够详细,本人决定写一个图文并茂的详细教程。因为本人只是初学,如有错误,欢迎指点。

开发环境是:VC 6.0

串口编程方法:32位控件

参考资料:http://leadtheway.iteye.com/blog/705760

第一步:建工程

运行VC 6.0,文件-〉新建,选择MFC AppWizard(exe) ,工程名称:CommTest。确定

进入MFC应用程序向导-步骤1

选择基本对话框,其他的都默认,所以可以直接点击完成。

这样工程就建立完毕。

第二步:控件布局与设置

工程建立后,出现如下对话框:

删除上面的一个静态文本和两个按钮。从控件工具栏拖入两个静态文本,两个编辑框,两个按钮和一个组框。如果没有控件工具栏,可以鼠标右键点击菜单栏空白处,选择控件。布局后的效果:

   

接下来开始设置显示的文字和ID号。

选中按钮1,右键-〉属性。ID号设为IDC_BtnOpen,标题为打开。用于打开串口

选中按钮2,右键-〉属性。ID号设为IDC_BtnSend,标题为发送。用于发送数据。

选择第一个编辑框,右键-〉属性,更改ID为IDC_EditRxData,用于显示接收的数据。

同理选择第二个编辑框,更改ID为IDC_EditTxData。用于输入待发送的数据。

分别选中静态文本和组框,更改标题,不需要更改ID号。

最终效果如下:

现在先编译运行一次,避免出现错误而影响到后面的操作。

接下来这一步是关键的一步:

在对话框中鼠标右键-〉选中插入ActiveX控件。选择Microsoft Communication Control,ver......(后面的字母没看到)。确定

这时出现了一个电话的控件,右键该控件-〉选择类向导……,出现如下对话框:

先设置每个控件的变量,选择Member Variables,选择IDC_BtnOpen,然后Add Variable。

设置变量名为m_BtnOpen,名称与ID号相似只是为了方便记忆,可随便定义。其他默认。同理添加其他控件的变量,在添加MSCOMM1的变量时,会出现提示,选择“是”。

添加完毕后:

变量添加完毕后选回Message Maps,选择IDC_BtnOpen->BN_CLICKED->Add Function,默认函数名就好了,OK。

同理分别添加IDC_BtnSend->BN_CLICKED函数和IDC_MSCOMM1->OnComm函数。确定。

 

编译运行,避免有错误。如果出错,详细检查有没有误操作。一般不会出错的。

 

第三步:添加代码

选择左边信息栏的File View,双击打开CommTestDlg.cpp,在文件尾部可以看到刚刚添加的三个函数。

在OnBtnOpen()函数添加代码:

void CCommTestDlg::OnBtnOpen() 
{
// TODO: Add your control notification handler code here
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。实物结果如图:

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!