文章目录

  • 1 功能展示
  • 2 实现步骤
    • 2.1 添加控件 及 控件变量
    • 2.2 添加按钮及静态文本框
    • 2.3 声明其他变量 及 函数
  • 3 函数实现
    • 3.1 初始刷函数
    • 3.2 设置串口参数
    • 3.3 打开串口函数
    • 3.4 显示串口状态
    • 3.5 关闭串口
    • 3.6 更改串口、波特率、校验位、数据位、停止位
    • 3.7 串口状态显示
  • 4 完整代码
    • 4.1 ...Dlg.h文件
    • 4.2 ...Dlg.cpp文件
  • 5 小改进
  • 6 完整MFC项目项下载

1 功能展示

实现串口通信的上位机。
在这里插入图片描述

2 实现步骤

2.1 添加控件 及 控件变量

在工具栏中 拖拽5个 Combobox 控件,和5个 Static Text控件,
排好序,并如下命名;
在这里插入图片描述

给5个 Combobox 控件,分别添加以下控件变量 和 值变量 (通过右键控件,弹出的窗口添加)

//控件 列表框变量	
m_Combo_Com;				//列表框:串口
m_Combo_Baud;			//列表框:波特率
m_Combo_Check;			//列表框:校验位
m_Combo_Data;				//列表框:数据位
m_Combo_Stop;				//列表框:停止位//值 字符变量
m_Str_Com;					//字符变量:串口
m_Str_Baud;					//字符变量:波特率
m_Str_Check;				   //字符变量:校验位
m_Str_Data;			 	  //字符变量:数据位
m_Str_Stop;				  //字符变量:停止位

…Dlg.h文件中 会多出10行;
在这里插入图片描述

…Dlg.cpp文件中 会多出以下代码

在这里插入图片描述

2.2 添加按钮及静态文本框

添加4个 Static Text控件,和一个 Button 按钮
在这里插入图片描述
其ID命名如下

IDC_COMSTATUS_STATIC
IDC_PORTisOPEN_STATIC
IDC_TXLEN_STATIC
IDC_RXLEN_STATIC
IDC_OPENCOM_BUTTON

定义两个变量

public://自定义变量long			m_rxlen;				//接收数据个数long			m_txlen;				//发送数据个数

2.3 声明其他变量 及 函数

Dlg.h文件中 所有用户生成或添加的 变量及函数

public://自定义变量HANDLE			m_hCom;					//串口句柄volatile int	m_bConnected;			//串口连接成功指示BOOL			m_COMStatu;				//串口状态指示long			m_rxlen;				//接收数据个数long			m_txlen;				//发送数据个数//列表框变量CComboBox	m_Combo_Com;				//列表框:串口CComboBox	m_Combo_Baud;				//列表框:波特率CComboBox	m_Combo_Check;				//列表框:校验位CComboBox	m_Combo_Data;				//列表框:数据位CComboBox	m_Combo_Stop;				//列表框:停止位//字符变量CString		m_Str_Com;					//字符变量:串口CString		m_Str_Baud;					//字符变量:波特率CString		m_Str_Check;				//字符变量:校验位CString		m_Str_Data;					//字符变量:数据位CString		m_Str_Stop;					//字符变量:停止位//函数=====================================================================================
public://串口相关函数BOOL OpenComm(int Num);								//打开串口BOOL SetCommParameter();							//设置串口参数void DisplayStatus();								//显示串口状态void CloseConnection();								//关闭串口//按钮函数afx_msg void OnBnClickedOpencomButton();			//串口状态显示//列表框函数afx_msg void OnCbnSelchangeComboCom();				//更改串口afx_msg void OnCbnSelchangeComboBaud();				//更改波特率afx_msg void OnCbnSelchangeComboCheck();			//更改校验位afx_msg void OnCbnSelchangeComboData();				//更改数据位afx_msg void OnCbnSelchangeComboStop();				//更改停止位

3 函数实现

3.1 初始刷函数

在OnInitDialog()函数中添加

// TODO: 在此添加额外的初始化代码//========================================== = 初始化对话框========================================== =//设串口组合列表框TCHAR com[][6] = {_T("COM1"),_T("COM2"),_T("COM3"),_T("COM4"),_T("COM5"),_T("COM6"),_T("COM7"),_T("COM8"),_T("COM9") };for (int i = 0; i < 9; i++)m_Combo_Com.AddString(com[i]);m_Combo_Com.SetCurSel(0);//默认显示第1个串口号//设波特率组合列表框TCHAR baud[][7] = {_T("9600"),_T("19200"),_T("38400"),_T("43000"),_T("56000"),_T("57600"),_T("115200"),_T("128000"),_T("230400") };for (int i = 0; i < 9; i++)m_Combo_Baud.AddString(baud[i]);m_Combo_Baud.SetCurSel(5);//默认显示第6个波特率//设校验位组合列表框TCHAR check[][7] = {_T("None"),_T("Odd"),_T("Even") };for (int i = 0; i < 3; i++)m_Combo_Check.AddString(check[i]);m_Combo_Check.SetCurSel(0);//默认显示无校验//设数据位组合列表框TCHAR data[][2] = {_T("8"),_T("7"),_T("6") };for (int i = 0; i < 3; i++)m_Combo_Data.AddString(data[i]);m_Combo_Data.SetCurSel(0);//设停止位组合列表框TCHAR stop[][2] = { _T("1"),_T("2") };for (int i = 0; i < 2; i++)m_Combo_Stop.AddString(stop[i]);m_Combo_Stop.SetCurSel(0);//打开串口函数赋初值OpenComm(0);

3.2 设置串口参数

/==============================================设置串口参数==============================================
//设置串口参数
BOOL CSerialPortDlg::SetCommParameter()
{DCB dcb;	//DCB结构,定义了串口通信设备的控制设置if (!GetCommState(m_hCom, &dcb))//读取新创建的 m_hCom串口句柄的 DCB设备控制块结构体,当只需要设置一部分 DCB参数时,可以通过此函数读取现有参数,只改变部分参数即可return FALSE;	//如果读取不成功直接结束//设置波特率long baudrate[] = { 300,600,1200,2400,4800,9600,19200,38400,43000,56000,57600,115200,128000,230400 };int baudindex = m_Combo_Baud.GetCurSel();m_Combo_Baud.GetLBText(baudindex, m_Str_Baud);dcb.BaudRate = baudrate[baudindex];//读取并设置波特率参数//设置数据位int databit[] = { 8,7,6 };int dataindex = m_Combo_Data.GetCurSel();m_Combo_Data.GetLBText(dataindex, m_Str_Data);dcb.ByteSize = databit[dataindex];//设置校验位int checkindex = m_Combo_Check.GetCurSel();m_Combo_Check.GetLBText(checkindex, m_Str_Check);switch (checkindex){case 0: dcb.Parity = NOPARITY; break;case 1: dcb.Parity = ODDPARITY; break;case 2: dcb.Parity = EVENPARITY; break;default:;}//设置停止位int stopindex = m_Combo_Stop.GetCurSel();m_Combo_Stop.GetLBText(stopindex, m_Str_Stop);switch (stopindex){case 0: dcb.StopBits = ONESTOPBIT; break;case 1: dcb.StopBits = TWOSTOPBITS; break;default:;}//流控制 dcb.fInX = FALSE;dcb.fOutX = FALSE;dcb.fNull = FALSE;	//为TRUE时,接收时自动去掉空(0值)字节dcb.fBinary = TRUE;	//指定是否允许二进制模式。Win32 API不支持非二进制模式传输,应设置为true dcb.fParity = FALSE;dcb.fOutxCtsFlow = FALSE;dcb.fOutxDsrFlow = FALSE;return(SetCommState(m_hCom, &dcb)); //应用设置
}

3.3 打开串口函数

/==============================================打开串口==============================================
//打开串口函数
BOOL CSerialPortDlg::OpenComm(int Num)
{m_Combo_Com.GetLBText(Num, m_Str_Com);//获取串口Combo下拉框中对应于Num位置的串口名称,比如Num=0时,m_SeriouStr 为"COM1"m_hCom = CreateFile(m_Str_Com, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);//将串口作为一个文件来看,用CreateFile()函数打开串口,返回结果存储在m_hCom中if (m_hCom == INVALID_HANDLE_VALUE)//如果返回INVALID_HANDLE_VALUE表示打开串口失败,{AfxMessageBox(_T("打开串口失败!"));	//失败时弹出对话框提醒m_bConnected = 0;				    //将串口连接标志设为0return FALSE;					    //打开失败后不再继续往下进行,直接返回FALSE}m_bConnected = 1;	//将串口连接标志设为1return 0;
}

3.4 显示串口状态

//============================================显示串口状态============================================
//显示串口状态
void CSerialPortDlg::DisplayStatus()
{CWnd* static_status = GetDlgItem(IDC_COMSTATUS_STATIC);CWnd* static_txlen  = GetDlgItem(IDC_TXLEN_STATIC);CWnd* static_rxlen  = GetDlgItem(IDC_RXLEN_STATIC);CString status_str, txlen_str, rxlen_str;if (m_bConnected){status_str = _T("STATUS:") + m_Str_Com + " OPENED," + m_Str_Baud + ',' + m_Str_Check + ',' + m_Str_Data + ',' + m_Str_Stop;SetCommParameter();}elsestatus_str = _T("STATUS:") + m_Str_Com + " CLOSED," + m_Str_Baud + ',' + m_Str_Check + ',' + m_Str_Data + ',' + m_Str_Stop;static_status->SetWindowText(status_str);txlen_str.Format(_T("TX: % ld"), m_txlen);static_txlen->SetWindowText(txlen_str);rxlen_str.Format(_T("RX:%ld"), m_rxlen);static_rxlen->SetWindowText(rxlen_str);
}

3.5 关闭串口

//==============================================关闭串口==============================================
//关闭串口
void CSerialPortDlg::CloseConnection()
{if (!m_bConnected)return;m_bConnected = FALSE;SetCommMask(m_hCom, 0);CloseHandle(m_hCom);
}

3.6 更改串口、波特率、校验位、数据位、停止位

//==============================================更改串口设置==============================================
//更改串口
void CSerialPortDlg::OnCbnSelchangeComboCom()
{// TODO: 在此添加控件通知处理程序代码if (m_bConnected)CloseConnection();if (m_COMStatu){int i = m_Combo_Com.GetCurSel();OpenComm(i);}DisplayStatus();
}//更改波特率
void CSerialPortDlg::OnCbnSelchangeComboBaud()
{// TODO: 在此添加控件通知处理程序代码int baudindex;baudindex = m_Combo_Baud.GetCurSel();if (baudindex != CB_ERR){SetCommParameter();//把索引号为baudindex的数据放到m_Str_Baud变量中,传给m_Combo_Baud控件m_Combo_Baud.GetLBText(baudindex, m_Str_Baud); }DisplayStatus();
}//更改校验位
void CSerialPortDlg::OnCbnSelchangeComboCheck()
{// TODO: 在此添加控件通知处理程序代码int checkindex;checkindex = m_Combo_Check.GetCurSel();if (checkindex != CB_ERR){SetCommParameter();m_Combo_Check.GetLBText(checkindex, m_Str_Check);DisplayStatus();}
}//更改数据位
void CSerialPortDlg::OnCbnSelchangeComboData()
{// TODO: 在此添加控件通知处理程序代码int dataindex;dataindex = m_Combo_Data.GetCurSel();if (dataindex != CB_ERR){SetCommParameter();m_Combo_Data.GetLBText(dataindex, m_Str_Data);DisplayStatus();}
}//更改停止位
void CSerialPortDlg::OnCbnSelchangeComboStop()
{// TODO: 在此添加控件通知处理程序代码int stopindex;stopindex = m_Combo_Stop.GetCurSel();if (stopindex != CB_ERR){SetCommParameter();m_Combo_Stop.GetLBText(stopindex, m_Str_Stop);DisplayStatus();}
}

3.7 串口状态显示

//==========================================串口开关按钮状态显示==========================================
//串口状态显示
void CSerialPortDlg::OnBnClickedOpencomButton()
{// TODO: 在此添加控件通知处理程序代码m_COMStatu = !m_COMStatu;if (!m_COMStatu)GetDlgItem(IDC_PORTisOPEN_STATIC)->SetWindowText(_T("串口状态:串口已关闭"));elseGetDlgItem(IDC_PORTisOPEN_STATIC)->SetWindowText(_T("串口状态:串口已打开"));OnCbnSelchangeComboCom();DisplayStatus();return;
}

4 完整代码

4.1 …Dlg.h文件


// SerialPortDlg.h: 头文件
//#pragma once// CSerialPortDlg 对话框
class CSerialPortDlg : public CDialogEx
{
// 构造
public:CSerialPortDlg(CWnd* pParent = nullptr);	// 标准构造函数//变量=====================================================================================
public://自定义变量HANDLE			m_hCom;					//串口句柄volatile int	m_bConnected;			//串口连接成功指示BOOL			m_COMStatu;				//串口状态指示long			m_rxlen;				//接收数据个数long			m_txlen;				//发送数据个数//列表框变量CComboBox	m_Combo_Com;				//列表框:串口CComboBox	m_Combo_Baud;				//列表框:波特率CComboBox	m_Combo_Check;				//列表框:校验位CComboBox	m_Combo_Data;				//列表框:数据位CComboBox	m_Combo_Stop;				//列表框:停止位//字符变量CString		m_Str_Com;					//字符变量:串口CString		m_Str_Baud;					//字符变量:波特率CString		m_Str_Check;				//字符变量:校验位CString		m_Str_Data;					//字符变量:数据位CString		m_Str_Stop;					//字符变量:停止位//函数=====================================================================================
public://串口相关函数BOOL OpenComm(int Num);								//打开串口BOOL SetCommParameter();							//设置串口参数void DisplayStatus();								//显示串口状态void CloseConnection();								//关闭串口//按钮函数afx_msg void OnBnClickedOpencomButton();			//串口状态显示//列表框函数afx_msg void OnCbnSelchangeComboCom();				//更改串口afx_msg void OnCbnSelchangeComboBaud();				//更改波特率afx_msg void OnCbnSelchangeComboCheck();			//更改校验位afx_msg void OnCbnSelchangeComboData();				//更改数据位afx_msg void OnCbnSelchangeComboStop();				//更改停止位// 对话框数据
#ifdef AFX_DESIGN_TIMEenum { IDD = IDD_SERIALPORT_DIALOG };
#endifprotected:virtual void DoDataExchange(CDataExchange* pDX);	// DDX/DDV 支持// 实现
protected:HICON m_hIcon;// 生成的消息映射函数virtual BOOL OnInitDialog();afx_msg void OnSysCommand(UINT nID, LPARAM lParam);afx_msg void OnPaint();afx_msg HCURSOR OnQueryDragIcon();DECLARE_MESSAGE_MAP()};

4.2 …Dlg.cpp文件


// SerialPortDlg.cpp: 实现文件
//#include "pch.h"
#include "framework.h"
#include "SerialPort.h"
#include "SerialPortDlg.h"
#include "afxdialogex.h"#ifdef _DEBUG
#define new DEBUG_NEW
#endif// 用于应用程序“关于”菜单项的 CAboutDlg 对话框class CAboutDlg : public CDialogEx
{
public:CAboutDlg();// 对话框数据
#ifdef AFX_DESIGN_TIMEenum { IDD = IDD_ABOUTBOX };
#endifprotected:virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支持// 实现
protected:DECLARE_MESSAGE_MAP()
};CAboutDlg::CAboutDlg() : CDialogEx(IDD_ABOUTBOX)
{
}void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{CDialogEx::DoDataExchange(pDX);
}BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
END_MESSAGE_MAP()// CSerialPortDlg 对话框CSerialPortDlg::CSerialPortDlg(CWnd* pParent /*=nullptr*/): CDialogEx(IDD_SERIALPORT_DIALOG, pParent), m_Str_Com(_T("")), m_Str_Baud(_T("")), m_Str_Check(_T("")), m_Str_Data(_T("")), m_Str_Stop(_T(""))
{m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}void CSerialPortDlg::DoDataExchange(CDataExchange* pDX)
{CDialogEx::DoDataExchange(pDX);DDX_Control(pDX, IDC_COMBO1, m_Combo_Com);DDX_Control(pDX, IDC_COMBO2, m_Combo_Baud);DDX_Control(pDX, IDC_COMBO3, m_Combo_Check);DDX_Control(pDX, IDC_COMBO4, m_Combo_Data);DDX_Control(pDX, IDC_COMBO5, m_Combo_Stop);DDX_CBString(pDX, IDC_COMBO1, m_Str_Com);DDX_CBString(pDX, IDC_COMBO2, m_Str_Baud);DDX_CBString(pDX, IDC_COMBO3, m_Str_Check);DDX_CBString(pDX, IDC_COMBO4, m_Str_Data);DDX_CBString(pDX, IDC_COMBO5, m_Str_Stop);
}BEGIN_MESSAGE_MAP(CSerialPortDlg, CDialogEx)ON_WM_SYSCOMMAND()ON_WM_PAINT()ON_WM_QUERYDRAGICON()ON_BN_CLICKED(IDC_OPENCOM_BUTTON, &CSerialPortDlg::OnBnClickedOpencomButton)
END_MESSAGE_MAP()// CSerialPortDlg 消息处理程序BOOL CSerialPortDlg::OnInitDialog()
{CDialogEx::OnInitDialog();// 将“关于...”菜单项添加到系统菜单中。// IDM_ABOUTBOX 必须在系统命令范围内。ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);ASSERT(IDM_ABOUTBOX < 0xF000);CMenu* pSysMenu = GetSystemMenu(FALSE);if (pSysMenu != nullptr){BOOL bNameValid;CString strAboutMenu;bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);ASSERT(bNameValid);if (!strAboutMenu.IsEmpty()){pSysMenu->AppendMenu(MF_SEPARATOR);pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);}}// 设置此对话框的图标。  当应用程序主窗口不是对话框时,框架将自动//  执行此操作SetIcon(m_hIcon, TRUE);			// 设置大图标SetIcon(m_hIcon, FALSE);		// 设置小图标// TODO: 在此添加额外的初始化代码//========================================== = 初始化对话框========================================== =//设串口组合列表框TCHAR com[][6] = {_T("COM1"),_T("COM2"),_T("COM3"),_T("COM4"),_T("COM5"),_T("COM6"),_T("COM7"),_T("COM8"),_T("COM9") };for (int i = 0; i < 9; i++)m_Combo_Com.AddString(com[i]);m_Combo_Com.SetCurSel(0);//默认显示第1个串口号//设波特率组合列表框TCHAR baud[][7] = {_T("9600"),_T("19200"),_T("38400"),_T("43000"),_T("56000"),_T("57600"),_T("115200"),_T("128000"),_T("230400") };for (int i = 0; i < 9; i++)m_Combo_Baud.AddString(baud[i]);m_Combo_Baud.SetCurSel(5);//默认显示第6个波特率//设校验位组合列表框TCHAR check[][7] = {_T("None"),_T("Odd"),_T("Even") };for (int i = 0; i < 3; i++)m_Combo_Check.AddString(check[i]);m_Combo_Check.SetCurSel(0);//默认显示无校验//设数据位组合列表框TCHAR data[][2] = {_T("8"),_T("7"),_T("6") };for (int i = 0; i < 3; i++)m_Combo_Data.AddString(data[i]);m_Combo_Data.SetCurSel(0);//设停止位组合列表框TCHAR stop[][2] = { _T("1"),_T("2") };for (int i = 0; i < 2; i++)m_Combo_Stop.AddString(stop[i]);m_Combo_Stop.SetCurSel(0);//打开串口函数赋初值OpenComm(0);return TRUE;  // 除非将焦点设置到控件,否则返回 TRUE
}void CSerialPortDlg::OnSysCommand(UINT nID, LPARAM lParam)
{if ((nID & 0xFFF0) == IDM_ABOUTBOX){CAboutDlg dlgAbout;dlgAbout.DoModal();}else{CDialogEx::OnSysCommand(nID, lParam);}
}// 如果向对话框添加最小化按钮,则需要下面的代码
//  来绘制该图标。  对于使用文档/视图模型的 MFC 应用程序,
//  这将由框架自动完成。void CSerialPortDlg::OnPaint()
{if (IsIconic()){CPaintDC dc(this); // 用于绘制的设备上下文SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);// 使图标在工作区矩形中居中int cxIcon = GetSystemMetrics(SM_CXICON);int cyIcon = GetSystemMetrics(SM_CYICON);CRect rect;GetClientRect(&rect);int x = (rect.Width() - cxIcon + 1) / 2;int y = (rect.Height() - cyIcon + 1) / 2;// 绘制图标dc.DrawIcon(x, y, m_hIcon);}else{CDialogEx::OnPaint();}
}//当用户拖动最小化窗口时系统调用此函数取得光标
//显示。
HCURSOR CSerialPortDlg::OnQueryDragIcon()
{return static_cast<HCURSOR>(m_hIcon);
}//==============================================设置串口参数==============================================
//设置串口参数
BOOL CSerialPortDlg::SetCommParameter()
{DCB dcb;	//DCB结构,定义了串口通信设备的控制设置if (!GetCommState(m_hCom, &dcb))//读取新创建的 m_hCom串口句柄的 DCB设备控制块结构体,当只需要设置一部分 DCB参数时,可以通过此函数读取现有参数,只改变部分参数即可return FALSE;	//如果读取不成功直接结束//设置波特率long baudrate[] = { 300,600,1200,2400,4800,9600,19200,38400,43000,56000,57600,115200,128000,230400 };int baudindex = m_Combo_Baud.GetCurSel();m_Combo_Baud.GetLBText(baudindex, m_Str_Baud);dcb.BaudRate = baudrate[baudindex];//读取并设置波特率参数//设置数据位int databit[] = { 8,7,6 };int dataindex = m_Combo_Data.GetCurSel();m_Combo_Data.GetLBText(dataindex, m_Str_Data);dcb.ByteSize = databit[dataindex];//设置校验位int checkindex = m_Combo_Check.GetCurSel();m_Combo_Check.GetLBText(checkindex, m_Str_Check);switch (checkindex){case 0: dcb.Parity = NOPARITY; break;case 1: dcb.Parity = ODDPARITY; break;case 2: dcb.Parity = EVENPARITY; break;default:;}//设置停止位int stopindex = m_Combo_Stop.GetCurSel();m_Combo_Stop.GetLBText(stopindex, m_Str_Stop);switch (stopindex){case 0: dcb.StopBits = ONESTOPBIT; break;case 1: dcb.StopBits = TWOSTOPBITS; break;default:;}//流控制 dcb.fInX = FALSE;dcb.fOutX = FALSE;dcb.fNull = FALSE;	//为TRUE时,接收时自动去掉空(0值)字节dcb.fBinary = TRUE;	//指定是否允许二进制模式。Win32 API不支持非二进制模式传输,应设置为true dcb.fParity = FALSE;dcb.fOutxCtsFlow = FALSE;dcb.fOutxDsrFlow = FALSE;return(SetCommState(m_hCom, &dcb)); //应用设置
}//==============================================打开串口==============================================
//打开串口函数
BOOL CSerialPortDlg::OpenComm(int Num)
{m_Combo_Com.GetLBText(Num, m_Str_Com);//获取串口Combo下拉框中对应于Num位置的串口名称,比如Num=0时,m_SeriouStr 为"COM1"m_hCom = CreateFile(m_Str_Com, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);//将串口作为一个文件来看,用CreateFile()函数打开串口,返回结果存储在m_hCom中if (m_hCom == INVALID_HANDLE_VALUE)//如果返回INVALID_HANDLE_VALUE表示打开串口失败,{AfxMessageBox(_T("打开串口失败!"));	//失败时弹出对话框提醒m_bConnected = 0;				    //将串口连接标志设为0return FALSE;					    //打开失败后不再继续往下进行,直接返回FALSE}m_bConnected = 1;	//将串口连接标志设为1return 0;
}//============================================显示串口状态============================================
//显示串口状态
void CSerialPortDlg::DisplayStatus()
{CWnd* static_status = GetDlgItem(IDC_COMSTATUS_STATIC);CWnd* static_txlen  = GetDlgItem(IDC_TXLEN_STATIC);CWnd* static_rxlen  = GetDlgItem(IDC_RXLEN_STATIC);CString status_str, txlen_str, rxlen_str;if (m_bConnected){status_str = _T("STATUS:") + m_Str_Com + " OPENED," + m_Str_Baud + ',' + m_Str_Check + ',' + m_Str_Data + ',' + m_Str_Stop;SetCommParameter();}elsestatus_str = _T("STATUS:") + m_Str_Com + " CLOSED," + m_Str_Baud + ',' + m_Str_Check + ',' + m_Str_Data + ',' + m_Str_Stop;static_status->SetWindowText(status_str);txlen_str.Format(_T("TX: % ld"), m_txlen);static_txlen->SetWindowText(txlen_str);rxlen_str.Format(_T("RX:%ld"), m_rxlen);static_rxlen->SetWindowText(rxlen_str);
}//==============================================关闭串口==============================================
//关闭串口
void CSerialPortDlg::CloseConnection()
{if (!m_bConnected)return;m_bConnected = FALSE;SetCommMask(m_hCom, 0);CloseHandle(m_hCom);
}//==============================================更改串口设置==============================================
//更改串口
void CSerialPortDlg::OnCbnSelchangeComboCom()
{// TODO: 在此添加控件通知处理程序代码if (m_bConnected)CloseConnection();if (m_COMStatu){int i = m_Combo_Com.GetCurSel();OpenComm(i);}DisplayStatus();
}//更改波特率
void CSerialPortDlg::OnCbnSelchangeComboBaud()
{// TODO: 在此添加控件通知处理程序代码int baudindex;baudindex = m_Combo_Baud.GetCurSel();if (baudindex != CB_ERR){SetCommParameter();//把索引号为baudindex的数据放到m_Str_Baud变量中,传给m_Combo_Baud控件m_Combo_Baud.GetLBText(baudindex, m_Str_Baud); }DisplayStatus();
}//更改校验位
void CSerialPortDlg::OnCbnSelchangeComboCheck()
{// TODO: 在此添加控件通知处理程序代码int checkindex;checkindex = m_Combo_Check.GetCurSel();if (checkindex != CB_ERR){SetCommParameter();m_Combo_Check.GetLBText(checkindex, m_Str_Check);DisplayStatus();}
}//更改数据位
void CSerialPortDlg::OnCbnSelchangeComboData()
{// TODO: 在此添加控件通知处理程序代码int dataindex;dataindex = m_Combo_Data.GetCurSel();if (dataindex != CB_ERR){SetCommParameter();m_Combo_Data.GetLBText(dataindex, m_Str_Data);DisplayStatus();}
}//更改停止位
void CSerialPortDlg::OnCbnSelchangeComboStop()
{// TODO: 在此添加控件通知处理程序代码int stopindex;stopindex = m_Combo_Stop.GetCurSel();if (stopindex != CB_ERR){SetCommParameter();m_Combo_Stop.GetLBText(stopindex, m_Str_Stop);DisplayStatus();}
}//==========================================串口开关按钮状态显示==========================================
//串口状态显示
void CSerialPortDlg::OnBnClickedOpencomButton()
{// TODO: 在此添加控件通知处理程序代码m_COMStatu = !m_COMStatu;if (!m_COMStatu)GetDlgItem(IDC_PORTisOPEN_STATIC)->SetWindowText(_T("串口状态:串口已关闭"));elseGetDlgItem(IDC_PORTisOPEN_STATIC)->SetWindowText(_T("串口状态:串口已打开"));OnCbnSelchangeComboCom();DisplayStatus();return;
}

5 小改进

可以将 OnInitDialog() 函数中 串口初始化 部分进行 独立函数 封装

//初始化串口
BOOL CSerialPortDlg::InitComm()
{//设串口组合列表框TCHAR com[][6] = { _T("COM1"),_T("COM2"),_T("COM3"),_T("COM4"),_T("COM5"),_T("COM6"),_T("COM7"),_T("COM8"),_T("COM9") };for (int i = 0; i < 9; i++)m_Combo_Com.AddString(com[i]);m_Combo_Com.SetCurSel(0);//默认显示第1个串口号//设波特率组合列表框TCHAR baud[][7] = { _T("9600"),_T("19200"),_T("38400"),_T("43000"),_T("56000"),_T("57600"),_T("115200"),_T("128000"),_T("230400") };for (int i = 0; i < 9; i++)m_Combo_Baud.AddString(baud[i]);m_Combo_Baud.SetCurSel(5);//默认显示第6个波特率//设校验位组合列表框TCHAR check[][7] = { _T("None"),_T("Odd"),_T("Even") };for (int i = 0; i < 3; i++)m_Combo_Check.AddString(check[i]);m_Combo_Check.SetCurSel(0);//默认显示无校验//设数据位组合列表框TCHAR data[][2] = { _T("8"),_T("7"),_T("6") };for (int i = 0; i < 3; i++)m_Combo_Data.AddString(data[i]);m_Combo_Data.SetCurSel(0);//设停止位组合列表框TCHAR stop[][2] = { _T("1"),_T("2") };for (int i = 0; i < 2; i++)m_Combo_Stop.AddString(stop[i]);m_Combo_Stop.SetCurSel(0);return true;
}

6 完整MFC项目项下载

MFC串口助手初级版实现(串口设置、初始化、打开、关闭、状态显示)—代码注释非常详细

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/915038.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/915038.shtml
英文地址,请注明出处:http://en.pswp.cn/news/915038.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

TBT 5、TBT 4 和 USB4 的差异概述

Thunderbolt 4 和 USB4 如今已成为笔记本电脑、电脑、电码头等移动电子设备中最常见的连接标准。 Thunderbolt 4 和 USB4 皆采用 USB Type-C 连接器&#xff0c;也因设计和功能上有许多相似之处而兼容。 这两种技术还支持 40Gbps 的数据传输速度、视频直通以及高达 240W 的电源…

算法-查找算法

下面是使用 Java 实现的四种查找算法&#xff1a; 线性查找&#xff08;Linear Search&#xff09;二分查找&#xff08;Binary Search&#xff09;插值查找&#xff08;Interpolation Search&#xff09;斐波那契查找&#xff08;Fibonacci Search&#xff09;✅ 1. 线性查找&…

二刷 黑马点评 附近商户

附近商户-GEO数据结构的基本用法 GEO就是Geolocation的简写形式&#xff0c;代表地理坐标 Redis在3.2版本中加入了对GEO的支持&#xff0c;允许存储地理坐标信息&#xff0c;帮助我们根据经纬度来检索数据。常见的命令有&#xff1a;GEOADD&#xff1a;添加一个地理空间信息&am…

【vue-3】深入理解 Vue 3 中的 v-if 指令:条件渲染的艺术

在 Vue.js 的世界中&#xff0c;条件渲染是构建动态界面的核心概念之一。作为 Vue 3 中最常用的指令之一&#xff0c;v-if 提供了强大的能力来控制元素的显示与隐藏。本文将深入探讨 v-if 的工作原理、最佳实践以及它在 Vue 3 中的新特性。 1. 什么是 v-if&#xff1f; v-if 是…

【实时Linux实战系列】实时系统中的内存策略

在实时系统中&#xff0c;内存管理是确保系统性能和稳定性的重要组成部分。实时系统通常需要快速响应和低延迟&#xff0c;因此高效的内存管理策略对于实现这些目标至关重要。实时 Linux 提供了多种内存管理机制&#xff0c;如使用大型页面&#xff08;Huge Pages&#xff09;和…

【C语言进阶】题目练习(2)

目录 题目6:看代码说结果 分析&#xff1a; 答案&#xff1a;255 题目7&#xff1a;猜名次 分析&#xff1a; 题目8&#xff1a;猜凶手 分析&#xff1a; 代码&#xff1a; 题目9&#xff1a;打印杨辉三角 思路: 代码: 题目10&#xff1a;关于指针的选择题 答案&a…

思科NAT综合实验

1 实验拓扑图2实验目的(1)巩固前面实验的配置(2)掌握四种NAT的配置(3)明白四种NAT的区别3实验步骤3.1配置边界路由器和外网路由器的端口IP三个步骤&#xff1a;进入端口 打开端口 配置IP地址和子网掩码interface f0/0 no shutdown ip address 192.168.201.2 255.255.255.03.2配…

VMC850立式加工中心Y轴传动机械结构设计cad【7张】三维图+设计说明书

摘 要 数控机床作为现代工业生产的重要设备&#xff0c;对国民经济的发展有着重要的作用&#xff0c;立式加工中心作为数控加工技术的核心&#xff0c;通过对其研究&#xff0c;可以深入了解数控技术未来的发展方向。本文主要完成了VMC850立式加工中心Y轴的机械传动结构设计&am…

mpiigaze的安装过程一

mpiigaze链接 mpiigaze应该不是作者本人写的&#xff0c;而是社区工作者的杰作&#xff0c;对原论文Appearance-Based Gaze Estimation in the Wild的代码进行的一些复现 1.创建conda环境 2.问题 Building wheels for collected packages: dlibBuilding wheel for dlib (py…

如何将华为文件传输到电脑

在数字管理领域&#xff0c;将华为设备上的文件传输到电脑是高频需求。无论为了备份、缓解手机存储压力&#xff0c;还是跨平台访问&#xff0c;把华为手机连接电脑已成为许多用户的刚需。下面介绍 5 种高效方法&#xff0c;可满足不同场景与偏好&#xff0c;助你轻松完成文件迁…

LP-MSPM0G3507学习--05中断及管脚中断

关键函数&#xff1a; NVIC_EnableIRQ(IRQn_Type IRQn)&#xff1a;使能中断 例5-1&#xff1a;单按键中断方式实现led灯的亮灭 在上一讲LP-MSPM0G3507学习--04GPIO控制中实现了通过按键控制led灯的亮灭&#xff0c;可以看出程序效率不高&#xff0c;下面采用中断的方式实现…

mac系统安装、启动Jenkins,创建pytest接口自动化任务

先安装Homebrew&#xff1a;mac系统安装brew-CSDN博客 1、安装Jenkins # 可以安装长期支持版本 brew install jenkins-lts# 或者最新版本&#xff08;我安了这个&#xff09; brew install jenkins 可查看Jenkins安装位置&#xff1a; # 最新版本 brew --prefix jenkins 2、…

设置第三方窗口置顶(SetWindowPos方法,vb.net)

起源在日常办公、游戏时&#xff0c;我们经常需要一些窗口处于置顶状态&#xff0c;而这些窗口往往是网页端&#xff08;浏览器&#xff09;、办公软件&#xff08;wps、office等&#xff09;&#xff0c;这些需要置顶的窗口往往自身没有明显的置顶开关&#xff0c;因此&#x…

Docker-下载和安装

一、Linux版 1.安装docker &#xff08;1&#xff09;更新软件包索引 sudo apt update &#xff08;2&#xff09;安装必要的依赖 sudo apt install apt-transport-https ca-certificates curl software-properties-common &#xff08;3&#xff09;添加 Docker 官方 GP…

电脑DLL错误修复dll微软运行库工具修复dll缺失找不到dll等问题,dll免费修复工具

解决DLL文件缺失问题&#xff1a;我的使用体验与建议 在使用电脑的过程中&#xff0c;我们常常会遇到软件或系统报错&#xff0c;例如“无法找到指定模块”或“缺少某.dll文件”等提示。DLL&#xff08;动态链接库&#xff09;是Windows系统中不可或缺的组件&#xff0c;为应用…

HTTPS的工作原理及DNS的工作过程

HTTPSHTTP协议安全上存在以下三个风险&#xff1a;完整性 可用性 保密性窃听风险&#xff0c;比如通信链路上可以获取通信内容&#xff0c;用户号容易没。篡改风险&#xff0c;比如强制植入垃圾广告&#xff0c;视觉污染&#xff0c;用户眼容易瞎。冒充风险&#xff0c;比如冒充…

VisualXML全新升级 | 新增BusLoad计算

VisualXML是一个功能强大的网络总线设计工具&#xff0c;专注于简化汽车电子系统中复杂的网络数据设计操作。该软件支持多种主流总线网络格式的数据编辑&#xff08;如DBC、LDF、ARXML、HEX等&#xff09;&#xff0c;并能够基于Excel表格的方式生成和转换多种数据库文件。由此…

李天意考研数学精讲课学习笔记(课堂版)

视频链接&#xff1a;【考研数学精讲课李天意】基础强化真题&#xff0c;概念精讲与解题技巧&#xff08;适用数学一/二/三&#xff09;_哔哩哔哩_bilibili 讲义&#xff1a;夸克网盘分享 高数6 不定积分

闲庭信步使用图像验证平台加速FPGA的开发:第二十三课——图像直方图和灰度图像叠加的FPGA实现

&#xff08;本系列只需要modelsim即可完成数字图像的处理&#xff0c;每个工程都搭建了全自动化的仿真环境&#xff0c;只需要双击top_tb.bat文件就可以完成整个的仿真&#xff0c;大大降低了初学者的门槛&#xff01;&#xff01;&#xff01;&#xff01;如需要该系列的工程…

C++并发编程-14. 利用栅栏实现同步

前文我们通过原子操作实战实现了无锁队列&#xff0c;今天完善一下无锁的原子操作剩余的知识&#xff0c;包括Relaese和Acquire内存序在什么情况下是存在危险的&#xff0c;以及我们可以利用栅栏机制实现同步等等。 线程可见顺序 我们提到过除了memory_order_seq_cst顺序&#…