|
吾爱游客
发表于 2021-6-15 15:52
1、申 请 I D : kaizi35 *同上
2、个人邮箱:252250608@qq.com *应确认邮箱可正常使用,注册后不可修改
3、原创技术文章:
VS2019-c++MFC基于CSerialPort类串口通信 https://editor.csdn.net/md/?articleId=117729757
VS2017-MFC基于CSerialPort类串口通信
仅供自己学习
因为不满我发的第一篇博客里的Mscomm控件导入的MFC串口通信只能在X86下运行,于是我又捯饬了一下,弄了一个新的通信方法
1.在VS2017环境下创建基于对话框的MFC应用程序
在这里插入图片描述
这是最终的MFC界面,编辑过程如下:
1. 1设置控件属性
最上面的ComboBox的ID设为IDC_COMBO_PORT_Nr
下面的ComboBox的ID设为IDC_COMBO_BAUDRATE
中间Button1的Caption为打开串口、ID为IDC_BUTTON_OPEN_CLOSE
下面Button2的Caption为发送、ID为IDC_BUTTON_SEND
接收区的编辑框的ID为IDC_ReceiveEdit
发送区的编辑框的ID为IDC_SendEdit
1.2为控件添加变量
给最上面ComboBox控件添加变量,右击添加变量,名称为m_PortNr
在这里插入图片描述
给下面ComboBox控件添加变量,右击添加变量,名称为m_BaudRate,图片类似同上
给“打开串口”这个控件添加变量,右击添加变量,名称为m_OpenCloseCtrl
在这里插入图片描述
给发送区的编辑框添加变量,右击添加变量,名称为m_Send
在这里插入图片描述
同理给接收区的编辑框添加变量,右击添加变量,名称为m_ReceiveCtrl
1.3为控件添加消息处理函数
给控件“打开串口”添加消息处理函数,右击添加函数:
在这里插入图片描述
点击编辑代码, 在CserialcommunicationDlg::OnBnClickedButtonOpenClose()中添加如下代码
void CserialcommunicationDlg::OnBnClickedButtonOpenClose()
{
// TODO: 在此添加控件通知处理程序代码
//GetDlgItem(IDC_SendEdit)->SetFocus();
CString temp;
m_OpenCloseCtrl.GetWindowText(temp);///获取按钮的文本
UpdateData(true);
if (temp == _T("关闭串口"))///表示点击后是"关闭串口",也就是已经关闭了串口
{
m_SerialPort.ClosePort();
m_OpenCloseCtrl.SetWindowText(_T("打开串口"));///设置按钮文字为"打开串口"
}
///打开串口操作
else if (m_PortNr.GetCount() > 0)///当前列表的内容个数
{
int SelPortNO, SelBaudRate;
UpdateData(true);
m_PortNr.GetWindowText(temp);///CString temp
temp.Delete(0, 3);
SelPortNO = _tstoi(temp);
m_BaudRate.GetWindowText(temp);
SelBaudRate = _tstoi(temp);
if (m_SerialPort.InitPort(this->GetSafeHwnd(), SelPortNO, SelBaudRate))
{
m_SerialPort.StartMonitoring();
m_OpenCloseCtrl.SetWindowText(_T("关闭串口"));
}
else
{
AfxMessageBox(_T("串口已被占用!"));
}
}
else
{
AfxMessageBox(_T("没有发现串口!"));
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
给控件“发送”添加消息处理函数,右击添加函数:
在这里插入图片描述
点击编辑代码,在CserialcommunicationDlg::OnBnClickedButtonSend()添加如下代码:
void CserialcommunicationDlg::OnBnClickedButtonSend()
{
// TODO: 在此添加控件通知处理程序代码
GetDlgItem(IDC_SendEdit)->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);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
1.4 添加CSerialPort类相关.cpp和.h文件
链接:https://download.csdn.net/download/weixin_44177837/12265880
下载后,将上述两个文件添加到工程项目里
可能需要在CSerialPort.cpp里添加#include "stdafx.h"或者#include “pch.h”,看个人情况,先不管这个,最后编译不通过在再来加这个
在serial communicationDlg.h里添加如下代码
#include "SerialPort.h"
using namespace std;
using namespace itas109;
extern CSerialPort m_SerialPort;
1
2
3
同时添加如下函数:
在这里插入图片描述
在这里插入图片描述
在serial communicationDlg.cpp里添加以下代码:
LRESULT CserialcommunicationDlg::OnReceiveStr(WPARAM str, LPARAM commInfo)
{
struct serialPortInfo
{
UINT portNr;//串口号
DWORD bytesRead;//读取的字节数
}*pCommInfo;
pCommInfo = (serialPortInfo*)commInfo;
CString str1((char*)str);
//char* m_str = (char*)str;
//TCHAR* dest = NULL;
//dest = new TCHAR[sizeof(TCHAR) * pCommInfo->bytesRead];
//wmemcpy(dest, (TCHAR*)str, sizeof(TCHAR)* pCommInfo->bytesRead+1);
//获取指定串口的数据
//if (pCommInfo->portNr == 2)
//{
int len = _tcslen(str1.GetBuffer(0));
if (len == pCommInfo->bytesRead)
{
GetDlgItem(IDC_ReceiveEdit)->SetWindowText(_T(""));
m_ReceiveCtrl.SetSel(-1, -1);
m_ReceiveCtrl.ReplaceSel(str1);
}
else
{
AfxMessageBox(_T("数据长度错误"));
}
//}
return TRUE;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
1.5添加初始化函数
在serial communicationDlg.cpp里的BOOL CserialcommunicationDlg::OnInitDialog()里的
// TODO: 在此添加额外的初始化代码
添加以下代码
// TODO: 在此添加额外的初始化代码
CString temp;
//添加波特率到下拉列表
for (int i = 0; i < sizeof(BaudRate) / sizeof(int); i++)
{
temp.Format(_T("%d"), BaudRate);
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);
OnBnClickedButtonOpenClose();
m_Send.SetWindowText(_T("http://blog.csdn.net/itas109"));
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
同时添加红线区域类的代码到相应位置
int BaudRate[] = { 300, 600, 1200, 2400, 4800, 9600, 14400, 19200, 38400, 56000, 57600, 115200 };
CSerialPort m_SerialPort;
1
在这里插入图片描述
2.运行结果
同我上一篇博文建立的MFC通过虚拟串口进行互传消息如下:
在这里插入图片描述
————————————————
版权声明:本文为CSDN博主「weixin_44177837」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_44177837/article/details/105059450
|
|
发帖前要善用【论坛搜索】功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。 |
|
|
|
|