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