VC中实现串口通讯的摸索过程

串口通讯对于需要进行嵌入式开发的小伙伴们来说是必不可少的,甚至说是无法回避的。而VC却又不像C#或者QT那样人性化,没有自带串口类(貌似VC6时代还有一个串口控件可以下载然后通过安装到VC6中),所以我们不得不到处寻找开源的串口通讯代码。
这里我找到的是CSerialPort,虽然官网作者没有继续更新了(还停留在2000年8月),但国内的牛人则在继续维护。
官网地址是这里:https://www.codeguru.com/cpp/i-n/network/serialcommunications/article.php/c2483/A-communication-class-for-serial-port.htm
我找到了牛人的维护版本下载了,感觉实现起来还算比较简单,这里将摸索过程罗列出来。
首先,我们必须找到SerialPort.cpp和SerialPort.h两个文件,并把他们添加到我们自己的工程中。
在这里插入图片描述
我这里建立一个基于对话框的MFC工程,添加完毕后注意引用到代码中,由于这个类修改者已经将SerialPort类置于了名称空间itas109中,所以不要忘记引入名称空间,开始代码如下:

第一步,引入必要的头文件
// SerialPortTestDlg.h : header file
//

#pragma once
#include "SerialPort.h"
using namespace std;
using namespace itas109;

第二步,声明串口变量及准备波特率数据

// CSerialPortTestDlg dialog
//此处准备我们需要用到的波特率及串口变量
int BaudRate[] = { 300, 600, 1200, 2400, 4800, 9600, 14400, 19200, 38400, 56000, 57600, 115200 };
CSerialPort m_SerialPort;

第三步,初始化串口(枚举所有串口)
这里要声明两个ComboBox变量,分别来存放串口号和波特率
在这里插入图片描述
在这里插入图片描述
在对话框的OnInitDialog中增加界面及串口初始化代码(增加代码之前在对话框中增加三个按钮和两个文本框两个下拉框)如下图:
在这里插入图片描述

// TODO: Add extra initialization here
	//这里添加我们初始化串口的必要代码
	CString temp;
	//添加波特率到下拉列表
	for (int i = 0; i < sizeof(BaudRate) / sizeof(int); i++)
	{
		temp.Format(_T("%d"), BaudRate[i]);
		m_BaudRate.AddString((LPCTSTR)temp);
	}

	temp.Format(_T("%d"), 9600);
	m_BaudRate.SetCurSel(m_BaudRate.FindString(0, temp));

	//获取串口号
	CSerialPortInfo a;
	list<string> m_portsList = CSerialPortInfo::availablePorts();
	list<string>::iterator itor;
	TCHAR m_regKeyValue[255];
	for (itor = m_portsList.begin(); itor != m_portsList.end(); ++itor)
	{
#ifdef UNICODE
		int iLength;
		const char * _char = (*itor).c_str();
		iLength = MultiByteToWideChar(CP_ACP, 0, _char, strlen(_char) + 1, NULL, 0);
		MultiByteToWideChar(CP_ACP, 0, _char, strlen(_char) + 1, m_regKeyValue, iLength);
#else
		strcpy_s(m_regKeyValue, 255, (*itor).c_str());
#endif
		m_PortNr.AddString(m_regKeyValue);
	}
	m_PortNr.SetCurSel(0);
	

到这里注意,如果我们编译会出现这样的错误:
在这里插入图片描述
一开始 ,我也是很郁闷,总怎么修改都有这个
Error C1010 unexpected end of file while looking for precompiled header. Did you forget to add ‘#include “stdafx.h”’ to your source? SerialPortTest
后来,经过摸索发现,应该将SerialPort.cpp预编译设置修改为,不使用预编译
在这里插入图片描述
我们再次编译运行,一切正常,如下图:
在这里插入图片描述
第四步,实现读数据功能(建立接受函数的消息映射)
通过类想到,找到Message选项,建立一个消息映射(记住,根据SerialPort.cpp中的定义,这里的消息WM_COMM_RXSTR只能用,否则无效)
在这里插入图片描述
之后我们在OnReceiveStr中添加如下代码即可

	struct serialPortInfo
	{
		UINT portNr;//串口号
		DWORD bytesRead;//读取的字节数
	}*pCommInfo;
	pCommInfo = (serialPortInfo*)lParam;

	CString str1((char*)wParam);
	
	int len = _tcslen(str1.GetBuffer(0));
	if (len == pCommInfo->bytesRead)
	{
		m_ReceiveCtrl.SetSel(-1, -1);
		m_ReceiveCtrl.ReplaceSel(str1);
	}
	else
	{
		AfxMessageBox(_T("数据长度错误"));
	}
	
	return 0;

在这里插入图片描述
到这里为止,我们的串口基本可以实现读取数据的功能了。
写功能比较简单,在发送数据的按钮事件中添加下面的代码即可:

GetDlgItem(IDC_EDIT2)->SetFocus();
	CString temp;
	UpdateData(true);
	m_OpenCloseCtrl.GetWindowText(temp);
	if (temp == "打开串口")///没有打开串口
	{
		AfxMessageBox(_T("请首先打开串口"));
		return;
	}
	m_Send.GetWindowText(temp);
	size_t len = _tcsclen(temp) + 1;;
	char* m_str = NULL;
	size_t* converted = 0;
	m_str = new char[len];
#ifdef UNICODE
	wcstombs_s(converted, m_str, len, temp.GetBuffer(0), _TRUNCATE);
#else
	m_str = temp.GetBuffer(0);
#endif
	m_SerialPort.WriteToPort(m_str, len);

VS2017下编写的串口通讯源代码见下面链接:
VC2017串口通讯实例源代码

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

河西石头

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值