这个过程当中主机检测到有设备插入就会向设备发送一些数据,而这些数据是设备刚插入主机时主机所要设备描述符的控制传输。现在我们的设备没有任何驱动程序来响应“组织的号召”,所以我们的“中央”就不知道如何来加载主机驱动来管理我们的设备,“中央”就会把它拉入黑名单说,硬件安装出现问题,设备不能正常运行,所以在设备管理器中就冒出了一个未知设备。在未知设备上点右键属性,在详细信息选项卡中会看到VID和PID都是0。如图2—3a,图2—3b是枚举成功的大容量存储设备。
第三篇:软件配置
我们来看一下程序在悍马1788是如何实现连接的。工程创建不讲述。
/**********************************************************************
函数功能;主函数
函 数 名;main
函数参数;无
函数返回;无
***********************************************************************/
int main (void)
{
debug_frmwrk_init(); /*串口调试初始化,
用于打印调试信息
和主机发给开发板
的数据还有开发板
发给主机的数据。*/
print_menu(); //打印字符串。
USB_Init(); // 初始化USB
USB_SetDevCondition(DEV_CON); // 链接USB
while (1)
{
;
}
}
看起来好像很简单,main函数里面关于USB的代码就两行。现在我们就来看下USB_Init();
/**********************************************************************
函数功能;初始化USB函数
函 数 名;USB_Init
函数参数;无
函数返回;无
***********************************************************************/
void USB_Init (void)
{
PINSEL_ConfigPin ( 0, 31, 1); //P0.31管脚设置为USB_D2+的功能
PINSEL_ConfigPin ( 0, 14, 3); //P0.14管脚设置为USB_CONNECT2功能
CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCUSB, ENABLE); //配置USB时钟/电源
LPC_USB->USBClkCtrl = 0x1A; /*USB时钟控制寄存器,
它控制了AHB、端口选
择寄存器、设备时钟,
这些时钟的使能和失能。*/
while ((LPC_USB->USBClkSt & 0x1A) != 0x1A); /*USBClkSt 寄存器是
时钟状态寄存器,检查
是否设置为0x1A。*/
LPC_USB->StCtrl = 0x3; //端口选择寄存器我们用的USB2所以是就是0x3
}
在初始化函数里面就只有USB_D2+和USB_CONNECT2引脚被配置了,而USB_D2-和VBUS没有配置。
接下来就是USB基本配置用库函数的CLKPWR_ConfigPPWR (CLKPWR_PCONP_PCUSB, ENABLE);来使能时钟和电源,下一行是USBClkCtrl寄存器配置,这个寄存器是USB时钟控制寄存器,它控制了AHB、端口选择寄存器、设备时钟,这些时钟的使能和失能,下面就是USBClkSt寄存器,这个寄存器是时钟状态寄存器,只是用来检测USBClkCtrl寄存器是否成功配置,还有一个是StCtrl寄存器,它是用来选择是用那一个USB端口。
实现简单的连接功能,初始化这些就可以搞定。现在分析USB_SetDevCondition(DEV_CON)函数;
/**********************************************************************
函数功能;设置USB设备状态
函 数 名;USB_SetDevCondition
函数参数;con;DEV_CON 0x01连接位表示设备的当前连接状态。用于CONNECT输出
DEV_CON_CH 0x02连接发生改变
DEV_SUS 0x04挂起位表示当前的挂起状态
DEV_SUS_CH 0x08挂起位(DEV_SUS)的变化指示,
设备进入挂起状态、设备断开连接、 设备在其上行端口上接收到恢复信号, 会发生翻转
DEV_RST 0x10总线复位位
函数返回;无
***********************************************************************/
void USB_SetDevCondition(uint32_t con)
{
WrCmdDat(CMD_SET_DEV_STAT, DAT_WR_BYTE(con));
}
我们看到USB_SetDevCondition(DEV_CON);函数里面还调用了WrCmdDat(CMD_SET_DEV_STAT, DAT_WR_BYTE(con));函数这个函数是一个写命令数据函数。
/**********************************************************************
函数功能;写命令数据函数
函 数 名;WrCmdDat
函数参数;cmd;命令
val: 数据
函数返回;无
***********************************************************************/
void WrCmdDat (uint32_t cmd, uint32_t val)
{
LPC_USB->DevIntClr = 1<<4; /*DevIntClr寄存器是设备中断清除寄存器
写相应的位就会清除DevIntSt设备中断状态
寄存器相应位,应为我们要写命令,所以我
们要把命令代码寄存器为空中断标志位清除*/
LPC_USB->CmdCode = cmd; /*写入命令*/
while ((LPC_USB->DevIntSt & 1<<4) == 0); /*等待命令代码寄存器
为空中断标志位置位*/
LPC_USB->DevIntClr = 1<<4; /*清除中断*/
LPC_USB->CmdCode = val; /*写入数据*/
while ((LPC_USB->DevIntSt & 1<<4) == 0); /*清除中断*/
}