引言
USB无疑已经成为21世纪嵌入式系统的标准外部串行接口;然而开发USB外设,需要面对微处理器和USB控制器的选择,熟悉Windows驱动程序,开发微处理器固件程序和PC机端应用程序等诸多问题,开发工作既专业又麻烦。签于此,本文以包含片上USB控制器的C8051F340单片机和进行PC机端GUI用户应用程序开发的Labview软件为基础,介绍一种基于API实现USB通信的开发方法,从而帮助大家了解和熟悉USB外设的API开发方法。
C8051F340是Silicon Laboratories公司最新推出的可提供USB功能的混合信号微控制器。它包含高速流水线的8051兼容微控制器核,运行速率可以高达48 MIPS;64 KB的芯片内建闪存与5 376字节的RAM,片上外设引脚可以软件配置,70%的指令可以在1个或2个机器周期中执行;USB功能控制器具有完整的USB 2.0认证,支持全速与低速操作,可以用于大多数USB外设设计。另外,Silicon Laboratories公司还为USB驱动程序开发提供了USBXpress开发套件,使得USB主机和从机驱动程序开发可以快捷、高效地完成。
Labview是一个具有革命性的图形化开发环境。它内置信号采集、测量分析与数据显示功能,摒弃了传统开发工具的复杂性,为用户提供强大功能的同时还保证了系统的灵活性。Labview将广泛的数据采集、分析与显示功能集中在了同一个环境中,让开发人员可以在自己的平台上无缝地集成一套完整的应用方案。利用Labview软件开发PC机端USB应用程序,不仅可以获得具有良好人机交互的GUI界面,而且将极大地加快开发进程。
1 API实现USB通信的原理
USB外设开发除了硬件设计外,大部分工作集中在固件编程和PC机端驱动程序以及用户应用程序的开发上。一般利用API实现USB通信的原理框图如图1所示。显然,要完成USB通信需要PC机端(USB主机)与C8051F340单片机端(USB器件)共同协作。在PC机端,需要首先建立USB主机驱动程序,然后编写用户应用程序,进而利用API函数实现用户应用程序从USB主机驱动处获取USB数据包,并完成相应的USB读写操作;在单片机端,同样需要先调用USB器件驱动程序,然后编写应用程序,而应用程序通过USB器件驱动程序实现访问USB底层硬件。于有了Silicon Laboratories公司提供的USBXpress的开发套件,上述驱动以及应用程序的编写变得极为简便。通过在Windows操作系统环境下安装USBXpress软件,就可以直接获得USB主机驱动程序(在USBXpress安装目录下的Driver目录中)、USB主机API(USBXpress安装目录下的SiUSBXp.dll)以及USB器件驱动程序(USBXpress安装目录下的USBX_F34X.LIB)。USBXpress开发套件提供的各种软件库通过一系列函数实现单片机端和PC机端的应用程序接口(API)。这些函数封装了USB协议的细节,使得程序开发人员不需要了解USB的过多细节即可使用USB进行数据通信。因此对USB通信开发来说,要做的仅仅是USB主机和USB器件的具体应用程序开发,以及API函数的直接调用。
图1单片机与PC机的USB通信原理框图
由于有了Silicon Laboratories公司提供的USBXpress的开发套件,上述驱动以及应用程序的编写变得极为简便。通过在Windows操作系统环境下安装USBXpress软件,就可以直接获得USB主机驱动程序(在USBXpress安装目录下的Driver目录中)、USB主机API(USBXpress安装目录下的SiUSBXp.dll)以及USB器件驱动程序(USBXpress安装目录下的USBX_F34X.LIB)。USBXpress开发套件提供的各种软件库通过一系列函数实现单片机端和PC机端的应用程序接口(API)。这些函数封装了USB协议的细节,使得程序开发人员不需要了解USB的过多细节即可使用USB进行数据通信。因此对USB通信开发来说,要做的仅仅是USB主机和USB器件的具体应用程序开发,以及API函数的直接调用。
2 API实现USB通信的方法和流程
2.1 PC机USB通信的方法和流程
借助USBXpress提供的USB主机API,即USBXpress安装目录下的SiUSBXp.dll,可以简便地实现在PC机上通过Labview软件编写的GUI程序与作为USB器件的C8051F340单片机的USB通信。USBXpress提供了10个USB主机API函数,如表1所列。
表1 USB主机API函数
Labview软件编写的GUI程序可通过Labview软件中的CLF节点(Labview高级子模板中的调用库函数节点)调用USBXpress提供的USB主机API,以达到访问USB底层硬件的目的。现以实现USB主机API函数中的SI_GetNumDevices()函数为例,具体说明在Labview软件中如何实现对USB API函数的调用。
首先,在Labview软件的程序面板中放置一个空的调用库函数节点,空的调用库函数节点是没有任何作用的,需要对它进行有效设置。通过双击空的调用库函数节点可产生图2所示的调用库函数节点配置对话框。此时,需先在“库名或路径”框中设置USB主机API函数的封装库SiUSBXp.dll的路径,然后在“函数名”下拉菜单中选择当前想要调用的SI_GetNumDevices()函数,在“线程”框中选择“在UI线程中运行”,在“调用规范”框中选择“stdcall(WINAPI)”,最后在“参数”菜单中进行相应设置。所有设置完毕,得到图3所示的名为“SI_GetNumDevices”的调用库函数节点。这样Labview的上层应用程序就可以通过调用这个库函数节点来获取USB器件的序列号信息。通过类似的方法,可以方便地将USB主机API函数中所有需要用到的函数生成为Lavbiew可以直接调用的调用库函数节点形式,从而实现对USB底层硬件的访问。
图2 Labview软件调用库函数节点配置API对话框
一般,Labview的上层应用程序通过调用USBXpress提供的USB主机API函数实现对下层USB硬件访问的程序流程如图4所示。
图3 Labview调用库函数节点图
由图4可以看出,通常USB主机API调用SI_GetNumDevices()、SI_GetProductString()、SI_Open()、SI_Close()、SI_Read()、SI_Write()、SI_GetTimeouts ()几个API函数就可以实现USB通信功能;而剩下的SI_FlushBuffers()、SI_SetTimeouts()、SI_CheckRXQueue()函数则可实现一些特殊功能。例如,调用SI_CheckRXQueue()函数,可分析出USB主机还有多少字节的数据还没有从USB器件的读队列缓冲中读取。另外需要说明两点: ① 不要过于频繁地调用SI_Open()和SI_Close()函数,否则将使Labview与USB的通信变得缓慢,效率降低;② USB主机一次可从USB器件读取0~64 KB个数据,但是一次只能向USB器件写入0~4 096[Z1]byte个数据,在进行USB数据读写时千万不能超过这两个界限,否则会导致数据传输丢失或USB总线返回错误报告。如果USB通信数据过多,超过了这两个界限,则可在调用SI_Open()后,在调用SI_Close()前通过多次调用SI_Read()和SI_Write()完成USB数据的读写。
图4 Labview利用API实现USB通信流程
2.2 C8051F340USB通信的方法和流程
借助USBXpress提供的USB器件API,即USBXpress安装目录下的USBX_F34X.LIB,同样可以简便地实现C8051F340单片机作为USB器件的USB通信。USBXpress提供了10个USB器件API函数,如表2所列。在对C8051F340单片机进行编程时,只需将USBXpress提供的API函数的封装库USBX_F34X.LIB调入编译软件的链接器中,并在主程序中用“include”命令包含USB_API.h头文件(申明了USBX_F34X.LIB中提供的10个API函数),可以像调用普通函数一样调用USBXpress提供的10个USB器件API函数,从而实现对USB数据包的读写。
表2 USB器件API函数
大多数情况下,C8051F340单片机的上层应用程序通过调用USBXpress提供的USB器件API函数,实现对下层USB硬件的访问,程序流程如图5所示。
图5 单片机利用API实现USB通信流程
在程序流程中需要注意的是:C8051F340单片机作为USB器件对USB主机进行读写操作的机制不同。当C8051F340单片机对USB主机进行写操作时,直接调用Block_Write()函数即可;但是当C8051F340单片机对USB主机进行读操作时,读操作的实现流程还要依靠USB总线处于何种工作方式。例如,当USB总线处于中断传输模式时,只有USB API中断发生时,USB器件才能获取USB主机数据,完成C8051F340单片机对USB主机的读操作,也即Block_Write()函数的调用一般放在USB API中断服务程序中进行。
3 结论
通过USBXpress开发套件提供的API实现USB通信的方法,可快捷、高效地实现C8051F340单片机与Labview编写的GUI程序之间的USB通信,且无需开发者熟悉USB总线协议规范,无需考虑USB主机和USB器件驱动程序的开发,而可以集中精力于上层应用程序的开发,从而大大降低了开发难度并缩短了开发周期。