C++ USB上位机开发
周立功USBCAN-II上位机开发(MFC)

周⽴功USBCAN-II上位机开发(MFC)使⽤的USB转CAN的设备是周⽴功的USBCAN-II,在购买的时候,会有上位机⼆次开发的库⽂件、例程和API⽂档等材料,可以参考。
1、库函数的调⽤⾸先,把库函数⽂件都放在⼯作⽬录下。
库函数⽂件总共有三个⽂件:ControlCAN.h、ControlCAN.lib、ControlCAN.dll和⼀个⽂件夹kerneldlls。
VC调⽤动态库的⽅法(1) 在扩展名为.CPP的⽂件中包含ControlCAN.h头⽂件。
如:#include “ControlCAN.h”(2) 在⼯程的连接器设置中连接到ControlCAN.lib⽂件。
如:在VC7环境下,在项⽬属性页⾥的配置属性→连接器→输⼊→附加依赖项中添加ControlCAN.lib中间换了⼀台电脑,出现电脑丢失ControlCAN.dll的问题,将ControlCAN.dll拷到了可执⾏⽂件的⽂件夹中即可2、基本操作2.1 连接设备我这⾥每次连接都会重新开启接收数据的线程,创建⼀次接收数据的txt⽂档void CTest_OilDlg::OnBnClickedButtonConnect(){//⾸先判断CAN是否打开,,如果已经打开,则先复位及重启CAN--1.8//关闭程序前必须点击断开连接按钮,否则报错if(m_connect == 1){m_connect = 0;//isShow = 0;Sleep(500);GetDlgItem(IDC_BUTTON_CONNECT)->SetWindowTextW(_T("连接"));VCI_CloseDevice(m_deviceType,m_deviceIndex);showListInfo(_T("断开设备成功"));//结束⾃发⾃收测试的定时器KillTimer(0);//结束当前线程if(m_pThread != NULL){//::WaitForSingleObject(m_pThread->m_hThread,INFINITE);//该函数会造成死锁//https:///silvervi/article/details/5874212 将上⾯函数修改成如下,以避免上⾯函数阻塞对话框主线程的消息队列DWORD dwRet = 0;MSG msg;while(true){//等待处理数据线程结束,和等待消息队列中的任何消息dwRet = MsgWaitForMultipleObjects(1,&m_pThread->m_hThread,false,INFINITE,QS_ALLINPUT);//dwRet = WaitForSingleObject(m_pThread->m_hThread,50);switch (dwRet){case WAIT_OBJECT_0:break;case WAIT_OBJECT_0 + 1://get the message from Queue and dispatch it to specific windowPeekMessage(&msg,NULL,0,0,PM_REMOVE);DispatchMessage(&msg);continue;default:break;}break;}//CloseHandle(m_pThread->m_hThread);delete m_pThread;m_pThread = NULL;//不太懂}//关闭存储数据的⽂件for(int i = 0;i < 4;i++){//判断⽂件是否打开,若打开了关闭if(m_waveDataFile[i].m_hFile != CFile::hFileNull){m_waveDataFile[i].Close();}}GetDlgItem(IDC_BUTTON_START)->SetWindowTextW(_T("开始⼯作"));return;}//------------打开设置---------------------////设备类型m_deviceType = VCI_USBCAN2;//设备索引号,只有⼀个设备,索引号为0m_deviceIndex = 0;//第0路CAN--只有⼀路,⽤户选择CString canNum;m_selectCANNum.GetWindowTextW(canNum);m_canNumA = _ttoi(canNum);if(VCI_OpenDevice(m_deviceType,m_deviceIndex,0) != STATUS_OK)//m_deviceType:设备类型号;m_deviceIndex:设备索引号;最后⼀个是保留参数,⼀般为0 {MessageBox(_T("打开设备失败!",_T("警告"),MB_OK|MB_ICONQUESTION));showListInfo(_T("打开设备失败"));SetHScroll();return ;}else{showListInfo(_T("打开设备成功"));SetHScroll();}///-------------对CAN进⾏初始化------------------////对CAN进⾏初始化VCI_INIT_CONFIG init_config;init_config.AccCode = 0x00000000;init_config.AccMask = 0xffffffff;//表⽰全部接收,(全部接收,AccMask:0xffffffff;AccCode:0x00000000---这块可以通过测试软件中的滤波设置功能中计算)init_config.Mode = 0;//正常模式;1:表⽰只听模式(只接收,不影响总线)init_config.Timing0 = 0x00;init_config.Timing1 = 0x14;//相当于波特率1000kbpsif(VCI_InitCAN(m_deviceType,m_deviceIndex,m_canNumA,&init_config) != STATUS_OK){MessageBox(_T("初始化CAN失败!"),_T("警告"),MB_OK|MB_ICONQUESTION);VCI_CloseDevice(m_deviceType,m_deviceIndex);showListInfo(_T("初始化CAN失败"));SetHScroll();return ;}else{showListInfo(_T("初始化CAN成功"));SetHScroll();}m_connect = 1;GetDlgItem(IDC_BUTTON_CONNECT)->SetWindowTextW(_T("断开"));//创建存储数据的⽂件CTime time0 = CTime::GetCurrentTime();CString fileName = _T("WaveData");if(!PathIsDirectory(fileName)){::CreateDirectory(fileName,NULL);}fileName.Format(_T("WaveData/%d-%d %dh%dm%ds"),time0.GetMonth(),time0.GetDay(),time0.GetHour(),time0.GetMinute(),time0.GetSecond());if(!PathIsDirectory(fileName)){::CreateDirectory(fileName,NULL);}CString fileName0 = fileName;for(int i = 0;i < 4;i++){CString i0;i0.Format(_T("/%dth"),i+1);fileName = fileName0 + i0;fileName += _T(".txt");m_waveDataFile[i].Open(fileName,CFile::modeWrite|CFile::modeCreate|CFile::modeNoTruncate);//若⽂件存在,则清空}//开启接收数据的线程m_pThread = AfxBeginThread(ReceiveThread,this,0,CREATE_SUSPENDED,NULL);m_pThread->m_bAutoDelete = false;}2.2 接收数据UINT CTest_OilDlg::ReceiveThread(void *param){CTest_OilDlg *dlg = (CTest_OilDlg*)param;VCI_CAN_OBJ frameInfo[5000];//⼀次性从缓冲区获取50个帧VCI_ERR_INFO errInfo;int len = 1;//获取到的CAN帧的个数int i = 0;CString str,tmpstr;while(1){Sleep(1);if(dlg->m_connect == 0){break;}//获取缓冲区的长度int lenBuf = VCI_GetReceiveNum(dlg->m_deviceType,dlg->m_deviceIndex,dlg->m_canNumA);//获取到的数据的个数,如果缓冲区⼤于5000,则取出5000,否则将缓冲区全部取出len = VCI_Receive(dlg->m_deviceType,dlg->m_deviceIndex,dlg->m_canNumA,frameInfo,5000,400);//每次从缓冲区获取50帧,等待200ms⽆响应后结束if(len <= 0){//注意:如果没有读到数据则必须调⽤此函数来读取出当前的错误码//千万不能省略这⼀步(即使你可能不想知道错误码是什么)DWORD error = VCI_ReadErrInfo(dlg->m_deviceType,dlg->m_deviceIndex,dlg->m_canNumA,&errInfo);//返回值为1 表⽰操作成功if((errInfo.ErrCode & 0x0000) == 0x0000){//表⽰错误码是0x0000}}else{for(i = 0;i < len;i++){str = _T("数据:\n");if(frameInfo[i].DataLen > 8)frameInfo[i].DataLen = 8;//原始数据----但是这⾥没有保存for(int j = 0; j < frameInfo[i].DataLen;j++){tmpstr.Format(_T("%04x \n"),frameInfo[i].Data[j]);str += tmpstr;}::SendMessage(dlg->GetSafeHwnd(),WM_WAVEFORM,WPARAM(&frameInfo[i]),NULL);//TRACE(_T("receive\n"));}}}return0;}这⾥的数据处理是通过发送⾃定义消息的⽅法实现的,因为这些数据同时也要画成曲线显⽰在界⾯上,需要对界⾯进⾏更新操作,这时候需要给界⾯的主线程发消息去实现界⾯更新2.3 发送数据void CTest_OilDlg::OnBnClickedButtonSend(){//-----------------发送井下仪器⼯作模式命令-------------------//if(m_connect == 0)return ;VCI_CAN_OBJ frameInfo;//设置发送重发超时时间,建议不⼩于1500ms,默认4000msVCI_SetReference(m_deviceType,m_deviceIndex,m_canNumA,4,&m_sendTimeout);frameInfo.ID = 0x84444444;//需要再确定frameInfo.SendType = 0;//正常发送frameInfo.RemoteFlag = 0;//数据帧frameInfo.ExternFlag = 1;//扩展帧frameInfo.DataLen = 3;//⼀个字节frameInfo.Data[0] = 0x04;frameInfo.Data[1] = 0xff;//01仪器待机;02:仪器⾃检;03:仪器定时开关机;04:仪器测试;05:仪器连续⼯作frameInfo.Data[2] = m_selectMode.GetCurSel() + 1;int ret = VCI_Transmit(m_deviceType,m_deviceIndex,m_canNumA,&frameInfo,1);if(ret == 1){showListInfo(_T("命令发送成功"));SetHScroll();}else{showListInfo(_T("命令发送失败"));SetHScroll();}}View Code3、问题做到现在,程序⾃发⾃收可以,接收下位机数据能接受5个左右的循环就接不到了,后来把数据的操作都屏蔽掉,只接收,发现也接不到,缓冲区内的数据个数为0.这个问题还没解决。
基于C#的USB3.0接口程序设计

基于C#的USB3.0接口程序设计作者:樊高有王勇杨振国来源:《软件导刊》2016年第11期摘要:USB3.0接口速度快、简单、占用资源少,在实际设计工作中应用广泛。
设计一种基于USB3.0接口的上位机软件,在C#.NET平台下实现USB3.0设备的读写、数据接收和发送、数据传输动态显示以及数据存储。
实验结果表明,采用该程序可以提高程序开发效率,各方面功能都能得到很好的实现。
关键词关键词:C#;USB3.0;上位机;数据传输DOIDOI:10.11907/rjdk.162031中图分类号:TP319文献标识码:A 文章编号文章编号:16727800(2016)0110111030 引言USB(Universal Serial Bus)是一种新型的计算机总线接口技术。
目前,在电子消费产品以及智能测控等领域应用越来越广泛,在设计工作中也被越来越多采用。
新的USB3.0总线技术提供了5.0Gb/s的传输速率,并向下兼容低速1.5Mb/s、全速12Mb/s和高速480Mb/s传输速率。
Cypress公司提供的Cypress Suite USB开发包包含.NET平台的动态链接库CyUSB.dll[1]。
本文探讨如何在Windows平台的.NET开发环境中,采用C#开发了USB3.0对接的上位机软件设备。
1 软件总体设计(1)从程序架构角度考虑,数据传输功能、显示功能以及数据存储功能分为独立的3个部分,分别由相应的类实现。
(2)使用事件传递内容,减小数据传输部分、显示部分以及数据存储部分的耦合度。
(3)程序功能相对复杂,分步实现:先完成USB设备检测,实现设备连接功能;然后传输数据,数据接收,实现数据存储功能;最后实现界面数据实时更新[2]。
上位机窗体界面主要有3个部分组成,即设置、运行状态以及接收与发送数据缓冲区,如图1所示。
程序总体工作流程如图2所示。
2 程序功能实现2.1 设备自动检测当USB设备连接到计算机时,能够自动获取USB设备列表、传输端点;当USB设备被移除后,能够自动识别USB设备已被断开,重新设置和获取USB设备。
USB开发基础:USB设备的开发流程

USB开发基础:USB设备的开发流程
USB设备的开发一般包括主机端(上位机)驱动程序的开发(如果您的USB设备符合某一标准设备类且主机端已经提供了此类设备的驱动程序的话,则可以省掉此步骤)和USB设备端驱动程序的开发,有时还可能包括主机端
应用程序的设计工作。
1、设备系统需求分析
设备系统需求分析是进行USB设备设计的第一步,通过对USB设备功能特性和USB主机端操作系统的分析,可以获得实现该USB设备的软硬件设计需求。
在该阶段,设计者需要充分了解该设备的应用环境(如USB主机的软件、
硬件平台),这样以用来确定是否需要提供USB主机端相关软件工作,以便该设备能得到广泛地应用。
为了提供合理的软硬件设计方案,设计者还需要充分了解市场上的USB接口芯片,不同的USB接口芯片在USB协议上有着不同程度的支持,比如,对数据包地址的硬件自动识别、CRC16和CRC5的自动生成等等。
当然,在确定具体的软硬件需求时,产品的开发费用和开发周期也是必须考虑的因素。
2、设备硬件需求
通过设备系统需求分析,以及对市场上USB接口芯片的充分了解,设计者
必须确定相应的设备硬件结构以及可能采用的硬件。
在选择器件时,需要考虑到器件体积、功耗等,因为,小的设备功耗,有利于采用总线供电模式。
必须通过设备系统的功耗来确定是否需要提供本地电源。
3、设备软件需求
在确定了设备的硬件结构以后,该设备的软件结构就会同时产生。
不同的硬。
上位机编程实现与USB—HID设备通信

上位机编程实现与USB—HID设备通信【摘要】在上位机中,通过人机交互界面,利用Windows提供的API函数,实现应用程序对HID设备的访问。
指出调用API函数的过程和方法,并提供了实现方法的具体实例。
【关键词】上位机;USB_HID;Visual C++;人机接口设备1.引言USB全称为Universal Serial Bus(通用串行总线),是一种快速、灵活的总线接口。
在USB出现之前,计算机接口在传输速度方面都存在速度偏低,容易产生I/O冲突,中断不够用等缺点。
人机接口设备(HID)主要是指一些人与计算机进行交互的设备,如键盘、鼠标、游戏杆等;但是HID设备不一定非要是这些人机交互设备,只要符合HID 设备定义规范要求的都可以认为是HID设备。
HID设备有以下主要特点:(1)交换的数据存储在报告的结构内,设备必须支持HID报告格式。
(2)每笔事务可以携带小量或中量的数据。
低速设备每笔事务最大为8字节,全速设备每笔最大为64字节,高速设备最大为1024字节;(3)有最大传输速度的限制。
低速设备最快10ms一笔事务,最高速度为800B/s;全速设备最快1ms一笔事务,最高速度为64KB/s;高速设备最快125μs 一笔事务,最高速度为24.576MB/s。
如何在应用程序中对HID类设备进行访问呢?在Windows环境下,不允许用户在应用程序中直接访问硬件设备,应用程序必须通过一个中间桥梁才能访问硬件设备,这个中间桥梁就是设备驱动程序。
从Windows98操作系统开始,为HID类设备提供了通用的驱动程序,所以只要按照HID设备类的规范编写设备的固件程序,就能够让Windows系统自动识别设备,省去了复杂的驱动程序编写过程。
2.Visual C++介绍应用基于MFC AppWizard的应用程序。
MFC(Microsoft Foundation Class Library)中的各种类结合起来构成了一个应用程序框架,它的目的就是在此基础上来建立Windows下的应用程序,这是一种相对SDK来说更为简单的方法。
零基础5分钟开发一个简单的MdbusTCP(RTU)主站上位机教程

如何在Windows平台上面快速搭建一个Modbus主站上位机demo现如今,Modbus协议可以说是工业控制,现场数据采集邻域各种控制设备与传感器应用最为广泛的数据交互协议,不管是简单方便的串口,还是高速稳定的以太网,Modbus协议都有相应的适配其传输特点的协议。
虽然目前主流的Modbus 人机交互主站是组态王或者各种工控厂家生产的触摸屏,但如果你想做一些带逻辑控制,或者界面比较自由的上位机,那么该文章将在Visual Studio集成开发环境下,使用C#语言和Visual Studio的Winform框架,从环境安装,创建工程,Modbus库的安装,代码编写,程序调试等几个步骤,带你快速开发出一个Window 平台环境下的Modbus主站上位机demo。
(该文档以Visual Studio 2017为例)一、搭建开发环境在“工作负荷”菜单处勾选“.NET桌面开发”(已省略安装具体步骤)与你需要的其他组件。
安装完成后,我们进入下一步。
二、创建工程1、打开Visual Studio依次点击“文件”->“新建”->“项目”2、创建Visual C#的Windows窗体应用,按如下步骤创建Windows窗体应用,下面第四步我们可以自定义工程名称,这里我将该工程命名成“ModbusMaster”,完成后点击“确定。
三、Modbus库的安装工程创建完成后,中间红色部分窗体就是我们该工程默认生成的界面,默认程序运行起来后会加载该界面,但我们先不管界面,我们先为工程安装Easy ModbusTcp库。
EasyModbusTCP是基于.NET Framework和Java平台上的Modbus TCP/UDP/RTU通讯协议库。
它主要用于工业自动化领域,帮助用户实现远程控制和数据采集。
EasyModbusTCP的特点如下:简单易用:EasyModbusTCP提供了简单易用的API,使得用户可以轻松地实现与Modbus设备的通信。
论文--基于Labview的USB接口上位机设计

基于LabVIEW的USB接口上位机设计摘要:通用串行总线(USB)作为一种灵活的高速总线接口技术,非常适合作为主机和外设之问的通信接口,但其结构复杂。
本文以一个高速数据采集系统为例,阐述USB接口应用系统的总体设计思路,在实现方法上避开传统、复杂的NI数据采集卡,另辟蹊径地给出使用NI-VISA来驱动USB接口以应用LabVIEW进行上位机的设计。
关键词:USB RAW设备;NI-VISA;LabVIEW一、数据传输USB模块1.1概述CH375是一个 USB总线的通用接口芯片,支持USB-HOST 主机方式和 USB-DEVICE/SLAVE 设备方式。
在本地端,CH375 具有 8位数据总线和读、写、片选控制线以及中断输出,可以方便地挂接到单片机/DSP/MCU/MPU 等控制器的系统总线上。
在USB 主机方式下,CH375还提供了串行通讯方式,通过串行输入、串行输出和中断输出与单片机/DSP/MCU/MPU 等相连接。
CH375 的 USB 设备方式与 CH372 芯片完全兼容,CH375 包含了 CH372 的全部功能。
本手册中没有提供CH375在USB设备方式下的说明,相关资料可以参考 CH372 手册CH372DS1.PDF。
CH375的 USB主机方式支持常用的USB全速备,外部单片机可以通过CH375按照相应的 USB 协议与 USB 设备通讯。
CH375 还内置了处理 Mass-Storage 海量存储设备的专用通讯协议的固件,外部单片机可以直接以扇区为基本单位读写常用的USB 存储设备。
1.2 USB硬件电路图其中USB设备采用5V供电,其他采用3.3V供电,DE0板子上I/O口处有5V和3.3V,因此直接用DE0板子上供电。
二、LabVIEW的上位机2.1 数据采集概述高速的数据采集产品多通过PCI或PXI等总线实现与PC机之间的通信。
PCI总线的数据采集卡易受PC机机箱内高频干扰的影响,无法消除高频电磁干扰,从而降低了采样精度。
串口USB接口的上位机软件设计

II
重庆大学本科学生毕业设计(论文)
目录
目录
摘
要 .................................................................................................................................... I
2.3.2 USB2.0 接口特点 .................................................................................................... 7
2.4 方案的选取 ....................................................................................................................... 8
This paper is based on Visual Studio 2010 platform, on c # language for the upper machine software developing design; and it is based on Keil2 for the firmware design of CY7C68013A chip, which achieves the configuration of USB chip and upper machine for communications; and Based on Visual Studio C++6.0 and DriverStudio , which helps to design out the USB driver for CY7C68013A. Thereby they make host computer and lower machine communicate successfully.
我在做usb上位机驱动过程中做的笔记VC6+DDK xp+DS3.2

我在做usb上位机驱动过程中做的笔记驱动程序安装成功后,应用程序的设计VC6+DDK xp+DS3.2驱动程序安装好后,应用程序要通过安装的驱动程序与设备的通信,但是应用程序怎么才能找到对应用的驱动程序呢?通过设备的GUID找到设备路径。
在windows操作系统环境下,设备通常被当作特殊文件处理。
要打开设备,就要知道该设备的路径,要找到设备的路径,要使用GUID来查找。
设备在安装时,windows安装器和相应设备的驱动程序负责将相应的设备与对应的GUID联系起来,并将GUID写入注册表,这样通过GUID(接口类GUID)就可以找到对应设备。
对于HID设备,因为它的驱动已经集成在操作系统中,在同一系统中GUID是一样的,但通常这个值在不同的系统下也许会不一样所以一般不直接使用这个GUID,而是使用一个API函数来获取(函数是void _stdcall HidD_GetHidGuid(Out LPGUID HidGuid)). 而我们自己做的嵌入式设备,因为驱动是自己写的,所以GUID肯定不一样,而且这个GUID不会因为设备用在不同的操作系统上而改变,因为这个GUID在生成设备驱动的时候已经生成,就对应这个设备了,这个设备类GUID可以在每个驱动的interface.h文件中看到。
我们就是要用这个文件中的GUID宏定义来查找已连接上设备,把系统中查到的设备列举出来,然后检查它的VID,PID以及设备版本号,看是不是要访问的设备,如果是,就可以对设备进行各种操作了,不是的话就循环下一个设备,直到找到或遍历完为止。
1.下面这个函数用来获取所有与ClassGuid指定的GUID相同的设备,当然对于HID设备在同一个pc机上可能会检测到多个,但是我们自己做的嵌入式设备,一般都是一个,要找到我们要的设备通过VID,PID以及设备版本号。
该函数返回HDEVINFO句柄,这个句柄指向ClassGuid指定的所有设备的一个信息集合。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
中止 I/O 端点的请求接口 IOCTL_ADAPT_ABORT_PIPE 用于中止 I/O 端点的请求,其使用示例代 码如下:
DWORD dwBytes = 0; UCHAR Address = 0x82; DeviceIoControl(hDevice, IOCTL_ADAPT_ABORT_PIPE,
9.获取端点数接口 IOCTL_ADAPT_GET_NUMBER_ENDPOINTS
获取端点数接口 IOCTL_ADAPT_GET_NUMBER_ENDPOINTS 用于获得 EZ-USB 的端点数,其使 用的示例代码如下:
DWORD dwBytes = 0;
153
UCHAR endPts; DeviceIoControl(hDevice, IOCTL_ADAPT_GET_NUMBER_ENDPOINTS, //DeviceIoControl 函数
获取电源接口 IOCTL_ADAPT_GET_DEVICE_POWER_STATE 用于获得 EZ-USB 设备的电源状态, 其使用示例代码如下:
DWORD dwBytes = 0; UCHAR pwrState; DeviceIoControl(hDevice, IOCTL_ADAPT_GET_DEVICE_POWER_STATE, //DeviceIoControl 函数
其中,参数 hDevice 表示当前 USB 设备的句柄,使用了 SET_TRANSFER_SIZE_INFO 结构,参数 IOCTL_ADAPT_GET_TRANSFER_SIZE 表示使用该接口进行通信。
//打开设备句柄
其中,hDevice 即为获得的 USB 设备句柄。在退出程序的时候,需要释放该 USB 设备句柄,使用
如下的语句即可:
delete USBDevice;
在主程序获得 USB 设备的控制句柄后,便可以调用 CYIOCTL 控制函数类提供的接口控制函数,下 面分别进行介绍。
1.中止 I/O 端点的请求接口 IOCTL_ADAPT_ABORT_PIPE
10.获取传输大小接口 IOCTL_ADAPT_GET_TRANSFER_SIZE
获取传输大小接口 IOCTL_ADAPT_GET_TRANSFER_SIZE 用于获得 EZ-USB 的传输大小,其使用 的示例代码如下:
DWORD BytesXfered; SET_TRANSFER_SIZE_INFO SetTransferInfo; SetTransferInfo.EndpointAddress = Address; DeviceIoControl(hDevice, IOCTL_ADAPT_GET_TRANSFER_SIZE, //DeviceIoControl 函数
//地址 //DeviceIoControl 函数
&Address, sizeof (UCHAR),
151
NULL, 0, &dwBytes, NULL);
这 里 在 DeviceIoControl 函 数 中 , 参 数 hDevice 表 示 当 前 USB 设 备 的 句 柄 , 参 数 IOCTL_ADAPT_ABORT_PIPE 表示使用该接口进行通信,参数 Address 为通信的端点号及传输方向。
DWORD dwBytes = 0; ULONG len = 256; UCHAR *buf = new UCHAR[len]; DeviceIoControl(hDevice, IOCTL_ADAPT_GET_DEVICE_NAME, //DeviceIoControl 函数
·152·
buf, len, buf, len, &dwBytes, NULL); delete[] buf;
10.1 Visual C++读写 USB 设备
在 USB 设备开发过程中,上位机程序可以采用广泛应用的 Visual C++来实现。对于 Cypress 公司的 EZ-USB 系列芯片,其提供了全面的 CY3684 开发包。在该开发包中,可以使用 CYIOCTL 控制函数类 和 CyAPI 控制函数类来实现 Visual C++环境下对 USB 设备的读写。
10.1.1 CYIOCTL 控制函数类
CYIOCTL 控制函数类为 Cypress 公司的 EZ-USB FX2LP 系列 USB 接口芯片,提供了简单的控制接 口。在使用 Cypress 公司提供的驱动程序基础上,只需在主机 Visual C++程序中加入头文件 cyioctl.h, 然后便可以调用相应的控制函数。
第 10 章 上位机程序开发
在 USB 设备开发中,上位机程序是用于与用户进行接口的。上位机程序通过 USB 设备驱动程序和 外部的 USB 硬件进行通信,USB 固件程序执行所用的硬件操作。一般来说,根据选择开发平台的不同, 可以使用 Visual C++、Visual C#和 LabVIEW 等开发上位机程序。
//DeviceIoControl 函数
NULL, 0,
NULL, 0,
&dwBytes, NULL);
其中,参数 hDevice 表示当前 USB 设备的句柄,参数 IOCTL_ADAPT_CYCLE_PORT 表示使用该
接口进行通信。
3.获得设备地址接口 IOCTL_ADAPT_GET_ADDRESS
&SetTransferInfo, sizeof (SET_TRANSFER_SIZE_INFO), &SetTransferInfo, sizeof (SET_TRANSFER_SIZE_INFO), &BytesXfered, NULL); LONG transferSz = SetTransferInfo.TransferSize;
为了能够使用这些函数,主机程序必须首先获得 USB 设备的控制句柄。可以通过以下的代码在程
序中获得连接到主机的 USB 设备句柄。
CCyUSBDevice *USBDevice = new CCyUSBDevice();
//USB 设备
பைடு நூலகம்
HANDLE hDevice = USBDevice->DeviceHandle();
&ver, sizeof (ver), &ver, sizeof (ver), &dwBytes, NULL);
其 中 , 参 数 hDevice 表 示 当 前 USB 设 备 的 句 柄 , 参 数 ver 为 返 回 的 版 本 号 , 参 数 IOCTL_ADAPT_GET_DRIVER_VERSION 表示使用该接口进行通信。
本章首先介绍了 Visual C++中控制 USB 设备的相关函数,接着介绍了 Visual C#中读写 USB 设备的 主意函数,最后介绍了在 LabVIEW 中如何读写 USB 设备。本章内容包括:
Visual C++读写 USB 设备; Visual C#读写 USB 设备; LabVIEW 读写 USB 设备。
DWORD dwBytes = 0; UCHAR intfc = 0; UCHAR alt; DeviceIoControl(hDevice, IOCTL_ADAPT_GET_ALT_INTERFACE_SETTING, //DeviceIoControl 函数
&intfc, sizeof (alt), &alt, sizeof (alt), &dwBytes, NULL);
NULL, 0, &endPts, sizeof (endPts), &dwBytes, NULL);
其 中 , 参 数 hDevice 表 示 当 前 USB 设 备 的 句 柄 , 参 数 endPts 为 返 回 的 端 点 个 数 , 参 数 IOCTL_ADAPT_GET_NUMBER_ENDPOINTS 表示使用该接口进行通信。
其 中 , 参 数 hDevice 表 示 当 前 USB 设 备 的 句 柄 , 参 数 buf 为 返 回 的 字 符 串 , 参 数 IOCTL_ADAPT_GET_DEVICE_NAME 表示使用该接口进行通信。
6.获取电源接口 IOCTL_ADAPT_GET_DEVICE_POWER_STATE
获得设备地址接口 IOCTL_ADAPT_GET_ADDRESS 用于重新获得 EZ-USB 设备的地址,其使用示 例代码如下:
DWORD dwBytes = 0; UCHAR DevAddr;
DeviceIoControl(hDevice, IOCTL_ADAPT_GET_ADDRESS, //DeviceIoControl 函数 &DevAddr, sizeof (UCHAR), &DevAddr, sizeof (UCHAR), &dwBytes, NULL);
&pwrState, sizeof (pwrState), &pwrState, sizeof (pwrState), &dwBytes, NULL);
其 中 , 参 数 hDevice 表 示 当 前 USB 设 备 的 句 柄 , 参 数 pwrState 为 返 回 的 字 符 串 , 参 数 IOCTL_ADAPT_GET_DEVICE_POWER_STATE 表示使用该接口进行通信。
其 中 , 参 数 hDevice 表 示 当 前 USB 设 备 的 句 柄 , 参 数 IOCTL_ADAPT_GET_ALT_INTERFACE_SETTING 表示使用该接口进行通信。
5.获取字符串接口 IOCTL_ADAPT_GET_DEVICE_NAME
获取字符串接口 IOCTL_ADAPT_GET_DEVICE_NAME 用于获得连接的 EZ-USB 设备的产品描述 字符串,其使用示例代码如下: