C++ MFC 简单 串口通信

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

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

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

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

1.1 程序框架:

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

1.2 关键代码分析:



(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);		//指向控件的caption

	if (!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);		//设置当前接收区数据长度为1024
		m_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);		//延时10ms
		UpdateData(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



附录:

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




结语:

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


  • 19
    点赞
  • 128
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值