文章目录
前言
通过CH343PT库我们可以获取使用芯片的功能信息,如芯片型号,芯片型号字符串,GPIO数量,是否内置EEPROM(可进行设备信息配置:可以配置VID,PID,供电方式,厂商字符串,产品字符串,Serial Number等信息。具体API使用可参考该篇文章:https://blog.csdn.net/WCH_TechGroup/article/details/127518991?spm=1001.2014.3001.5502,USB描述符内厂商字符串,产品字符串信息,SN号信息,串口序号和串口名等信息。
一、获取芯片功能信息结构体和函数接口介绍
1.1 芯片功能信息结构
typedef struct _USBSER_Property
{
UCHAR ChipType; //芯片型号,USER_TYPE_CHxxx
CHAR ChipTypeStr[32]; //芯片型号字符串
CHAR FwVerStr[32]; //固件版本字符串
UCHAR GpioCount; //GPIO脚数,如果大于0,此型号有专用GPIO脚或复用脚;为0表示芯片不支持GPIO引脚
BOOL IsEmbbedEeprom; //是否内置EEPROM,如支持,可进行设备信息的配置
BOOL IsSupportMcuBootCtrl; //是否支持Modem引脚作为103 MCU下载控制
CHAR ManufacturerString[64];//USB描述符内厂商字符串
CHAR ProductString[64]; //USB描述符内产品字符串
USHORT bcdDevice; //USB描述符内bcdDevice值
UCHAR PortIndex; //单串为0,如多串则为芯片第几个号串口
BOOL IsSupportGPIOInit; //是否支持GPIO上电初始化设置
CHAR PortName[32]; //串口号
ULONG ResvD[8]; //预留数据
}ChipPropertyS,*pChipPropertyS;
结构体参数信息如注释所示。
1.2 获取芯片功能信息函数
UCHAR WINAPI CH343PT_GetChipProperty(HANDLE iPortHandle, //串口句柄值
pChipPropertyS ChipProperty); //返回芯片GPIO、EEPROM等功能信息
传入芯片功能信息结构体,从而获取芯片功能信息。
二、函数接口的使用(软件实现)
下面编写一个demo去调用获取芯片功能信息函数,使用VC++6.0创建一个对话框去演示获取芯片的功能信息。
2.1 对话框界面
点击搜索WCH串口按钮去搜索串口,点击按钮输出芯片功能信息可输出芯片功能信息,点击清除芯片功能信息记录清除输出的芯片信息。
2.2 代码实现
代码如下:
//Main.cpp
#include "Main.h"
#include <winioctl.h>
#include <string>
//全局变量
HANDLE hCom; //串口句柄
//输出调试信息
VOID DbgPrint (LPCTSTR lpFormat,...)
{
CHAR TextBufferTmp[5120]="";
va_list arglist;
va_start(arglist, lpFormat);
vsprintf(&TextBufferTmp[strlen(TextBufferTmp)],lpFormat,arglist);
va_end(arglist);
strcat(TextBufferTmp,"\r\n");
SendDlgItemMessage(AfxWndHwnd,IDC_show,EM_SETSEL,0xFFFFFFFE,0xFFFFFFFE);
SendDlgItemMessage(AfxWndHwnd,IDC_show,EM_REPLACESEL,0,(LPARAM)TextBufferTmp);
SendDlgItemMessage(AfxWndHwnd,IDC_show,EM_SETSEL,0xFFFFFFFE,0xFFFFFFFE);
return ;
}
//获取串口友好名称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];
}
//MessageBox(AfxMainHwnd,ComName,"test",MB_OK);
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;
}
//获取芯片功能信息
VOID GetCH34XChipInfo()
{
UCHAR Retval;
ChipPropertyS CH34XChipInfo = {
0};
//打开串口
if(!OpenCom())
{
MessageBox(AfxMainHwnd,"打开串口失败!","GetCH34XChipInfo",MB_ICONWARNING);
return;
}
//获取芯片功能信息
Retval = CH343PT_GetChipProperty(hCom,&CH34XChipInfo);
if(Retval == 0xFF)
{
DbgPrint("未知型号");
return;
}
DbgPrint("芯片型号: %s",CH34XChipInfo.ChipTypeStr);
//判断串口是否为多串口
if(Retval == USER_TYPE_CH342F || Retval == USER_TYPE_CH342K ||
Retval == USER_TYPE_CH342G || Retval == USER_TYPE_CH342J ||
Retval == USER_TYPE_CH344L || Retval == USER_TYPE_CH344Q ||
Retval == USER_TYPE_CH348L || Retval == USER_TYPE_CH348Q ||
Retval == USER_TYPE_CH9103M)
DbgPrint("该芯片为多串口,打开的串口序号: %d",CH34XChipInfo.PortIndex);
else
DbgPrint("该芯片为单串口");
//判断芯片是否支持GPIO
if(CH34XChipInfo.GpioCount)
DbgPrint("支持%d个GPIO配置",CH34XChipInfo.GpioCount);
else
DbgPrint("不支持GPIO配置");
//判断芯片是否支持EEPROM配置
if(CH34XChipInfo.IsEmbbedEeprom)
DbgPrint("支持芯片信息EEPROM配置");
else
DbgPrint("不支持芯片信息EEPROM配置");
//关闭串口
CloseCom();
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;
//串口初始化
GetComFriendlyName();
srand( (unsigned)time( NULL ) );
{
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);
}
SendDlgItemMessage(hWnd,IDC_ShowMessage,EM_LIMITTEXT,0xFFFFFFFF,0);
}
break;
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
switch (wmId)
{
case IDC_PrintChipInfo:
GetCH34XChipInfo();
break;
case IDC_ClearEdit:
{
SetDlgItemText(hWnd, IDC_ShowMessage, "");
}
break;
case WM_DESTROY:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
}
return 0;
}
2.3 运行demo
(1)插入USB转单串口设备CH343P,获取芯片信息如下面界面所示:
从界面的输出信息可以看到CH343P不支持GPIO配置,支持芯片信息EEPROM配置。
(2)插入单串口设备CH9102X,获取芯片信息如界面所示:
从界面的输出信息可以看到CH9102X支持GPIO配置,不支持芯片信息EEPROM配置。
(3)插入单串口设备CH348L,获取芯片信息如界面所示:
从界面的输出信息可以看到CH348L是多串口设备,打开的是第1个串口(串口序号从0开始排序),支持GPIO配置,也支持芯片信息EEPROM配置。
总结
通过上面的demo,调用相应的接口函数在界面输出芯片的功能信息,如芯片型号,是否支持GPIO配置,是否支持芯片信息EEPROM配置等信息。通过获取到的芯片信息就可以清楚的了解芯片有哪些功能,从而可以进行芯片相应功能的开发。