C++MFC 串口通信 上位机

这篇具有很好参考价值的文章主要介绍了C++MFC 串口通信 上位机。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

本节介绍

        在工业控制中,工控机(一般都基于Windows平台)经常需要与智能仪表通过串口进行通信。串口通信方便易行,应用广泛。
        一般情况下,工控机和各智能仪表通过RS485总线进行通信。RS485的通信方式是半双工的,只能由作为主节点的工控PC机依次轮询网络.上的各智能控制单元子节点。每次通信都是由PC机通过串口向智能控制单元发布命令,智能控制单元在接收到正确的命令后作出应答。
        在Win32下,可以使用两种编程方式实现串口通信,其一是使用ActiveX控件,这种方法程序单,但欠灵活。其二是调用Windows的API函数,这种方法可以清楚地掌握串口通信的机制,并且自由灵活。本文我们只介绍API串口通信部分。
        接下来我们来实现一个串口调试助手!

ADO访问数据库
        ➢1、 安装串口虚拟软件
        ➢2、 打开串口
        ➢3、设置串口属性(波特率、奇偶校验等)
        ➢4、 读写串口
        ➢5、 校验(求和校验、CRC校验 )
        ➢6、 通信协议

建立工程

项目是在visual studio2005编译器内创建,点击“文件”->“新建”->“项目”

C++MFC 串口通信 上位机,stm32,单片机,嵌入式硬件

 按照图标提示选择,点击下一步。

C++MFC 串口通信 上位机,stm32,单片机,嵌入式硬件

 单击下一步,下一步,完成。

C++MFC 串口通信 上位机,stm32,单片机,嵌入式硬件

C++MFC 串口通信 上位机,stm32,单片机,嵌入式硬件

 点击完成后:

C++MFC 串口通信 上位机,stm32,单片机,嵌入式硬件

 接下来开始构建项目:

编辑如图所示的窗口:

C++MFC 串口通信 上位机,stm32,单片机,嵌入式硬件

 在WinDemoDlg.h中声明初始化函数

public:
	void InitComboBox();

 在WinDemoDlg.cpp中实现改函数:

void CWinDemoDlg::InitComboBox(){
	CComboBox* pComboComm=(CComboBox*)GetDlgItem(IDC_COMBO_COMM);
	ASSERT(pComboComm);
	for(int i=1;i<=8;i++){
		CString strComm;
		strComm.Format(_T("COM%d"),i);
		pComboComm->AddString(strComm);
	}
	pComboComm->SetCurSel(0);

	//波特率
	CComboBox* pComboBaudrate=(CComboBox*)GetDlgItem(IDC_COMBO_BAUDRATE);
	ASSERT(pComboBaudrate);
	pComboBaudrate->SetItemData(pComboBaudrate->AddString(_T("300")),300);
	pComboBaudrate->SetItemData(pComboBaudrate->AddString(_T("600")),600);
	pComboBaudrate->SetItemData(pComboBaudrate->AddString(_T("1200")),1200);
	pComboBaudrate->SetItemData(pComboBaudrate->AddString(_T("2400")),2400);
	pComboBaudrate->SetItemData(pComboBaudrate->AddString(_T("4800")),4800);
	pComboBaudrate->SetItemData(pComboBaudrate->AddString(_T("9600")),9600);
	pComboBaudrate->SetItemData(pComboBaudrate->AddString(_T("19200")),19200);
	pComboBaudrate->SetItemData(pComboBaudrate->AddString(_T("43000")),43000);
	pComboBaudrate->SetItemData(pComboBaudrate->AddString(_T("56000")),56000);
	pComboBaudrate->SetItemData(pComboBaudrate->AddString(_T("1152000")),1152000);
	pComboBaudrate->SetCurSel(5);
	
	//校验位
	CComboBox* pComboCheckBit=(CComboBox*)GetDlgItem(IDC_COMBO_CHECKBIT);
	ASSERT(pComboCheckBit);
	pComboCheckBit->SetItemData(pComboCheckBit->AddString(_T("无None")),NOPARITY);
	pComboCheckBit->SetItemData(pComboCheckBit->AddString(_T("奇ODD")),ODDPARITY);
	//pComboCheckBit->SetItemData(pComboCheckBit->AddString(_T("偶EUEN")),EUENPARITY);
	pComboCheckBit->SetCurSel(0);

	//数据位
	CComboBox* pComboDateBit=(CComboBox*)GetDlgItem(IDC_COMBO_DATABIT);
	ASSERT(pComboDateBit);
	pComboDateBit->SetItemData(pComboDateBit->AddString(_T("6")),6);
	pComboDateBit->SetItemData(pComboDateBit->AddString(_T("7")),7);
	pComboDateBit->SetItemData(pComboDateBit->AddString(_T("8")),8);
	pComboDateBit->SetCurSel(0);

	//停止位
	CComboBox* pComboStopBit=(CComboBox*)GetDlgItem(IDC_COMBO_STOPBIT);
	ASSERT(pComboStopBit);
	pComboStopBit->SetItemData(pComboStopBit->AddString(_T("1")),ONESTOPBIT);
	pComboStopBit->SetItemData(pComboStopBit->AddString(_T("2")),TWOSTOPBITS);
	pComboStopBit->SetCurSel(0);


}

 并将初始化函数放入OnInitDialog()函数中:

C++MFC 串口通信 上位机,stm32,单片机,嵌入式硬件

 添加一个串口类,这个串口类用来实现具体的串口通信:

        点击“项目”->“添加类”

C++MFC 串口通信 上位机,stm32,单片机,嵌入式硬件

         添加一般的C++类即可

C++MFC 串口通信 上位机,stm32,单片机,嵌入式硬件

         将类名设置为:CSerialPort

C++MFC 串口通信 上位机,stm32,单片机,嵌入式硬件

 其中CSerialPort.h代码如下:

#pragma once

class CSerialPort
{
public:
	CSerialPort(void);
public:
	~CSerialPort(void);
public:
	BOOL OpenComm(CString strComm);
	BOOL SetCommState(DWORD dwBaudrate,BYTE byParity,BYTE byByteSize,BYTE byStopBits);
	BOOL SetupComm(DWORD dwInQueue,DWORD dwOutQueue);
	BOOL PurgeComm(DWORD dwFlags);
	BOOL SetCommMask(DWORD dwEvtMask);
	BOOL WriteFile(IN LPCVOID lpBuffer,IN DWORD nNumberOfBytesToWrite,OUT LPDWORD lpNumberOfBytesWritten,IN LPOVERLAPPED lpOverlapped);
	BOOL ReadFile(OUT LPVOID lpBuffer,IN DWORD nNumberOfBytesToRead,OUT LPDWORD lpNumberOfBytesRead,IN LPOVERLAPPED lpOverlapped);
	BOOL ClearCommError(OUT LPDWORD lpErrors,OUT LPCOMSTAT lpStat);
	BOOL GetOverlappedResult(IN LPOVERLAPPED lpoverlapped,OUT LPDWORD lpNumberOfByterTransferred,IN BOOL bWait);
	void CloseComm();	//关闭窗口

public:
	HANDLE m_hComm;

};

CSerialPort.cpp代码如下:

#include "StdAfx.h"
#include "SerialPort.h"

CSerialPort::CSerialPort(void)
{
	m_hComm=NULL;
}

CSerialPort::~CSerialPort(void)
{
}
BOOL CSerialPort::OpenComm(CString strComm){
	if(NULL==m_hComm){
		m_hComm=CreateFile((TCHAR*)(LPCTSTR)strComm,GENERIC_READ | GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,0);
		if(INVALID_HANDLE_VALUE==m_hComm){
			int nError=GetLastError();
			m_hComm=NULL;
			return FALSE;
		}
		return TRUE;
	}
	return FALSE;

}
BOOL CSerialPort::SetCommState(DWORD dwBaudrate,BYTE byParity,BYTE byByteSize,BYTE byStopBits){
	if(NULL==m_hComm) return FALSE; 
	DCB dcb;
	BOOL bRet= ::GetCommState(m_hComm,&dcb);
	if(!bRet){
		if(m_hComm){

			//CloseHandle(m_hComm);
			m_hComm=NULL;
		}
		return FALSE;
	}
	dcb.BaudRate=dwBaudrate;
	dcb.ByteSize=byByteSize;
	dcb.Parity=byParity;
	dcb.StopBits=byStopBits;
	bRet=::SetCommState(m_hComm,&dcb);
	if(!bRet){
		if(m_hComm){

			CloseHandle(m_hComm);
			m_hComm=NULL;
		}
		return FALSE;
	}
	return TRUE;
}
BOOL CSerialPort::SetupComm(DWORD dwInQueue,DWORD dwOutQueue){
	if(NULL==m_hComm) return FALSE; 
	return ::SetupComm(m_hComm,dwInQueue,dwOutQueue);
}
BOOL CSerialPort::PurgeComm(DWORD dwFlags){
	if(NULL==m_hComm) return FALSE; 

	return ::PurgeComm(m_hComm,dwFlags);
}
BOOL CSerialPort::SetCommMask(DWORD dwEvtMask){
	if(NULL==m_hComm) return FALSE; 

	return ::SetCommMask(m_hComm,dwEvtMask);
}
BOOL CSerialPort::WriteFile(IN LPCVOID lpBuffer,IN DWORD nNumberOfBytesToWrite,OUT LPDWORD lpNumberOfBytesWritten,IN LPOVERLAPPED lpOverlappe)
{
	if(NULL==m_hComm) return FALSE; 

	return ::WriteFile(m_hComm,lpBuffer,nNumberOfBytesToWrite, lpNumberOfBytesWritten, lpOverlappe);
}
BOOL CSerialPort::ReadFile(OUT LPVOID lpBuffer,IN DWORD nNumberOfBytesToRead,OUT LPDWORD lpNumberOfBytesRead,IN LPOVERLAPPED lpOverlapped)
{
	if(NULL==m_hComm) return FALSE; 

	return ::ReadFile(m_hComm,lpBuffer,nNumberOfBytesToRead, lpNumberOfBytesRead, lpOverlapped);
}
BOOL CSerialPort::ClearCommError(OUT LPDWORD lpErrors,OUT LPCOMSTAT lpStat)
{
	if(NULL==m_hComm) return FALSE; 

	return ::ClearCommError(m_hComm,lpErrors,lpStat);
}
BOOL CSerialPort::GetOverlappedResult(IN LPOVERLAPPED lpoverlapped,OUT LPDWORD lpNumberOfByterTransferred,IN BOOL bWait)
{
	if(NULL==m_hComm) return FALSE; 

	return ::GetOverlappedResult(m_hComm,lpoverlapped,lpNumberOfByterTransferred,bWait);
}
//关闭窗口
void CSerialPort::CloseComm(){
	if(m_hComm){
		CloseHandle(m_hComm);
		m_hComm=NULL;
	}
}	

        这时就封装好了一个串口类,一旦串口开始工作的时候,需要一个线程,用这个线程来进行收发数据;线程运行时通过ReadFile()函数从串口中读出数据,如果有数据需要将数据放到接受框中显示出来。

        下面创建一个线程,一个串口对应一个线程对象,创建C++类,类名为:CThread。

C++MFC 串口通信 上位机,stm32,单片机,嵌入式硬件

 CThread.h代码:

#pragma once

class CThread
{
public:
	CThread(void);
public:
	~CThread(void);
public:
	void Start();
	void Stop();
public:
	virtual void SetThreadData(DWORD dwParam);
	virtual DWORD GetThreadData();

public:
	virtual void run();
public:
	static DWORD ThreadProc(LPVOID pParam);
public:
	HANDLE m_hThread;
	bool m_bExit;
	DWORD m_dwParam;

};

CThread.cpp代码:

#include "StdAfx.h"
#include "Thread.h"

CThread::CThread(void)
{

	m_bExit=FALSE;
	m_dwParam=0;
	m_hThread=NULL;
}

CThread::~CThread(void)
{
	if(!m_bExit){
		Stop();
	}
}
void CThread::Start()
{
	DWORD dwThreadID;	//获取的线程ID
	HANDLE hThread=::CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ThreadProc,this,0,&dwThreadID);
	ASSERT(hThread);
	m_hThread=hThread;
}
DWORD CThread::ThreadProc(LPVOID pParam)
{
	CThread* pThis=(CThread*)pParam;
	ASSERT(pThis);

	while(!pThis->m_bExit)
	{
		pThis->run();
	}
	return TRUE;
}
void CThread::Stop()
{
	if(m_hThread)
	{
		m_bExit=true;
		::WaitForSingleObject(m_hThread,INFINITE);
		::CloseHandle(m_hThread);
		m_hThread=NULL;
	}
}
void CThread::run()
{
	Sleep(100);
}
void CThread::SetThreadData(DWORD dwParam)
{
	if(m_dwParam!=dwParam)
	{
		m_dwParam=dwParam;
	}
}
DWORD CThread::GetThreadData()
{
	return m_dwParam;
}

接下来需要从这个线程派生出一个基类,创建C++类,类名为:CThreadComm; CThreadComm用来处理串口数据的收发线程。

C++MFC 串口通信 上位机,stm32,单片机,嵌入式硬件

CThreadComm.h代码:

CThreadComm.cpp代码:文章来源地址https://www.toymoban.com/news/detail-663961.html

到了这里,关于C++MFC 串口通信 上位机的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 通信工程毕设 基于Stm32的便携体测仪(心率 体温) - 单片机 嵌入式 物联网

    🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。 为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天

    2024年02月20日
    浏览(55)
  • 通信工程毕设 单片机自动写字机器人设计与实现 - 物联网 嵌入式 stm32

    🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。 为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天

    2024年01月15日
    浏览(67)
  • 通信工程毕设 Stm32 WIFI智能家居温湿度和烟雾检测系统 - 单片机 物联网 嵌入式

    🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。 为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天

    2024年02月02日
    浏览(61)
  • VC++6.0上实现PC机与单片机串口通信的PC端上位机软件

    我做这个的主要原因是选了一个PC和单片机的全双工串口通信作为课设题目,单片机端是用汇编语言编程且要预先下载到板子里,关于这个这里我就不多说,主要说说怎么实现PC端的上位机软件。 早知道要写软件,鬼才选这个课题 。但是自己选的路哭着也要走完。 做的时候我

    2024年02月05日
    浏览(38)
  • 【嵌入式知识08】STM32的USART串口通信,给上位机连续发送Hello Windows!

    本文主要介绍串口协议和RS-232、485标准,以及RS232、485电平与TTL电平的区别,了解\\\"USB/TTL转232\\\"模块的工作原理;并完成一个STM32的USART串口通讯程序。   串口通信(Serial Communication)的概念非常简单,串口按位(bit)发送和接收字节的通信方式。尽管比按字节(byte)的并行通信

    2024年02月13日
    浏览(47)
  • STM32毕设分享 - 基于单片机的智能鱼缸系统设计与实现 - 嵌入式 物联网 stm32 51单片机 智能鱼缸

    Hi,大家好,今天向大家介绍一个 单片机项目, 大家可用于 课程设计 或 毕业设计 基于单片机的智能鱼缸系统设计与实现 🔥 项目分享与指导: https://gitee.com/sinonfin/sharing 近年以来,随着我国综合实力飞速飙升,人们对物质和精神生活质量的要求也不断提升,各式各样的智能

    2024年04月11日
    浏览(58)
  • 单片机项目分享 stm32机器视觉的人脸识别系统 - 单片机 物联网 嵌入式

    🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。 为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天

    2024年01月22日
    浏览(81)
  • 【单片机毕设选题】stm32实现车牌识别系统 -物联网 嵌入式 单片机

    🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。 为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天

    2024年02月20日
    浏览(55)
  • 单片机项目分享 基于stm32的便携用电功率统计系统 -物联网 嵌入式 单片机

    🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。 为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天

    2024年02月19日
    浏览(110)
  • 单片机STM32看门狗详解(嵌入式学习)

    单片机STM32的看门狗(Watchdog)是一种硬件定时器,用于监控系统的运行状态并在出现故障或死锁时采取措施以恢复正常操作。看门狗的主要功能是定期检查系统是否正常运行,并在系统出现问题时触发复位操作。 STM32系列单片机通常配备了内置的看门狗定时器(通常称为独立

    2024年02月13日
    浏览(61)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包