功能的命令集,命令接口部分就是将各命令用函数的形式加以实现。对应的函数主要有: 设置地址使能
void D12_SetEndpointEnable(unsigned char bEnable);
void D12_SetAddressEnable(unsigned char bAddress, unsigned char bEnable);
//
//设置端点使能
void D12_SetMode(unsigned char bConfig, unsigned char bClkDiv); //设置模式 unsigned short D12_ReadInterruptRegister(void); //读中断寄存器
unsigned char D12_SelectEndpoint(unsigned char bEndp); //选择端点
unsigned char D12_ReadLastTransactionStatus(unsigned char bEndp); //读最后处理状态
unsigned char D12_ReadEndpointStatus(unsigned char bEndp); //读端点状态
void D12_SetEndpointStatus(unsigned char bEndp, unsigned char bStalled); //设置端点状态
void D12_SendResume(void); //发送恢复
unsigned short D12_ReadCurrentFrameNumber(void); //读取当前帧号 unsigned short D12_ReadChipID(void); //读D12芯片ID
unsigned char D12_ReadEndpoint(unsigned char endp, unsigned char len, unsigned char * buf);//读取端点数据
unsigned char D12_WriteEndpoint(unsigned char endp, unsigned char len, unsigned char * buf);//写端点数据
void D12_AcknowledgeEndpoint(unsigned char endp);//设置端点应答
3.4.3 中断服务程序ISR.C
这部分代码处理由PDIUSBDI2产生的中断,ISR从PDIUSBD12收集数据,当数据充足时,通知主循环已经准备好等待处理。它将数据从PDIUSBDI2的内部FIFO取回到CPU存储器,并建立正确的事件标志以通知主循环程序。在ISR函数的入口固件使用
ReadInterruptRegister()来决定中断源,根据中断源进入相应的子程序进行处理。 中断服务处理的部分代码如下: //USB中断处理
usb_isr() interrupt 0 {
DISABLE; fn_usb_isr(); ENABLE; }
void fn_usb_isr() {
unsigned int i_st;
bEPPflags.bits.in_isr = 1;
i_st = D12_ReadInterruptRegister(); if(i_st != 0) {
}
if(i_st & D12_INT_BUSRESET) {
bus_reset();
bEPPflags.bits.bus_reset = 1; }
if(i_st & D12_INT_EOT) dma_eot();
if(i_st & D12_INT_SUSPENDCHANGE) bEPPflags.bits.suspend = 1; if(i_st & D12_INT_ENDP0IN)
ep0_txdone();
if(i_st & D12_INT_ENDP0OUT) ep0_rxdone();
if(i_st & D12_INT_ENDP1IN)
ep1_txdone();
if(i_st & D12_INT_ENDP1OUT) ep1_rxdone();
if(i_st & D12_INT_ENDP2IN) main_txdone();
if(i_st & D12_INT_ENDP2OUT)
main_rxdone();
bEPPflags.bits.in_isr = 0; }
//A/D转换中断处理 adc_isr() interrupt 1 {
DISABLE;
bEPPflags.bits.adc_isr = 1; ENABLE; }
3.4.4 主循环MAINLOOP.C
主循环检查事件标志并进入对应的子程序进行进一步的处理。在主循环中,MCU首先对其所有端口、存储区、定时器和中断服务程序进行初始化,之后MCU将重新连接USB,包括
将Softe Connect寄存器设置为ON。这些过程是很重要的,它确保了在MCU准备好服务D12之前,D12不会进行操作。初始化后,进入循环,轮询各种状态。当轮询到了检测建立包时,它确认建立标志在之前是否被中断服务程序所置位。如果建立标志被置位,它将向协议层发送一个器件请求进行处理。
/* 数据采集子程序 */ void adc_handler(void)
{ unsigned char ADC_DATA; ADC_DATA=IN_PORT;
D12_WriteEndpoint(3, 1, &ADC_DATA); IN_PORT=0x00;
if(bEPPflags.bits.ep1_rxdone) { DISABLE;
bEPPflags.bits.ep1_rxdone = 0; ENABLE;
ADC_IN_ID =0x7FF8+GenEpBuf[3];
} }
/* 主程序循环 */
while(TRUE){ if(bEPPflags.bits.adc_isr){ // DISABLE;
bEPPflags.bits.adc_isr = 0; ENABLE;
if(bEPPflags.bits.configuration) adc_handler();
}
if (bEPPflags.bits.bus_reset) { // DISABLE;
bEPPflags.bits.bus_reset = 0; ENABLE; D12SUSPD = 1;
}
数据采集处理 设备复位中断处理 if (bEPPflags.bits.suspend) { //挂起改变中断处理 DISABLE;
bEPPflags.bits.suspend= 0; ENABLE;
if(D12SUSPD == 1) { //挂器处理 D12SUSPD = 0; P0 = 0xFF; P1 = 0xFF; P2 = 0xFF; P3 = 0xFF; D12SUSPD = 1; PCON |= 0x02; while (1);
}
}
if (bEPPflags.bits.setup_packet){ //Setup DISABLE;
bEPPflags.bits.setup_packet = 0; ENABLE;
control_handler(); D12SUSPD = 1;
}
} // End Main Loop
包中断处理
4 USB设备驱动程序设计
设备驱动程序是一个软件组件,介于硬件与用户应用软件之间,为它们之间的通信提供桥梁。首先必须具备编制设备驱动程序的软件环境:Visual Studio和Windows DDK(Driver Develop Kit)。大多软件开发人员习惯于使用DriverStudio来编写设备驱动程序,因为它产生的代码是C风格,并且由于它的封装形式类似应用程序,作为一个由应用程序装入内核级程序编写人员,这个工具非常有用。有些却采用DDK开发方案,这样能够避免Windows操作系统的快速更新以及其他的原因所带来的影响。
在USB的概念中,USB设备的一个类是指一组具有一些相同属性的设备的集合。把这些设备归为一组,是为了给这一类设备开发基于HOST的驱动。这个设备类规范作为这一类设备的框架,定义属于该类设备的操作。这让设备类驱动程序的开发可以脱离设备的制造商而依据于规范。因此硬件制造商可以专注于它们的硬件开发,而软件开发者可以专注于开发它们的软件和驱动程序,但所有的USB设备必须符合USB协议,一个类设备也必须符合这个类规范要求。这个类规范说明一个USB设备和驱动程序的通讯过程。本文所讨论的基于USB的数据采集系统,在USB中并没有定义这类设备。因为这类设备面向的应用是千差万别的,因此这些设备很难抽象出很多的共性,因此我们需要对自己的设备开发USB的驱动程序。 设备驱动程序主要是提供操作系统与硬件设备的接口,支持用户及其应用程序要求的信息流。由于用户对数据快速处理的要求,驱动程序现在必须作比发送和接收数据多得多的工作。对于该设备驱动程序的编写,我们采用WDM(Windows32 Driver Mode)驱动程序模型,该模型主要有以下特点:①支持即插即用(PnP)和电源管理。也就是说外部设备可以在系统运行时添加或删除,操作系统可以在任何时候分配设备需要的硬件资源,电源管理表明设备对系统电源的使用情况是动态变化的。WDM驱动程序支持设备的电源管理,使得设备同系统电源使用情况和设备所处的工作状态相关。②提供系统总线驱动程序。设备驱动程序通过总线驱动程序控制在USB总线上的设备,总线驱动程序提供了一个较高层次的接口,这个接口可以接收系统对USB设备的请求,驱动程序的功能设备对象不需要直接和USB控制器交互信息。③支持WMI(Windows Management Instrumentation),它是一种系统管理员报告管理信息的协议,这个协议能测量和管理消耗在本地或者是网络中客户机上的资源信息,WDM驱动程序必须支持WMI,一般这种请求是通过IRP_MJ_SYSTEM_CONTROL请求传递给PDO的。④支持类驱动程序/微驱动程序分层结构。WDM驱动程序采用分层结构,可和其它驱动程序相联系,接收建立在其上的驱动程序提供的服务,也可向其它驱动程序发送IRP请求。WDM型驱动程序采用了分层处理的方法,用户不需要直接和硬件打交道,而只需要通过下层驱动程序提供的接口来访问硬件。
微软在他们的WinHEC96中发布了Win32驱动程序模型WDM。它的目标是为Windows NT,