“USB状态与信息检测”上位机设计方法

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/snaking616/article/details/83378569

1. 使用MFC新建USB上位机工程

    USB芯片型号为:CYC7C68013A,上位机的开发环境为Visual Studio 2008,工程文件由MFC向导生成,具体步骤如下:

(1)打开VS2008,依次单击 文件 -> 新建 -> 项目,菜单中项目类型一栏选择“MFC”,右侧模板选择“MFC应用程序”。在菜单栏下方,名称填入“USBdetect”,位置选择“C:\project”,最后点击确定!

(2)在MFC应用程序向导菜单中,左侧概述选择应用程序类型,右侧应用程序类型选择“基于对话框(D)”,其它选项默认,点击下一步。

(3)连续单击“下一步”,直到点击完成!

使用MFC向导得到的USB上位机工程模板如下

其中:

区域1:工程需要包含的头文件;

区域2:工程的主程序文件;

区域3:工程的资源文件链接;

区域4:程序调试窗口;

区域5:上位机的运行界面;

区域6:对话框编辑器窗口。

 

2. 添加相关头文件与库文件

(1)文件的获取

    在电脑上安装Cypress Suite USB 3.4.7应用程序后,可在路径“C:\Cypress\Cypress Suite USB 3.4.7\CyAPI\inc”和“C:\Cypress\Cypress Suite USB 3.4.7\CyAPI\lib”下,分别得到所需的

USB头文件:CyAPI.h、cyioctl.h、usb100.h、usb200.h与库文件:CyAPI.lib,

(注意:不同平台的库文件不一样,64位系统选择x64文件夹下的库文件)

(2)在工程文件中添加Cypress公司的头文件和库文件

    首先,将文件CyAPI.h、cyioctl.h、usb100.h、usb200.h和CyAPI.lib拷贝至“C:\project\USBdetect\USBdetect”目录下;

接着,打开程序USBdetectDlg.cpp,在头部添加以下代码:

    #include "CyAPI.h"

    #include "cyioctl.h"

    #include <dbt.h>

    打开头文件USBdetectDlg.h,在头部添加以下代码:

    #include "CyAPI.h"

    #include <afxmt.h>

    在网上下载devioctl.h头文件,放在工程路径下,打开cyioctl.h修改第24行代码为 #include "devioctl.h"!

(devioctl.h头文件下载地址:http://www.newxing.com/Code/VC/other/4393.html

   最后,给工程添加库文件CyAPI.lib,在工程USBdetect上右击并点击属性,依次单击左侧选项中的 配置属性->链接器->输入,在右侧的附加依赖项中填入CyAPI.lib,至此工程的头文件与库文件添加完毕!

 

3. 上位机界面设计

(1)删除控件“IDC_STATIC1 (Text Control)”,添加控件Group Box,并调整box边框大小和名称,名称由静态改为“USB状态与信息”;

(2)添加4个“Static Text”控件,并将它们的ID修改为IDC_TEXTA、IDC_TEXTB、IDC_TEXTC、IDC_TEXTD;

上位机界面如下,4个静态文本控件的含义分别是:

IDC_TEXTA:用于显示USB状态,断开或者连接!

IDC_TEXTB:显示VendorID

IDC_TEXTC:显示ProductID

IDC_TEXTD:显示设备信息

 

4. 上位机检测程序设计

打开头文件“USBdetectDlg.h”,在public:声明下填写:        

    CCyUSBDevice *USBDevice;
    CWinThread *ReadThread; //Thread
    //CCyUSBEndPoint *InEndpt; //USB endpoint
    BOOL ReadThreadLooping; //线程循环标志
    CCyUSBEndPoint* pInEndpt;
    CCyUSBEndPoint* pOutEndpt;
    CSemaphore m_Semaphore;
    bool bPnP_Arrival;
    bool bPnP_DevNodeChange;
    bool bPnP_Removal;
    CWinThread *pXferInThread;
    CWinThread *pXferOutThread;
    bool m_bXfer;

    void DisplayDevices(void);
    afx_msg void OnDestroy();
    void EndOutThread(int nThreadID);
    void TestRate(double mb, unsigned long nSuc, unsigned long nErr);

在USBdetectDlg.cpp的初始化函数OnInitDialog()的“// TODO: 在此添加额外的初始化代码声明下填写:

    ReadThread=NULL;                           //线程禁止
    USBDevice = new CCyUSBDevice(m_hWnd);    //USB设备
    SetDlgItemText(IDC_TEXTA,_T("USB状态: 断开!"));
    SetDlgItemText(IDC_TEXTB,_T("VendorID=NULL"));
    SetDlgItemText(IDC_TEXTC,_T("ProductID=NULL"));
    SetDlgItemText(IDC_TEXTD,_T("设备:NULL"));

另外,添加两个新的成员函数DisplayDevices(void)和WindowProc(UINT message, WPARAM wParam, LPARAM lParam),前者用于更新上位机界面,后者用于实现USB热拔插功能!

void CUSBdetectDlg::DisplayDevices(void)
{
	CString strA = _T("USB状态:  断开!");
	CString strB = _T("VendorID=NULL");
	CString strC = _T("ProductID=NULL");
	CString strD = _T("设备:NULL");
	
	UCHAR nCount,n;
	int vID,pID;
	Sleep(10);
	m_Semaphore.Lock();
	nCount=USBDevice->DeviceCount();

    for(n=0;n < nCount;n++)
	{
		if(USBDevice->Open(n))
		{
			strD = USBDevice->DeviceName;
			if(strD==_T("YJ-Development Kit C402"))
			{
				strA = _T("USB状态:  已连接!");

				vID=USBDevice->VendorID;		//读取VID
				pID=USBDevice->ProductID;		//读取PID
				strB.Format(_T("VendorID=0x%x"),vID);
				//SetDlgItemText(IDC_TEXT1,str2);
				strC.Format(_T("ProductID=0x%x"),pID);
				//SetDlgItemText(IDC_TEXT2,str3);

				strD = _T("设备: ");
				strD+=USBDevice->DeviceName;
				pInEndpt  = USBDevice->EndPointOf(0x86);
				pOutEndpt = USBDevice->EndPointOf(0x02);
				
				if(!pInEndpt || !pOutEndpt) strD +=  _T("错误!    设备端点不可用");
				break;
			}			
		}
		pInEndpt  = NULL;
		pOutEndpt = NULL;
	}
	m_Semaphore.Unlock();
	//SetWindowText(str);
	SetDlgItemText(IDC_TEXTA,strA);
	SetDlgItemText(IDC_TEXTB,strB);
	SetDlgItemText(IDC_TEXTC,strC);
	SetDlgItemText(IDC_TEXTD,strD);
}
LRESULT CUSBdetectDlg::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
	if (message == WM_DEVICECHANGE) 
	{
		// Tracks DBT_DEVICEARRIVAL followed by DBT_DEVNODES_CHANGED
		if (wParam == DBT_DEVICEARRIVAL)
		{
			bPnP_Arrival = true;
			bPnP_DevNodeChange = false;
		}
		// Tracks DBT_DEVNODES_CHANGED followed by DBT_DEVICEREMOVECOMPLETE
		if (wParam == DBT_DEVNODES_CHANGED) 
		{
			bPnP_DevNodeChange = true;
			bPnP_Removal = false;
		}
		if (wParam == DBT_DEVICEREMOVECOMPLETE) 
		{
			bPnP_Removal = true;
			PDEV_BROADCAST_HDR bcastHdr = (PDEV_BROADCAST_HDR) lParam;
			if (bcastHdr->dbch_devicetype == DBT_DEVTYP_HANDLE) 
			{
				PDEV_BROADCAST_HANDLE pDev = (PDEV_BROADCAST_HANDLE) lParam;
				if (pDev->dbch_handle == USBDevice->DeviceHandle())
					USBDevice->Close();
				DisplayDevices();
			}
		}
		// If DBT_DEVNODES_CHANGED followed by DBT_DEVICEREMOVECOMPLETE
		if (bPnP_Removal && bPnP_DevNodeChange) 
		{
		//	Sleep(10);
		//	DisplayDevices();
			bPnP_Removal = false;
			bPnP_DevNodeChange = false;
		}
		// If DBT_DEVICEARRIVAL followed by DBT_DEVNODES_CHANGED
		if (bPnP_DevNodeChange && bPnP_Arrival) 
		{
			DisplayDevices();
			bPnP_Arrival = false;
			bPnP_DevNodeChange = false;
		}
	}

	return CDialog::WindowProc(message, wParam, lParam);
}

 

5. 上位机测试

    双击路径“C:\project\USBdetect\Debug”下USBdetect.exe,当电脑没有连接Cypress USB设备时,上位机显示界面如下:

插入Cypress USB设备,上位机界面显示USB设备已连接,VendorID=0x4b4,ProductID=0x1004,设备名称为

YJ-Development Kit C402,当USB线断开或者USB设备断电时,上位机的界面会返回至上面的状态。

 

6. 参考资料

(1)MFC编程入门之十(对话框:设置对话框控件的Tab顺序) - 木缥缈 - 博客园

https://www.cnblogs.com/mupiaomiao/p/6203234.html

(2)Cyapi使用心得 - shengzhuzhu的专栏 - CSDN博客

https://blog.csdn.net/shengzhuzhu/article/details/34894187

(3)基于Cy68013的USB设备在VC程序中热插拔的实现 | 学步园

https://www.xuebuyuan.com/1488224.html

(4)error C4430: 缺少类型说明符 - 一梦一程-记录学习点滴-51CTO博客

http://blog.51cto.com/jincheng/850069

(5)理解Semaphore及其用法详解 - flyingdon的专栏 - CSDN博客

https://blog.csdn.net/flyingdon/article/details/5110582?utm_source=blogxgwz4

7. 工程文件下载地址

USB状态与信息检测上位机MFC工程-CSDN下载
https://download.csdn.net/download/snaking616/10743784

 

猜你喜欢

转载自blog.csdn.net/snaking616/article/details/83378569