vs2010基于Win32API串口通信MFC实例

83 篇文章 3 订阅

介绍如何使用win32API函数进行通信端口的编程,因为串口数据接收需要不停地监视串口和处理串口事件,因此,再本实例中将其封装为单个线程执行类。

创建串口线程类并初始化,由CThreadCom1对象的构造函数完成,它实现串口工作变量的初始化工作。

CThreadCom1::CThreadCom1(HANDLE hCom)
{
	m_hCom=hCom;
	m_bInit=false;
	m_sCom="";
	m_sError="No Error!";
	m_hThread=NULL;
	m_dwSendMsgToParent=0;
	m_dwRecvMsgToParent=0;
	m_pWndParent=NULL;
	memset((unsigned char*)&m_overRead,0,sizeof(OVERLAPPED));
	memset((unsigned char*)&m_overWrite,0,sizeof(OVERLAPPED));
	m_overRead.hEvent=CreateEvent(NULL,true,false,NULL);
	m_overWrite.hEvent=CreateEvent(NULL,true,false,NULL);
	
}

CThreadCom1::~CThreadCom1()
{
	CloseHandle(m_overRead.hEvent);
	CloseHandle(m_overWrite.hEvent);
}

BOOL CThreadCom1::InitInstance()
{
	// TODO: 在此执行任意逐线程初始化
	m_bAutoDelete=false;
	m_bDone=false;
	return TRUE;
}

int CThreadCom1::ExitInstance()
{
	// TODO: 在此执行任意逐线程清理
	BOOL bFlag=CloseCom();
	return CWinThread::ExitInstance();
}

串口接收线程的处理工作由CThreadCom1对象的Run()函数完成。它实现

循环从串口读取数据,并将接收的数据发送给处理函数的功能。

int CThreadCom1::Run(void)//重载线程类的Run()运行函数
{
	//return 0;
	DWORD dwError,dwReadNum,dwByteRead,dwEvent;
	COMSTAT	ComStat;//串口状态变量
	BYTE rBuf[MAXCOMINBUF];//输入缓冲区
	while(!m_bDone)
	{
		while(m_hCom!=INVALID_HANDLE_VALUE)
		{
			if(::WaitCommEvent(m_hCom,&dwEvent,NULL))//等待注册的串口事件发生
			{
				dwByteRead=0;//初始化读字节数
				if(dwEvent&EV_RXCHAR)
				{
					ClearCommError(m_hCom,&dwError,&ComStat);//清空当前串口事件
					if(ComStat.cbInQue!=0)//输入列队中的数据个数
					{
						dwReadNum=ComStat.cbInQue;
						dwByteRead=0;
						if(dwReadNum>200)
							dwReadNum=200;
						memset(rBuf,0,sizeof(rBuf));//清空接收缓冲区变量
						DWORD i=::ReadFile(m_hCom,rBuf,dwReadNum,&dwByteRead,&m_overRead);
						for(i=dwByteRead;i<1024;i++)
							rBuf[i]=0;//用0x00填充剩余字节
					}
				}
				if(dwByteRead)
					if(m_pWndParent)
						m_pWndParent->SendMessage(m_dwRecvMsgToParent,(DWORD)rBuf,dwByteRead);//读取的数据发送到父窗口
						
			}

		}
		Sleep(1000);
	}
	return CWinThread::Run();//调用基类的Run()函数
}

//打开串口,根据程序配置,打开指定工作串口的功能

BOOL CThreadCom1::OpenCom(CString strCom, CWnd* pWndParent, DWORD dwSendMsgToParent, DWORD dwRecvMsgToParent)
{
	//return 0;
	CloseCom();
	CString strLog;
	m_hCom=::CreateFile(strCom,GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,NULL);//打开串口
	if(m_hCom==INVALID_HANDLE_VALUE)
	{
		strLog.Format("Open %s Error",strCom);
		AfxMessageBox(strLog);
		return FALSE;
	}
	::SetupComm(m_hCom,MAXCOMINBUF,MAXCOMOUTBUF);//设置串口输入输出缓冲区
	DCB dcb;//定义DCB结构
	if(!GetCommState(m_hCom,&dcb))
	{
		AfxMessageBox("获取串口状态错误");
		CloseHandle(m_hCom);
		m_hCom=INVALID_HANDLE_VALUE;
		return FALSE;
	}
	if(!SetCommState(m_hCom,&dcb))
	{
		CloseHandle(m_hCom);
		m_hCom=INVALID_HANDLE_VALUE;
		strLog.Format("set %s CommState Error!",strCom);
		AfxMessageBox(strLog);
		return FALSE;
	}
	//

	m_sError="No Error";	
	m_pWndParent	=	pWndParent;//存储父窗口句柄
	m_dwSendMsgToParent	= dwSendMsgToParent;//存储接收发送消息的父窗口
	m_dwRecvMsgToParent	= dwRecvMsgToParent;//存储接收接收消息的父窗口



	//
	DWORD CommMask;
	CommMask=0|EV_BREAK|EV_CTS|EV_DSR|EV_ERR|EV_EVENT1|EV_EVENT2|EV_PERR|EV_RING|EV_RLSD|EV_RX80FULL|EV_RXCHAR|EV_RXFLAG|EV_TXEMPTY;
	::SetCommMask(m_hCom,CommMask);//注册要处理的事件
	::GetCommTimeouts(m_hCom,&m_Commtimeout);//读取超时时间设置
	m_Commtimeout.ReadTotalTimeoutMultiplier=5;
	m_Commtimeout.ReadTotalTimeoutConstant=100;
	m_bInit=true;
	return TRUE;


}

//关闭串口

BOOL CThreadCom1::CloseCom(void)
{
	//return 0;
	if(m_hCom!=INVALID_HANDLE_VALUE)
	{
		PurgeComm(m_hCom,PURGE_RXCLEAR);//释放串口事件
		CloseHandle(m_hCom);
		m_hCom=INVALID_HANDLE_VALUE;//设置句柄无效
	}
	m_bInit=false;
	return true;
}

//发送数据

BOOL CThreadCom1::SendData(BYTE* s, DWORD dwLen)
{
	//return 0;
	if(!dwLen)
		return false;
	::GetCommTimeouts(m_hCom,&m_Commtimeout);
	m_Commtimeout.WriteTotalTimeoutMultiplier=0;//设置读操作超时时间
	m_Commtimeout.WriteTotalTimeoutConstant=2*dwLen;//设置读操作超时常量

	::SetCommTimeouts(m_hCom,&m_Commtimeout);//设置超时时间设置
	if(m_hCom!=INVALID_HANDLE_VALUE)
	{
		DWORD dwSend;
		m_pWndParent->SendMessage(m_dwSendMsgToParent,(DWORD)s,dwLen);
	//发送日志
		if(!WriteFile(m_hCom,s,dwLen,&dwSend,&m_overWrite))//向串口发送数据
		{
			m_sError="串口发送数据失败";
			return false;
		}
		return true;
	}
	else
	{
		m_sError="串口句柄无效";
		return false;
	}
}

串口线程类代码结束后。界面的处理,对话框类中,实现相关按钮触发事件。

对话框类头文件相关声明:

public:
//	CString m_Log;
	CString m_editSend;
	CString m_editReceive;
	CComboBox m_comboComm;
	afx_msg void OnBnClickedButtonOpenserial();
	CThreadCom1* pThreadCom; 
	BOOL m_bCom;
	void WriteLog(CString log);
	afx_msg void OnBnClickedButtonSend();
//	void OnSendMsg(DWORD dwEvent, DWORD dwLen);
	CEdit m_Log;
//	void OnRecvMsg(DWORD dwEvent, DWORD dwLen);
	//HRESULT OnSendMsg(DWORD dwEvent, DWORD dwLen);
	HRESULT OnSendMsg(WPARAM dwEvent, LPARAM dwLen);
	//HRESULT OnRecvMsg(DWORD dwEvent, DWORD dwLen);
	HRESULT OnRecvMsg(WPARAM dwEvent, LPARAM dwLen);
	CEdit m_edit_Receive1;

//打开串口的按钮

void CTxwtechWin32API_CommDlg::OnBnClickedButtonOpenserial()
{
	// TODO: 在此添加控件通知处理程序代码
	if(pThreadCom!=NULL) return;
	CString str;
	CString com;
	//int com1;
	//com1=m_comboComm.GetCurSel();
	//com1+=1;
	//com=m_comboComm.GetWindowText();
	m_comboComm.GetWindowTextA(com);//获取组合框com的内容
	//com.Format("%s",com1);
	pThreadCom=(CThreadCom1*)AfxBeginThread(RUNTIME_CLASS(CThreadCom1));
	pThreadCom->SetComStr(com);//设置串口线程的串口名称变量
	if(pThreadCom->OpenCom(com,(CWnd*)this->GetSafeOwner(),WM_USER_COMSENDMESSAGE,WM_USER_COMRECVMESSAGE))
	{
		str.Format("打开串口%s成功",pThreadCom->GetComStr());
		WriteLog(str);
	}
	else
	{
		str.Format(pThreadCom->m_sError+",请重新配置串口");
		WriteLog(str);
		pThreadCom->m_bInit=FALSE;
		return;
	}
	m_bCom=TRUE;
	m_comboComm.EnableWindow(FALSE);
	return;
}

//发送按钮绑定的代码

void CTxwtechWin32API_CommDlg::OnBnClickedButtonSend()
{
	// TODO: 在此添加控件通知处理程序代码
	UpdateData(true);
	int iLen=m_editSend.GetLength();
	BYTE* s=new BYTE[iLen];
	memset(s,0x00,iLen);//初始化数据缓冲区
	memcpy(s,(LPCTSTR)m_editSend,iLen);//复制数据
	pThreadCom->SendData((unsigned char*)s,iLen);
}

//发送数据通知

HRESULT CTxwtechWin32API_CommDlg::OnSendMsg(WPARAM dwEvent, LPARAM dwLen)
{
	if(!dwLen)
		return 0;
	BYTE* temp=new BYTE[dwLen+1];
	memset(temp,0x00,dwLen+1);
	memcpy(temp,(const void*)dwEvent,dwLen);
	CString log;
	log.Format("\r\n发送数据%s",(LPCTSTR)temp);
	if(m_Log)
	{
		CEdit* editLog=(CEdit*)FromHandle(m_Log);
		if(editLog->GetWindowTextLength()>50000)
		{
			editLog->SetSel(0,-1);//把发送区的全部内容选中
			editLog->Clear();//清空全部内容
			editLog->SetSel(0,0);//设置光标到0字节处
			editLog->ReplaceSel(log);//更新新的内容
		}
		else
		{
			editLog->SetSel(editLog->GetWindowTextLength(),editLog->GetWindowTextLength());//光标指向句末
			editLog->ReplaceSel(log);//添加新内容
		}
	}
//	return;
	return E_NOTIMPL;
}

//接收消息通知

HRESULT CTxwtechWin32API_CommDlg::OnRecvMsg(WPARAM dwEvent, LPARAM dwLen)
{
	if(!dwLen) return 0;
	BYTE* temp=new BYTE[dwLen+1];
	memset(temp,0x00,dwLen+1);
	memcpy(temp,(const void*)dwEvent,dwLen);
	CString log;
	log.Format("\r\n接收数据=%s",(LPCTSTR)temp);
	if(m_editReceive.GetLength()>50000)
		m_editReceive="";
	m_editReceive+=log;
	CEdit* editLog=(CEdit*)FromHandle(m_edit_Receive1);
	editLog->SetSel(editLog->GetWindowTextLength(),editLog->GetWindowTextLength());
			editLog->ReplaceSel(log);
	//UpdateData(false);
	return E_NOTIMPL;
}

相关调试遇到的问题:

error C2511: “CThreadCom1::CThreadCom1(HANDLE)”:“CThreadCom1”中没有找到重载的成员函数
原因:头文件未定义。
CThreadCom1(HANDLE hCom=INVALID_HANDLE_VALUE);
error C2668: “CThreadCom1::CThreadCom1”: 对重载函数的调用不明确
头文件中只有有一个重载函数,把默认的删除掉

TxwtechWin32API_Comm.exe 中的 0x100c14cf (msvcr100d.dll) 处有未经处理的异常: 0xC0000005: 读取位置 0x00000002 时发生访问冲突,
rootcause:连接串口不能是数值,而是字符串COM1...

TxwtechWin32API_Comm.exe 中的 0x7898391c (mfc100d.dll) 处有未经处理的异常: 0xC0000005: 读取位置 0x00000020 时发生访问冲突
缺少如下两句://m_dwSendMsgToParent 没有获取父窗口的值
//m_dwSendMsgToParent = dwSendMsgToParent;
 m_dwRecvMsgToParent = dwRecvMsgToParent;

接收框中无法接收消息,注意消息的映射与宏定义

#define WM_USER_COMSENDMESSAGE WM_USER+200
#define WM_USER_COMRECVMESSAGE WM_USER+201

BEGIN_MESSAGE_MAP(CTxwtechWin32API_CommDlg, CDialogEx)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDC_BUTTON_OpenSerial, &CTxwtechWin32API_CommDlg::OnBnClickedButtonOpenserial)
	ON_BN_CLICKED(IDC_BUTTON_Send, &CTxwtechWin32API_CommDlg::OnBnClickedButtonSend)
	ON_MESSAGE(WM_USER_COMSENDMESSAGE,OnSendMsg)
	ON_MESSAGE(WM_USER_COMRECVMESSAGE,OnRecvMsg)
END_MESSAGE_MAP()

  • 2
    点赞
  • 51
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 8
    评论
里面讲了MSComm控件 、 WinAPI 串口通信、CSerial类,例子很详实,每一步操作都有解释。作者是龚建伟,有一个个人主页www.gjwtech.com,讲串口通信的内容比较多,还行,大家可以先看看这个主页。 本书目录 第1章轻松体验串口通信编程与调试 1.1初识串口 1.1.1从外观上了解串口 1.1.2 串口通信的发展前景 1.2 自己制作简单的串口线 1.2.1 三线制串口接线的规定 1.2.2 焊接制作自己的串口连接线 1.3 调试串口通信程序时的几种使用串口的技巧 1.3.1 查看计算机串口资源 1.3.2 常规调试-2个物理串口之间的通信 1.3.3 特殊调试-单个物理串口之间的通信 1.3.4 虚拟串口-为计算机添加取之不尽的串口资源 1.4 使用串口调试助手来体验串口通信 1.5体验Windows环境下Visual C++串口通信编程 1.6体验DOS环境下Turbo C串口通信编程 第2章 VC多线程串口编程工具CSerialPort类 2.1 类功能及成员函数介绍 2.2 应用CSerialPort类编制基于对话框的应用程序 2.3 应用CSerialPort类编制基于单文档的应用程序 2.4对CSerialPort类的改进 2.5 在Visual C++.NET中应用CSerialPort类 第3章 控件MSComm串口编程 3.1 MSComm控件详细介绍 3.1.1 VC中应用MSComm控件编程步骤 3.1.2 MSComm控件串行通信处理方式 3.1.3 MSComm 控件的属性说明 3.1.4 MSComm控件错误信息 3.2使用MSComm控件的几个疑难问题 3.2.1使用VARIANT 和SAFEARRAY 数据类型从串口读写数据 3.2.2 MSComm控件能离开对话框独立存在吗? 3.2.3 如何发送接收ASCII值为0和大于128的字符? 3.2.4 在同一程序中用MSComm控件控制多个串口的具体操作方法 3.2.5解决使用控件编程时程序占用的内存会不断增大的问题 3.2.6在没有安装Visual Studio的计算机上如何使用MSComm控件 3.2.7 在MSComm控件串口编程时遇到的其它问题说明 3.3在基于单文档(SDI)程序中应用MSComm控件 3.4应用MSComm控件控制多个串口实例 第4章 Windows API串口编程 4.1 Windows API串口编程概述 4.2 API串口编程中用到的结构及相关概念说明 4.2.1 DCB(Device Control Block)结构 4.2.2超时设置COMMTIMEOUTS结构 4.2.3 OVERLAPPED异步I/O重叠结构 4.2.4 通信错误与通信设备状态 4.2.5 串行通信事件 4.3 Windows API串行通信函数 4.4 Win32 API串口通信编程的一般流程和特殊实例 4.4.1 Win32 API串口通信编程的一般流程 4.4.2 用查询方式读串口 4.4.3同步I/O读写数据 4.4.4 关于流控制的设置问题 4.5 CSerialPort类中的API函数编程应用剖析 4.6 Win32 API串口编程TTY(虚拟终端)实例 4.7 Windows API串口精简例程 第5章 串口调试助手V2.2详细编程 5.1 建立SCOMM程序工程实现界面功能 5.2 串口的初始化及关闭 5.3串口数据的发送与接收及十六进制数据的处理 5.3.1 十六进数据发送处理 5.3.2 手动发送处理 5.3.3自动发送处理 5.3.4 接收处理及十六进制显示 5.4 其它辅助功能的实现 5.4.1 接收数据的文件保存 5.4.2 实现小文件发送 5.4.3 图钉按钮功能使程序能浮在最上层 5.4.4 对话框动画图标的实现 5.4.5 超链接功能的实现 5.4.6 如何打开帮助网页文件 第6章 DOS环境下的Turbo C串口编程及通用实例GSerial类 6.1 PC机异步通信适配器8250及其编程操作 6.1.1 INS8250内部寄存器及其选择方式 6.1.2 波特率设置 6.1.3数据位、奇偶校验、停止位等数据格式设置 6.1.4 查询I/O方式相关设置 6.1.5 中断I/O通信方式相关设置 6.1.6 Modem寄存器 6.2 COMRXTX程序实例
### 回答1: VS2010是Microsoft开发的集成开发环境,具有丰富的功能和强大的调试工具。基于Win32 APIMFC开发串口通信功能是相对常见的需求。下面是一个基于Win32 APIMFC实现串口通信的示例: 1. 首先,在VS2010中创建一个新的MFC项目。选择创建一个对话框应用程序。 2. 打开资源视图,找到对话框资源,并双击打开对话框编辑器。 3. 在对话框中添加两个按钮和一个编辑框。一个按钮用于打开串口,另一个按钮用于关闭串口。编辑框用于显示和接收串口数据。 4. 在类视图中找到对话框类,右击并选择“添加成员变量”。添加一个CComboBox类型的成员变量,用于选择串口号。添加一个CEdit类型的成员变量,用于显示和接收串口数据。 5. 在对话框类的头文件中包含头文件"afxwin.h"、"afxmt.h"和"atlstr.h"。 6. 在对话框类的头文件中添加以下成员变量: ``` HANDLE m_hComm; //串口句柄 CEvent m_Event; //事件对象 CPtrList m_List; //接收数据的链表 ``` 7. 在OnInitDialog函数中初始化串口号下拉框,并为两个按钮添加按钮事件处理程序。 8. 实现打开串口的函数OpenPort,代码如下: ``` bool CMySerialDlg::OpenPort(CString strPort) { DCB dcb; CString strCom; strCom.Format(_T("\\\\.\\%s"), strPort); m_hComm = CreateFile(strCom, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL); if (m_hComm == INVALID_HANDLE_VALUE) { AfxMessageBox(_T("无法打开串口")); return false; } GetCommState(m_hComm, &dcb); dcb.BaudRate = 9600; //设置波特率 dcb.ByteSize = 8; //设置数据位 dcb.Parity = NOPARITY; //设置校验位 dcb.StopBits = ONESTOPBIT; //设置停止位 SetCommState(m_hComm, &dcb); m_Event.ResetEvent(); ::ResetEvent(m_OL.hEvent); //创建一个独立的线程来接收串口数据 AfxBeginThread(RecvThread, this); return true; } ``` 9. 实现关闭串口的函数ClosePort,代码如下: ``` void CMySerialDlg::ClosePort() { if (m_hComm != INVALID_HANDLE_VALUE) { PurgeComm(m_hComm, PURGE_TXCLEAR | PURGE_RXCLEAR); CloseHandle(m_hComm); m_hComm = INVALID_HANDLE_VALUE; } m_Event.SetEvent(); } ``` 10. 创建一个独立的线程来接收串口数据,代码如下: ``` UINT RecvThread(LPVOID pParam) { CMySerialDlg* pDlg = (CMySerialDlg*)pParam; BOOL bResult = TRUE; DWORD dwBytesRead = 0; OVERLAPPED m_OL; m_OL.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); //不停地接收串口数据 while (!::WaitForSingleObject(pDlg->m_Event, 0)) { bResult = ReadFile(pDlg->m_hComm, pDlg->m_buffer, sizeof(pDlg->m_buffer), &dwBytesRead, &m_OL); if (!bResult && GetLastError() != ERROR_IO_PENDING) { break; } ::WaitForSingleObject(m_OL.hEvent, INFINITE); pDlg->m_List.AddTail(dwBytesRead); //将接收到的数据添加到链表中 pDlg->m_Event.SetEvent(); } CloseHandle(m_OL.hEvent); return 0; } ``` 11. 在按钮的点击事件处理程序中调用OpenPort函数和ClosePort函数来打开关闭串口,并在链表中读取和显示串口数据。 12. 编译和运行程序,可以在对话框中选择串口号并通过按钮打开和关闭串口串口数据将在编辑框中显示并可以通过编辑框发送到串口。 以上就是一个基于Win32 APIMFC实现串口通信的示例。 ### 回答2: 在VS2010中,可以使用Win32 APIMFC来进行串口通信。下面是一个基于Win32 APIMFC串口通信示例: 首先,我们需要创建一个MFC应用程序。在创建应用程序的对话框中,勾选“对话框”选项,并在下一步中选择“基于对话框”的应用程序类型。 在对话框资源中,添加两个按钮,一个用于打开串口,另一个用于关闭串口。 打开串口按钮的点击事件处理程序中,我们需要调用Win32 API函数来进行串口的初始化和打开。示例代码如下: ``` void CMyDlg::OnBnClickedOpenPort() { // 获取串口号和波特率 int nPort = GetDlgItemInt(IDC_EDIT_PORT); int nBaudrate = GetDlgItemInt(IDC_EDIT_BAUDRATE); // 打开串口 HANDLE hPort = CreateFileA("COM" + std::to_string(nPort).c_str(), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); if (hPort != INVALID_HANDLE_VALUE) { // 配置串口参数 DCB dcb; dcb.DCBlength = sizeof(DCB); GetCommState(hPort, &dcb); dcb.BaudRate = nBaudrate; dcb.ByteSize = 8; dcb.Parity = NOPARITY; dcb.StopBits = ONESTOPBIT; SetCommState(hPort, &dcb); // 设置读写超时时间 COMMTIMEOUTS timeouts; timeouts.ReadIntervalTimeout = MAXDWORD; timeouts.ReadTotalTimeoutConstant = 0; timeouts.ReadTotalTimeoutMultiplier = 0; timeouts.WriteTotalTimeoutConstant = 1000; timeouts.WriteTotalTimeoutMultiplier = 0; SetCommTimeouts(hPort, &timeouts); // 保存串口句柄 m_hPort = hPort; // 禁用打开串口按钮,启用关闭串口按钮 GetDlgItem(IDC_BUTTON_OPENPORT)->EnableWindow(FALSE); GetDlgItem(IDC_BUTTON_CLOSEPORT)->EnableWindow(TRUE); } else { // 打开串口失败 AfxMessageBox(_T("打开串口失败!")); } } ``` 关闭串口按钮的点击事件处理程序中,我们需要调用Win32 API函数来关闭串口并释放资源。示例代码如下: ``` void CMyDlg::OnBnClickedClosePort() { if (m_hPort != INVALID_HANDLE_VALUE) { // 关闭串口 CloseHandle(m_hPort); // 清空串口句柄 m_hPort = INVALID_HANDLE_VALUE; // 启用打开串口按钮,禁用关闭串口按钮 GetDlgItem(IDC_BUTTON_OPENPORT)->EnableWindow(TRUE); GetDlgItem(IDC_BUTTON_CLOSEPORT)->EnableWindow(FALSE); } } ``` 以上就是一个简单的基于Win32 APIMFC串口通信示例。在实际应用中,还需要处理串口数据的读取和写入等操作,以实现具体的数据通信功能。 ### 回答3: VS2010基于Win32API串口通信MFC实例可以通过以下步骤实现。 1. 首先,建立一个MFC应用程序项目,选择“对话框”类型,并创建一个对话框界面。 2. 打开资源视图,在对话框中添加一个编辑框(用于显示串口收发的数据),两个按钮(一个用于打开串口,另一个用于发送数据),以及一个组合框(用于选择串口号和波特率)。 3. 在对话框的类文件中添加相应的头文件和变量声明。头文件中包括afxwin.h、winbase.h和commdlg.h等。 4. 在OnInitDialog()函数中初始化串口列表并将其添加到组合框中,同时设置波特率。 5. 添加按钮的响应函数,包括打开串口的按钮OnClickOpenSerial()和发送数据的按钮OnClickSendData()。 6. 在OnClickOpenSerial()函数中,使用CreateFile()函数打开选中的串口号,并设置相应的串口参数,如波特率、数据位、停止位和校验位等。 7. 在OnClickSendData()函数中,通过WriteFile()函数向串口发送数据。 8. 创建一个新的线程,用于读取串口数据。通过WaitCommEvent()函数等待串口数据的到来,并使用ReadFile()函数读取收到的数据。 9. 将读取到的数据显示在编辑框中,可以通过SendMessage()函数将数据添加到编辑框的末尾,并使用SetSel()函数将光标移到末尾。 10. 在程序结束时,需要关闭串口,使用CloseHandle()函数关闭句柄。 以上是一个简单的基于Win32API串口通信MFC实例。根据需要可以进一步添加错误处理、数据校验和其他功能。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

txwtech笛克特科

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

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

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

打赏作者

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

抵扣说明:

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

余额充值