CH343PT库使用<四> 搜索WCH串口


前言

下面介绍两种方法去搜索WCH串口通过调用CH343PT库接口来实现,第一种方法枚举串口(需打开串口)搜索到PC上插入的WCH串口。第二种搜索WCH串口方法,需要传入串口的端口号字符串参数就可以做到。


方法1:搜索WCH串口(需要打开串口)

使用的CH343PT库的函数接口:

BOOL	WINAPI CH343PT_HandleIsCH34x(  // 检查已经打开的端口是否为CH341端口
									 HANDLE		iPortHandle );  // 指定已经打开的端口句柄

代码实现:

//搜索WCH串口
VOID SerachWchUARTA()
{
	//打开串口
	if(!OpenCom())
	{
		MessageBox(NULL,"打开串口失败!","SearchWchUart",MB_ICONWARNING);
		return;
	}
	//方法1:判断是否为WCH串口
	if(CH343PT_HandleIsCH34x(hCom))
		SetDlgItemText(AfxMainHwnd,IDC_SerachResult, "当前选中的串口是WCH串口");
	else
		SetDlgItemText(AfxMainHwnd,IDC_SerachResult, "当前选中的串口不是WCH串口");
	//关闭串口
	CloseCom();
	return;
}

方法2:搜索WCH串口

代码实现:

//搜索WCH串口
VOID SerachWchUARTB()
{
	CHAR TempBuf[64] = {0};
	INT i,BegainSer,EndSer,Len;
	std::string strTemp,strComName;
	CHAR ComName[16] = "";
	CHAR tempBuf[256] = "";
	CHAR buf[256] = "";

	//提取设备友好名称中的COM号
	GetDlgItemText(AfxMainHwnd,IDC_Com,tempBuf,sizeof(tempBuf));
	Len =strlen(tempBuf);
	strTemp = tempBuf;
	BegainSer = strTemp.find('(');
	EndSer = strTemp.find(')');
	for(i=0; i<EndSer-BegainSer-1; i++)
	{
		ComName[i] = tempBuf[BegainSer+1+i];
	}
	strComName += "\\\\.\\";
	strComName += ComName;

	//方法2:判断是否为WCH串口
	if(CH343PT_NameIsCH34x((PUCHAR)strComName.c_str())) //传入端口号字符串,如:"\\\\.\\COMXX"
		SetDlgItemText(AfxMainHwnd,IDC_SerachResult, "当前选中的串口是WCH串口");
	else
		SetDlgItemText(AfxMainHwnd,IDC_SerachResult, "当前选中的串口不是WCH串口");
	return;
}

该方法需要传入COM端口号,且该端口必须未被占用(指未被其它程序打开)。

软件实现

使用VC++6.0创建一个对话框,如下图所示。
在这里插入图片描述

点击“搜索WCH串口(方法1)”按钮后输出结果,如下图所示:
在这里插入图片描述

在这里插入图片描述

点击“搜索WCH串口(方法2)”按钮后输出结果,如下图所示:
在这里插入图片描述
代码实现:

//Main.c
#include "Main.h"
#include <Windows.h>
#include <string>

//全局变量
HANDLE hCom; //串口句柄

//获取串口友好名称friendlyName
VOID GetComFriendlyName()
{
	INT     wImageIdx = 0;
	SHORT   wItem = 0;
	CHAR    szBuf[MAX_PATH] = { 0 };
	TCHAR   szComName[MAX_PATH] = { 0 };
	
	SendDlgItemMessage(AfxMainHwnd,IDC_Com,CB_RESETCONTENT,0,0); //清除组合框列表
	HDEVINFO hDevInfo = SetupDiGetClassDevs(NULL, NULL, NULL, DIGCF_PRESENT|DIGCF_ALLCLASSES); //构建系统存在的所有设备列表
	if (hDevInfo == INVALID_HANDLE_VALUE)
	{
		return;
	};
	 
	SP_DEVINFO_DATA SpDevInfoData = { 0 };
	SpDevInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
	for (DWORD i = 0; SetupDiEnumDeviceInfo(hDevInfo, i, &SpDevInfoData); i++)	
	{
			
		if (!SetupDiGetDeviceRegistryProperty(hDevInfo, &SpDevInfoData, SPDRP_CLASS, NULL, (PBYTE)szBuf, sizeof(szBuf), 0))
		{
			continue;
		}
		else
		{
			if (strcmp(szBuf, "Ports") != 0) //过滤端口,只取COM
			{
				continue;
			}
		}
		
		if (SetupDiGetDeviceRegistryProperty(hDevInfo, &SpDevInfoData, SPDRP_FRIENDLYNAME, NULL, (PBYTE)szComName, sizeof(szComName), 0))
		{
			ComCounts++;
			SendDlgItemMessage(AfxMainHwnd,IDC_AllCom,CB_ADDSTRING,0,(LPARAM)szComName); //向组合框中添加获取的设备友好名称
		}
	}
	SendDlgItemMessage(AfxMainHwnd,IDC_AllCom,CB_SETCURSEL,0,0); 
	if(hDevInfo)
		SetupDiDestroyDeviceInfoList(hDevInfo); //释放资源
}

//打开串口
BOOL OpenCom()
{
	CHAR TempBuf[64] = {0};
	INT i,BegainSer,EndSer,Len;
	std::string strTemp,strComName;
	CHAR ComName[16] = "";
	CHAR tempBuf[256] = "";
	CHAR buf[256] = "";

	//提取设备友好名称中的COM号
	GetDlgItemText(AfxMainHwnd,IDC_Com,tempBuf,sizeof(tempBuf));
	Len =strlen(tempBuf);
	strTemp = tempBuf;
	BegainSer = strTemp.find('(');
	EndSer = strTemp.find(')');
	for(i=0; i<EndSer-BegainSer-1; i++)
	{
		ComName[i] = tempBuf[BegainSer+1+i];
	}
	strComName += "\\\\.\\";
	strComName += ComName;
	
	hCom = CreateFile((LPCTSTR)strComName.c_str(),GENERIC_READ|GENERIC_WRITE,
			0,NULL,OPEN_EXISTING,
			NULL,
			NULL);
	if(hCom == INVALID_HANDLE_VALUE)
	{
		return FALSE;
	}
		return TRUE;
}

//关闭串口
BOOL CloseCom()
{
	if (INVALID_HANDLE_VALUE != hCom)
	{
		CloseHandle(hCom);
		hCom = INVALID_HANDLE_VALUE;		
	}
	return TRUE;
}

//方法1:判断是否为WCH串口
VOID SerachWchUARTA()
{
	//打开串口
	if(!OpenCom())
	{
		MessageBox(AfxMainHwnd,"打开串口失败!","SearchWchUart",MB_ICONWARNING);
		return;
	}
	//方法1:判断是否为WCH串口
	if(CH343PT_HandleIsCH34x(hCom))
		SetDlgItemText(AfxMainHwnd,IDC_SerachResult, "当前选中的串口是WCH串口");
	else
		SetDlgItemText(AfxMainHwnd,IDC_SerachResult, "当前选中的串口不是WCH串口");
	//关闭串口
	CloseCom();
	return;
}

//方法2:判断是否为WCH串口
VOID SerachWchUARTB()
{
	CHAR TempBuf[64] = {0};
	INT i,BegainSer,EndSer,Len;
	std::string strTemp,strComName;
	CHAR ComName[16] = "";
	CHAR tempBuf[256] = "";
	CHAR buf[256] = "";

	//提取设备友好名称中的COM号
	GetDlgItemText(AfxMainHwnd,IDC_Com,tempBuf,sizeof(tempBuf));
	Len =strlen(tempBuf);
	strTemp = tempBuf;
	BegainSer = strTemp.find('(');
	EndSer = strTemp.find(')');
	for(i=0; i<EndSer-BegainSer-1; i++)
	{
		ComName[i] = tempBuf[BegainSer+1+i];
	}
	strComName += "\\\\.\\";
	strComName += ComName;

	//方法2:判断是否为WCH串口
    if(CH343PT_NameIsCH34x((PUCHAR)strComName.c_str()))
		SetDlgItemText(AfxMainHwnd,IDC_SerachResult, "当前选中的串口是WCH串口");
	else
		SetDlgItemText(AfxMainHwnd,IDC_SerachResult, "当前选中的串口不是WCH串口");
	return;
}

//应用程序入口
int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
{
	return 	DialogBox(hInstance, (LPCTSTR)IDD_MainWnd, 0, (DLGPROC)WndProc);
}

//主窗体进程
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	int wmId, wmEvent;

	switch (message)
	{

	case WM_INITDIALOG:
		{
			AfxMainHwnd = hWnd;
			HICON hicon;
			hicon = (HICON)LoadIcon(AfxMainIns,(LPCTSTR)IDI_Main);
			PostMessage(AfxMainHwnd,WM_SETICON,ICON_BIG,(LPARAM)(HICON)hicon);
			PostMessage(AfxMainHwnd,WM_SETICON,ICON_SMALL,(LPARAM)(HICON)hicon);	
			//串口初始化
			GetComFriendlyName();
		}
		break;
	case WM_COMMAND:
		wmId    = LOWORD(wParam); 
		wmEvent = HIWORD(wParam); 
		switch (wmId)
		{
		
		case IDC_SearchWchUartA:
			SerachWchUARTA();
			break;
		case IDC_SearchWchUartB:
			SerachWchUARTB();
			break;		
	case WM_DESTROY:
			DestroyWindow(hWnd);
			break;
		default:
			return DefWindowProc(hWnd, message, wParam, lParam);
		}
		break;	
		case WM_DESTROY:
			PostQuitMessage(0);
			break;		
	}
	return 0;
}

总结

可以通过上述两种方法来确定所选的串口是否为WCH串口,前提要安装VCP驱动才可以使用,使用上述两种方法可以过滤WCH串口,从而方便串口的后续操作。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值