C++ MFC 简单 串口通信

来源:互联网 发布:单片机是什么专业 编辑:程序博客网 时间:2024/06/07 00:26

说来惭愧,自己看别人的API说明,想要鼓捣出一个串口通讯界面,结果失败了,最后还是看的教程。。。。

使用MFC进行串口通讯的上位机的软件编程,教程网址如下,十分简单。

http://download.csdn.net/download/peter_jjh/9938549

1. 程序框架及代码分析:

1.1 程序框架:

(1) 初始化界面
(2) 打开串口 (读取串口号,初始化串口参数(波特率、校验位、数据位等),若串口已经打开则关闭串口)
(3) 发送数据 (更新控件状态,进入MSComm事件驱动函数,读缓冲区,数据转换,更新编辑框成员函数,更新编辑框内容)
(4) 退出界面 (检测串口是否开启,若开启则关闭串口,再进行退出)

1.2 关键代码分析:

代码下载地址:http://download.csdn.net/download/peter_jjh/9938503


(1)初始化界面:除却MFC自动生成的界面初始化代码,这里的关键在于初始化参数,在BOOL xxxxx:OnInitDialog()中添加部分代码


// 串口选择组合框CString str;int i;for (i = 0; i<30; i++){str.Format(_T("com %d"), i + 1);m_ComNum.InsertString(i, str);}m_ComNum.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++)//使用AddString会无序排列,在Dialog中把这一ComboBox的Sorted改为False即可{int judge_tf = m_BaudRate.AddString(str1[i]);if ((judge_tf == CB_ERR) || (judge_tf == CB_ERRSPACE))MessageBox(_T("build baud error!"));}/*for (int i = 0; i<12; i++)//更换为使用InsertString{m_BaudRate.InsertString(i, str1[i]);}*/m_BaudRate.SetCurSel(5);//预置波特率为"9600"

(2) 打开串口:

void CComCommunicateDlg::OnBnClickedButtonOpen()//打开串口按钮{CString str, str1, n;//定义字符串GetDlgItemText(IDC_BUTTON_OPEN, str);CWnd *h1;h1 = GetDlgItem(IDC_BUTTON_OPEN);//指向控件的captionif (!m_mscom.get_PortOpen()){m_BaudRate.GetLBText(m_BaudRate.GetCurSel(), str1);//取得所选的字符串,并存放在str1里面str1 = str1 + ',' + 'n' + ',' + '8' + ',' + '1';//这句话很关键m_mscom.put_CommPort((m_ComNum.GetCurSel() + 1));//选择串口m_mscom.put_InputMode(1);//设置输入方式为二进制方式m_mscom.put_Settings(str1);//波特率为(波特率组Á合框)无校验,8数据位,1个停止位m_mscom.put_InputLen(1024);//设置当前接收区数据长度为1024m_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);//改变按钮名称为打开串口}}}

(3) 发送数据 

void CComCommunicateDlg::OnBnClickedButtonSend(){UpdateData(true);//将控件的状态传给其关联的变量m_mscom.put_Output(COleVariant(m_EditSend));//把发送编辑框的数据发送出去,跳转到OnCommMscomm1中}
void CComCommunicateDlg::OnCommMscomm1()//事件驱动{if (m_mscom.get_CommEvent() == 2)//事件值为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_EditReveive += str;      //接收到编辑框里面//SetTimer(1,10,NULL);//延时10msUpdateData(false);}}

(4) 退出界面

void CComCommunicateDlg::OnBnClickedButtonClose(){if (m_mscom.get_PortOpen())m_mscom.put_PortOpen(false);//先关闭串口再退出,否则串口一直被占用CDialogEx::OnCancel();}

2. 遇到的问题:

2.1 缺少Microsoft Communications Control 控件

MSComm 控件是一个串行通讯控件,作用为替程序员串口通讯编程节省时间,有关于MSComm空间的介绍可以参考这篇博客:串口通信-MSComm控件使用详解


这一问题的解决方式很简单,下载压缩包解压复制就可以,下载网址:


http://download.csdn.net/download/peter_jjh/9937696


1.解压缩压缩包内包含3个文件:

MSCOMM.SRG
MSCOMM32.DEP
mscomm32.ocx
2.复制文件到指定路径:

32位的系统,文件复制到C:\WINDOWS\SYSTEM32目录下;

64位的系统,文件复制到C:\Windows\SysWOW64目录下。

3.win+r输入cmd打开cmd窗口,在cmd中输入:

32位:regsvr32 C:\Windows\System32\mscomm32.ocx
64位:regsvr32 C:\Windows\SysWOW64\mscomm32.ocx

如果失败,请以管理员身份打开cmd,再进行步骤3。


2.2 error LNK2001: 无法解析的外部符号

在进行编译时,出现如上错误的原因有两个,分别是
(1)部分函数声明了却未定义
(2)部分动态链接库的编译方式未统一

针对第一种错误,只需要找到未定义的函数,注释掉或者删除就可以了,在我的测试程序中,这类问题主要出现在BoxEditor中,可能是由于我的误操作导致,添加了OnEnChangeEditRev函数,该OnEnChange***函数针对的是窗口中数据内容变化的响应函数,但是实际没有实现这个函数,所以导致了错误。
参考:http://tieba.baidu.com/p/2049736254 

针对第二种错误,需要将 MFC使用 和 运行库 都进行统一。注意先将右上角的配置选为 所有配置, 具体选择如下:



参考:http://www.360doc.com/content/11/1031/14/4190063_160548608.shtml



附录:

在研究如何自动读取可用的串口号时,发现了一个十分完整的开源的串口通信项目。较为复杂,慢慢研究,该项目的地址如下:
http://blog.csdn.net/itas109/article/details/51337538




结语:

本文存在诸多不足,希望大家多多指教!


原创粉丝点击