环境:
系统:windows 10 64位
编译器:Visual Studio 2008
CSerialPort项目是一个基于C/C++的轻量级开源跨平台串口类库,可以轻松实现跨平台多操作系统的串口读写,同时还支持C#, Java, Python, Node.js等。
CSerialPort项目的开源协议自 V3.0.0.171216 版本后采用GNU Lesser General Public License v3.0
为了让开发者更好的使用CSerialPort进行开发,特编写基于4.3.x版本的CSerialPort教程系列。
CSerialPort项目地址:
MFC完整示例程序地址:
新建一个基于对话框的MFC项目,解决方案名称为CommMFC
在CommMFC解决方案目录下载CSerialPort源码
$ cd CommMFC
$ git clone https://github.com/itas109/CSerialPort
目录结构如下:
D:/CommMFC $ tree
.
+--- CommMFC
| +--- CommMFC.aps
| +--- CommMFC.cpp
| +--- CommMFC.h
| +--- CommMFC.rc
| +--- CommMFC.vcproj
| +--- CommMFCDlg.cpp
| +--- CommMFCDlg.h
| +--- ReadMe.txt
| +--- res
| | +--- CommMFC.ico
| | +--- CommMFC.rc2
| +--- Resource.h
| +--- stdafx.cpp
| +--- stdafx.h
| +--- targetver.h
+--- CommMFC.sln
+--- CSerialPort
| +--- include
| | +--- CSerialPort
| | | +--- SerialPort.h
| | | +--- SerialPortInfo.h
| +--- src
| | +--- SerialPort.cpp
| | +--- SerialPortBase.cpp
| | +--- SerialPortInfo.cpp
| | +--- SerialPortInfoBase.cpp
| | +--- SerialPortInfoWinBase.cpp
| | +--- SerialPortWinBase.cpp
右键【CommMFC根命名空间】-【属性】-【C/C++】-【常规】-【附加包含目录】-添加CSerialPort的头文件目录
D:\CommMFC\CSerialPort\include
或
$(ProjectDir)\..\CSerialPort\include
右键【CommMFC根命名空间】-【添加】-【新建筛选器(命名为CSerialPort)】
右键【CSerialPort筛选器】-【添加】-【现有项】-添加CSerialPort的src目录的所需文件()
所需文件清单如下:
注意:
需要将添加的cpp文件的预编译头设置为"不使用预编译头",如右键【serialport.cpp】-【属性】-【C/C++】-【预编译头】-【预编译头: 不使用预编译头】
如不设置会报错:
serialport.cpp: fatal error C1010: 在查找预编译头时遇到意外的文件结尾。是否忘记了向源中添加“#include "stdafx.h"?
SerialPortBase.cpp: fatal error C1010: 在查找预编译头时遇到意外的文件结尾。是否忘记了向源中添加“#include "stdafx.h"?
SerialPortWinBase.cpp: fatal error C1010: 在查找预编译头时遇到意外的文件结尾。是否忘记了向源中添加“#include "stdafx.h"?
SerialPortInfo.cpp: fatal error C1010: 在查找预编译头时遇到意外的文件结尾。是否忘记了向源中添加“#include "stdafx.h"?
SerialPortInfoBase.cpp: fatal error C1010: 在查找预编译头时遇到意外的文件结尾。是否忘记了向源中添加“#include "stdafx.h"?
SerialPortInfoWinBase.cpp: fatal error C1010: 在查找预编译头时遇到意外的文件结尾。是否忘记了向源中添加“#include "stdafx.h"?
windows下CSerialPort必须的依赖库为setupapi.lib
右键【CommMFC根命名空间】-【属性】-【链接器】-【输入】-【附加依赖项】-添加setupapi.lib
在CommMFCDlg.h
文件中
CSerialPortListener
onReadEvent(const char *portName, unsigned int readBufferLen)
代码如下:
// CommMFCDlg.h : 头文件
//
#pragma once
// add by itas109
#include "CSerialPort/SerialPort.h"
#include "CSerialPort/SerialPortInfo.h"
using namespace itas109;
// end by itas109
// CCommMFCDlg 对话框
class CCommMFCDlg : public CDialog, public CSerialPortListener // add by itas109
{
...
// add by itas109
private:
void onReadEvent(const char *portName, unsigned int readBufferLen);
// end by itas109
// add by itas109
private:
CSerialPort m_serialPort;
// end by itas109
};
注意:
如果CCommMFCDlg不继承CSerialPortListener,调用connectReadEvent函数时会报错
CSerialPort::connectReadEvent: 不能将参数 1 从CCommMFCDlg *const 转换为itas109::CSerialPortListener *
在CommMFCDlg.cpp
文件增加
CCommMFCDlg::OnInitDialog()
中增加CSerialPort的测试代码// CommMFCDlg.cpp: 实现文件
...
BOOL CCommMFCDlg::OnInitDialog()
{
...
// TODO: 在此添加额外的初始化代码
// add by itas109
m_serialPort.connectReadEvent(this);
m_serialPort.init("COM1");
m_serialPort.open();
if (m_serialPort.isOpen())
{
m_serialPort.writeData("itas109", 7);
}
else
{
MessageBox(_T("open failed"));
}
// end by itas109
...
}
// add by itas109
void CCommMFCDlg::onReadEvent(const char *portName, unsigned int readBufferLen)
{
if(readBufferLen > 0)
{
char data[1024];
int recLen = m_serialPort.readData(data,readBufferLen > 1023 ? 1023 : readBufferLen);
if (recLen > 0)
{
data[recLen] = '\0';
CString cstr;
cstr.Format(_T("OnReceive - data: %s, size: %d"), CString(data), recLen);
MessageBox(LPCTSTR(cstr));
}
}
}
// end by itas109
代码中的COM2对应的串口为RS232环回测试硬件,因此对应的结果为程序启动后,初始化并打开串口COM1,发送数据itas09
,随后弹框提示收到数据(如OnReceive - data: itas109, size: 7)
License
License under CC BY-NC-ND 4.0: 署名-非商业使用-禁止演绎
Reference: