STM32-USB使用方法
开发板买的是奋斗mini开发板,芯片是:STM32F103VET6. 如果需要源程序keil4-arm工程,上位机vb。加qq339396264要程序。
USB开发涉及主机和设备,为了避免开发驱动程序,使用Windows自带的驱动程序。所以设备枚举成HID类设备。USB鼠标就是标准的USB-HID设备。不过操作系统阻止了应用程序直接访问USB鼠标返回的报告。所以本例使用自定义HID设备。一来免去了开发驱动程序,二来自定义的HID设备应用程序和设备可以自由收发数据(仅指数据内容)。
本文主要介绍STM32的USB模块的简单使用,不会介绍USB协议。主要是介绍一下STM32F103的USB模块使用。
USB模块从初始化首先是配置和使能时钟
下面是时钟的初始化:
void Set_USBClock(void) { }
首先系统时钟要设置为72MHz,然后配置USB时钟为48MHz并使能。
然后是配置中断
void USB_Interrupts_Config(void) { }
//【使能USB中断】
NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn; //【USB低优先级中断】 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); NVIC_InitTypeDef NVIC_InitStructure; #define USB_LP_CAN1_RX0_IRQn 20
//RCC_USBCLKSource_PLLCLK_1Div5表示【USB时钟 = PLL时钟除以1.5】【72/1.5=48MHz】 RCC_USBCLKConfig(RCC_USBCLKSource_PLLCLK_1Div5);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USB, ENABLE);//【使能配置好了的USB时钟】
然后初始化模块的一些寄存器 USART_send_str(\"USB断开\\r\\n\");
USB_DISCONNECT//这是断开1.5k上拉电阻 delay(0x7AFFFF);//延时一会
USB_CONNECT//使能1.5K上拉电阻 USART_send_str(\"USB连接\\r\\n\");
DADDR = 0x0080;//USB模块使能位。EF必须置1
CNTR = 0x0001;//强制复位 CNTR = 0x0000;//退出复位
ISTR = 0x0000;//清除可能产生的假中断
CNTR = (I_CTR | I_RESET);//使能一些中断,为了简单这里只使能了【总线复位中断】和【数据正确传输中断】 ISTR = 0x0000;//清除可能产生的假中断
自此USB模块初始化完毕。
以后的流程就在USB中断的驱动下执行。
USB中断函数:
void USB_LP_CAN1_RX0_IRQHandler(void) { u16 wIstr; //USB中断状态寄存器 wIstr = (u16)ISTR; //【USB复位中断】 if(wIstr &I_RESET) { USB_RST_Process(); return; } //【正确传输中断】 if (wIstr & I_CTR) { USB_CTR_Process(); return; } }
在USB中断函数中就是判断中断源,并转向相应的中断服务函数。
USB总线复位后,USB相关的一些寄存器会复位。在USB总线复位中要配置一下寄存器和数据收发的缓冲区。程序如下 void USB_RST_Process(void) { //清除中断 ISTR = (u16)(~I_RESET);//清除ISTR寄存器中断RESET位。写0清除,写1寄存器位内容不变。
// USART_send_str(\"【USB】【复】【位】【中】【断】\\r\\n\"); usb_status = 0; //复位处理 DADDR = 0x0080; //USB模块使能位。EF必须置1 BTABLE = 0; //复位后默认为0 EP0REG = (u16)(0x0220); //0000 0010 0010 0000 端点0初始化:控制端点,NAK主机的IN令牌,端点号0 //设置TX/RX起始地址 USB_ADDR0_TX = 32;//32-95 端点0的发送缓冲区从32开始到95,共64字节 USB_ADDR0_RX = 96;//96-159 端点0的接收缓冲区从96开始到159,共64字节 //设置端点0接收缓冲区大小:64Byte USB_CNT0_RX = 0x8400;//1000,0100,0000,0000
//【端点1】
EP1REG = (u16)(0x0621);//0000 0110 0010 0001 端点0初始化:中断端点,NAK主机的IN令牌,端点号1
//设置TX/RX起始地址
USB_ADDR1_TX = 160;//160-223 端点1的发送缓冲区从160开始到223,共64字节 USB_ADDR1_RX = 224;//224-287 端点1的接收缓冲区从224开始到287,共64字节 //设置端点1接收缓冲区大小:64Byte
USB_CNT1_RX = 0x8400;//1000,0100,0000,0000 //设置RX Valid .端点0可用于接收 { u16 t = EP0REG;//读出端点0寄存器值 t &= 0x8F8F;//1000 1111 1000 1111 由于t位写0不影响原来的值,写1翻转,所以把 t位都设置为0 t |= 0x8080;//1000 0000 1000 0000 由于w0位写0清除,写1无影响,所以w0位都设置为1 t |= 0x3000;//0011 0000 0000 0000 把 SRAT_RX[1:0]设置为1,通过写1翻转来实现。 EP0REG = t; } }
下面是正确传输中断 //USB分组正确传输处理 void USB_CTR_Process(void) {
/******************************************【端点0】******************************************/ if((ISTR & 0x0F) == 0)//端点0 { // //
if((ISTR & 0x10) == 0)//in分组 { }
USART_send_str(\"****************端点0的IN分组发送完成****************\\r\\n\");
if(usb_status == 1) { usb_status = 2; DADDR = 0x80 | (usb_addr&0xFF);//设置地址一定要找控制传输的状态完成后写入地址寄存器 USART_send_str(\"\\r\\n【写入地址完成】\\r\\n\"); }
//发送剩余数据 USB_ep0_send();
//清除CTR_TX { u16 t = EP0REG; t &= 0x8F8F;//1000 1111 1000 1111 把 t位都设置为0 t |= 0x8080;//1000 0000 1000 0000 把w0位都设置为1 t &= 0xFF7F;//1111 1111 0111 1111 把CTR_TX设置为0,清除CTR_RX位 EP0REG = t; }
if(ISTR & 0x10)//【OUT】分组 or 【SETUP】分组 { u16 ep0r= EP0REG;
//清除CTR_RX { u16 t = EP0REG; t &= 0x8F8F;//1000 1111 1000 1111 把 t位都设置为0 t |= 0x8080;//1000 0000 1000 0000 把w0位都设置为1 t &= 0x7FFF;//0111 1111 1111 1111 把CTR_RX设置为0,清除CTR_RX位 EP0REG = t; }
if(ep0r & 0x0800)//SETUP令牌包 { //USART_send_str(\"端点0收到【SETUP】分组\\r\\n\"); //默认控制端点处理——枚举处理 ep0_setup_Process(); memset(USB_rcv_buffer, 0x00, sizeof(USB_rcv_buffer)); USB_enable_ep0_rx(); } else { //USART_send_str(\"控制读传输:状态阶段\\r\\n\"); USB_read_EP0_buf(USB_rcv_buffer, (u32*)(PMAAddr+96*2)); USB_enable_ep0_rx(); } } //else//【IN分组传输成功】 }
/******************************************【端点1】******************************************/ else if((ISTR & 0x0F) == 1) { USART_send_str(\"端点1数据完成传输\\r\\n\"); if(ISTR & 0x10)//【OUT分组】 { //清除CTR_RX { u16 t = EP1REG; t &= 0x8F8F;//1000 1111 1000 1111 把 t位都设置为0 t |= 0x8080;//1000 0000 1000 0000 把w0位都设置为1 t &= 0x7FFF;//0111 1111 1111 1111 把CTR_RX设置为0,清除CTR_RX位 EP1REG = t; } USB_read_EP1_buf(USB_rcv_buffer, (u32*)(PMAAddr+224*2)); //【读 取】端点1数据 //【处 理】端点1数据 USB_enable_ep1_rx(); //【继续接受】端点1数据 }
}
else//【IN分组】 { //清除CTR_TX { u16 t = EP1REG; }
t &= 0x8F8F;//1000 1111 1000 1111 把 t位都设置为0 t |= 0x8080;//1000 0000 1000 0000 把w0位都设置为1 t &= 0xFF7F;//1111 1111 0111 1111 把CTR_TX设置为0,清除CTR_RX位 EP1REG = t; }
//标记发送完成
/******************************************【端点ERR】******************************************/ else { USART_send_str(\"出错!端点号是没有开启对端点。\\r\\n\"); } }
其他代码:
//设置RX Valid .使端点继续接收 void USB_enable_ep0_rx(void) { u16 t = EP0REG;
// USART_send_str(\"EP0REG = \");USART_send_HEX(t>>8);USART_send_HEX(t&0xff);USART_send_str(\"\\r\\n\"); t &= 0x8F8F;//1000 1111 1000 1111 把 t位都设置为0 t |= 0x8080;//1000 0000 1000 0000 把w0位都设置为1 switch(EP0REG & 0x3000) { case 0x0000: t |= 0x3000;break; case 0x1000: t |= 0x2000;break; case 0x2000: t |= 0x1000;break; case 0x3000: t |= 0x0000;break; } EP0REG = t;
// t = EP0REG;
// USART_send_str(\"EP0REG = \");USART_send_HEX(t>>8);USART_send_HEX(t&0xff);USART_send_str(\"\\r\\n\"); }
//设置RX Valid .使端点继续接收 void USB_enable_ep1_rx(void) { u16 t = EP1REG; t &= 0x8F8F;//1000 1111 1000 1111 把 t位都设置为0 t |= 0x8080;//1000 0000 1000 0000 把w0位都设置为1 switch(EP1REG & 0x3000) { case 0x0000: t |= 0x3000;break; case 0x1000: t |= 0x2000;break; case 0x2000: t |= 0x1000;break; case 0x3000: t |= 0x0000;break; } EP1REG = t; }
//读取端点0收到的数据
u8 USB_read_EP0_buf(u8 *buf, u32 *USB_buf) {
u16 rcv_num; u8 read_cnt; u8 i;
u16 temp; u8 j = 0;
//接收到的数据
rcv_num = USB_CNT0_RX & 0x03FF; //{
// unsigned char s[32] = {0};
// sprintf((char*)s, \"端点0读取【%d】字节数据:\ // USART_send_str(s); //} //USART_send_str(\"\\r\\n--------------------------------------------------------------------------------\\r\\n\"); //读取次数 read_cnt = (rcv_num+1)>>1; for(i=0;i u8 USB_read_EP1_buf(u8 *buf, u32 *USB_buf) { u16 rcv_num; u8 read_cnt; u8 i; u16 temp; u8 j = 0; //接收到的数据 rcv_num = USB_CNT1_RX & 0x03FF; { } unsigned char s[32] = {0}; sprintf((char*)s, \"【端点1】读取【%d】字节数据:\USART_send_str(s); USART_send_str(\"\\r\\n--------------------------------------------------------------------------------\\r\\n\"); //读取次数 read_cnt = (rcv_num+1)>>1; for(i=0;i void USB_write_EP0_buf(u8 *buf, u32 *USB_buf, u8 len) { u8 send_cnt; u8 i; u8 j = 0; u16 h,l; // { // unsigned char s[32] = {0}; // sprintf((char*)s, \"端点0发送【%d】字节数据:\// USART_send_str(s); // } // // USART_send_str(\"\\r\\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\\r\\n\"); // for(i=0;i send_cnt = (len+1) >> 1; for(i=0;i //通过端点1发送数据 void USB_write_EP1_buf(u8 *buf, u32 *USB_buf, u8 len) { u8 send_cnt; u8 i; u8 j = 0; u16 h,l; { unsigned char s[32] = {0}; sprintf((char*)s, \"端点1发送【%d】字节数据:\ USART_send_str(s); } USART_send_str(\"\\r\\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\\r\\n\"); for(i=0;i //发送次数 send_cnt = (len+1) >> 1; for(i=0;i if(send_len_ep0 != 0)//一次能够发送完成 { USB_write_EP0_buf(p_send_ep0, ((u32*)(PMAAddr+32*2)), send_len_ep0); send_len_ep0 = 0; } else//等于0 { if(need_0_pack_ep0 == 1) { need_0_pack_ep0 =0; USB_write_EP0_buf(p_send_ep0, ((u32*)(PMAAddr+32*2)), 0); } } } } //端点0枚举过程处理 void ep0_setup_Process(void) { //读取接收到的数据 USB_read_EP0_buf(USB_rcv_buffer, (u32*)(PMAAddr+96*2)); req_type = USB_rcv_buffer[0]; req = USB_rcv_buffer[1]; w_value = (USB_rcv_buffer[3]<<8) | USB_rcv_buffer[2]; w_index = (USB_rcv_buffer[5]<<8) | USB_rcv_buffer[4]; w_length = (USB_rcv_buffer[7]<<8) | USB_rcv_buffer[6]; if(req_type & 0x80)//输入请求 { switch((req_type>>5) & 0x03)//请求的类型 { case 0://标准请求.省略了对“请求的接收者”的判断 { //USART_send_str(\"USB标准输入请求:\"); switch(req)//标准请求代码 { case 0://获取状态 { //USART_send_str(\"获取状态\\r\\n\"); } break; case 6://获取描述符 { //USART_send_str(\"获取描述符——\"); switch((w_value>>8) & 0xFF)//描述符类型 { case 1://设备描述符 { //USART_send_str(\"设备描述符\\r\\n\"); p_send_ep0 = (u8*)dev_d;//设备描述符数组 if(w_length > dev_d[0])//如果请求的数据大于描述符长度,返回描述符长度最大长度 { send_len_ep0 = dev_d[0];//18 if((send_len_ep0 % dev_d[7]) == 0) { need_0_pack_ep0 = 1;//是包长的整数倍,需要发送0长度数据包 } } else//请求长度小于等于描述符长度,则返回请求长度 { } send_len_ep0 = w_length; USB_ep0_send(); } break; case 2://配置描述符 { //USART_send_str(\"配置描述符\\r\\n\"); p_send_ep0 = (u8*)cfg_d;//设备描述符数组 send_len_ep0 = (cfg_d[3]<<8) | cfg_d[2];//发送长度等于配置集合长度 if(w_length > send_len_ep0)//如果请求的数据大于端点0,返回端点0最大长度 { if((send_len_ep0 % dev_d[7]) == 0) { need_0_pack_ep0 = 1;//是包长的整数倍,需要发送0长度数据包 } } else//请求小于等于端点0,返回请求长度 { send_len_ep0 = w_length; } USB_ep0_send(); } break; case 3://字符串描述符 { //USART_send_str(\"字符串描述符\\r\\n\"); } break; case 0x22://报告描述符 { //USART_send_str(\"报告描述符\\r\\n\"); p_send_ep0 = (u8*)rpt_d; send_len_ep0 = sizeof(rpt_d); if(w_length > send_len_ep0)//如果请求的长度大于实际长度 { if((send_len_ep0 % dev_d[7]) == 0) { need_0_pack_ep0 = 1;//是包长的整数倍,需要发送0长度数据包 } } else { send_len_ep0 = w_length;//返回长度等于请求长度 } USB_ep0_send(); // // // } break; default://其他描述符 { USART_send_str(\"其他描述符:\"); USART_send_HEX((w_value>>8)&0xFF); USART_send_str(\"\\r\\n\"); } break; } } break; case 8://获取配置 { //USART_send_str(\"获取配置\\r\\n\"); } break; case 10://获取接口 { //USART_send_str(\"获取接口\\r\\n\"); } break; case 12://帧同步 { //USART_send_str(\"帧同步\\r\\n\"); } break; default: { //USART_send_str(\"USB未定义输入请求\\r\\n\"); } break; } } break; case 1://类请求 { //USART_send_str(\"USB类输入请求\\r\\n\"); } break; case 2://厂商请求 { //USART_send_str(\"厂商输入请求\\r\\n\"); } break; case 3://保留 { //USART_send_str(\"USB输入请求:保留\\r\\n\"); } break; } } else/*********************************输出请求*********************************/ { switch((req_type>>5) & 0x03)//请求的类型 { case 0://标准请求.省略了对“请求的接收者”的判断 { //USART_send_str(\"USB标准输出请求:\"); switch(req)//标准请求代码【GET】 { case 1://清除特性 { //USART_send_str(\"清除特性\\r\\n\"); send_len_ep0 = 0; need_0_pack_ep0 = 1; USB_ep0_send();//发送数据 } break; case 5://设置地址 { USART_send_str(\"设置地址\\r\\n\"); //USART_send_HEX(w_value&0xFF); //USART_send_str(\"\\r\\n\"); usb_status = 1;//表示主机设置了地址 usb_addr = w_value & 0xFF; send_len_ep0 = 0; need_0_pack_ep0 = 1; USB_ep0_send();//发送数据 } break; case 9://设置配置 { USART_send_str(\"设置配置\\r\\n\"); //设置RX Valid .【端点1】可用于接收 { u16 t = EP1REG; t &= 0x8F8F;//1000 1111 1000 1111 把 t位都设置为0 t |= 0x8080;//1000 0000 1000 0000 把w0位都设置为1 t |= 0x3000;//0011 0000 0000 0000 把 SRAT_RX[1:0]设置为1 EP1REG = t; } send_len_ep0 = 0; need_0_pack_ep0 = 1; USB_ep0_send();//发送剩余数据 usb_status = 3; } break; case 7://设置描述符 { //USART_send_str(\"设置描述符\\r\\n\"); } break; case 3://设置特性 { //USART_send_str(\"设置特性\\r\\n\"); } break; case 11://设置接口 { //USART_send_str(\"设置接口\\r\\n\"); } break; default://出错 { //USART_send_str(\"标准输出请求代码出错\\r\\n\"); } break; } } break; case 1://类请求 { //USART_send_str(\"USB类输出请求:\"); switch(req) { case 0x0A: { USART_send_str(\"设置空闲\\r\\n\"); send_len_ep0 = 0; need_0_pack_ep0 = 1; USB_ep0_send();//发送剩余数据 } break; default: { #ifdef HEEY_DEBUG //UART_send_str(\"未知请求\\r\\n\"); #endif } break; } } break; } } } case 2://厂商请求 { //USART_send_str(\"厂商输出请求\\r\\n\"); } break; case 3://保留 { //USART_send_str(\"输出请求:保留\\r\\n\"); } break; //描述符的话用数组实现的这里就不给出来。 源程序的kile 4 - arm写的,可以向我要。奋斗STM32迷你板应该下载后可以直接使用。 上位机软件使用vb。 一下是枚举过程 USB断开 USB连接 【U】【S】【B】【复】【位】【中】【断】 【U】【S】【B】【复】【位】【中】【断】 端点0【SETUP】分组接收完成 端点0读取【8】字节数据: -------------------------------------------------------------------------------- 0x80 0x06 0x00 0x01 0x00 0x00 0x40 0x00 -------------------------------------------------------------------------------- USB标准输入请求:获取描述符——设备描述符 端点0发送【18】字节数据: ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 0x12 0x01 0x10 0x01 0x00 0x00 0x00 0x40 0xAA 0xAA 0x02 0x00 0x00 0x01 0x00 0x00 0x00 0x01 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 0x62 0x60 tx=2 tx2=3 rx=2 rx2=3 ****************端点0的IN分组发送完成**************** rx=0 rx2=0 端点0的【OUT】分组接收完成 端点0读取【0】字节数据: -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- rx=0 rx2=0 【U】【S】【B】【复】【位】【中】【断】 端点0【SETUP】分组接收完成 端点0读取【8】字节数据: -------------------------------------------------------------------------------- 0x00 0x05 0x16 0x00 0x00 0x00 0x00 0x00 -------------------------------------------------------------------------------- USB标准输出请求:设置地址。地址为:0x16 端点0发送【0】字节数据: ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 0x62 0x60 tx=2 tx2=3 rx=2 rx2=3 ****************端点0的IN分组发送完成**************** ========写入地址完成======== rx=3 rx2=3 端点0【SETUP】分组接收完成 端点0读取【8】字节数据: -------------------------------------------------------------------------------- 0x80 0x06 0x00 0x01 0x00 0x00 0x12 0x00 -------------------------------------------------------------------------------- USB标准输入请求:获取描述符——设备描述符 端点0发送【18】字节数据: ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 0x12 0x01 0x10 0x01 0x00 0x00 0x00 0x40 0xAA 0xAA 0x02 0x00 0x00 0x01 0x00 0x00 0x00 0x01 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 0x62 0x60 tx=2 tx2=3 rx=2 rx2=3 端点0的【OUT】分组接收完成 端点0读取【8】字节数据: -------------------------------------------------------------------------------- 0x80 0x06 0x00 0x02 0x00 0x00 0x09 0x00 -------------------------------------------------------------------------------- rx=2 rx2=3 端点0【SETUP】分组接收完成 端点0读取【8】字节数据: -------------------------------------------------------------------------------- 0x80 0x06 0x00 0x02 0x00 0x00 0x09 0x00 -------------------------------------------------------------------------------- USB标准输入请求:获取描述符——配置描述符 端点0发送【9】字节数据: ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 0x09 0x02 0x29 0x00 0x01 0x01 0x00 0x80 0x32 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 0x72 0xE0 tx=2 tx2=3 rx=3 rx2=3 端点0的【OUT】分组接收完成 端点0读取【8】字节数据: -------------------------------------------------------------------------------- 0x80 0x06 0x00 0x02 0x00 0x00 0xFF 0x00 -------------------------------------------------------------------------------- rx=2 rx2=3 端点0【SETUP】分组接收完成 端点0读取【8】字节数据: -------------------------------------------------------------------------------- 0x80 0x06 0x00 0x02 0x00 0x00 0xFF 0x00 -------------------------------------------------------------------------------- USB标准输入请求:获取描述符——配置描述符 端点0发送【41】字节数据: ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 0x09 0x02 0x29 0x00 0x01 0x01 0x00 0x80 0x32 0x09 0x04 0x00 0x00 0x02 0x03 0x00 0x00 0x00 0x09 0x21 0x10 0x01 0x21 0x01 0x22 0x1B 0x00 0x07 0x05 0x81 0x03 0x40 0x00 0x0A 0x07 0x05 0x01 0x03 0x40 0x00 0x0A ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 0x72 0xE0 tx=2 tx2=3 rx=3 rx2=3 ****************端点0的IN分组发送完成**************** rx=2 rx2=3 端点0的【OUT】分组接收完成 端点0读取【0】字节数据: -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- rx=2 rx2=3 端点0【SETUP】分组接收完成 端点0读取【8】字节数据: -------------------------------------------------------------------------------- 0x80 0x06 0x00 0x01 0x00 0x00 0x12 0x00 -------------------------------------------------------------------------------- USB标准输入请求:获取描述符——设备描述符 端点0发送【18】字节数据: ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 0x12 0x01 0x10 0x01 0x00 0x00 0x00 0x40 0xAA 0xAA 0x02 0x00 0x00 0x01 0x00 0x00 0x00 0x01 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 0x72 0x60 tx=2 tx2=3 rx=3 rx2=2 端点0的【OUT】分组接收完成 端点0读取【8】字节数据: -------------------------------------------------------------------------------- 0x80 0x06 0x00 0x02 0x00 0x00 0x09 0x00 -------------------------------------------------------------------------------- rx=2 rx2=3 端点0【SETUP】分组接收完成 端点0读取【8】字节数据: -------------------------------------------------------------------------------- 0x80 0x06 0x00 0x02 0x00 0x00 0x09 0x00 -------------------------------------------------------------------------------- USB标准输入请求:获取描述符——配置描述符 端点0发送【9】字节数据: ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 0x09 0x02 0x29 0x00 0x01 0x01 0x00 0x80 0x32 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 0x72 0xE0 tx=2 tx2=3 rx=3 rx2=3 端点0的【OUT】分组接收完成 端点0读取【8】字节数据: -------------------------------------------------------------------------------- 0x80 0x06 0x00 0x02 0x00 0x00 0x29 0x00 -------------------------------------------------------------------------------- rx=2 rx2=3 端点0【SETUP】分组接收完成 端点0读取【8】字节数据: -------------------------------------------------------------------------------- 0x80 0x06 0x00 0x02 0x00 0x00 0x29 0x00 -------------------------------------------------------------------------------- USB标准输入请求:获取描述符——配置描述符 端点0发送【41】字节数据: ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 0x09 0x02 0x29 0x00 0x01 0x01 0x00 0x80 0x32 0x09 0x04 0x00 0x00 0x02 0x03 0x00 0x00 0x00 0x09 0x21 0x10 0x01 0x21 0x01 0x22 0x1B 0x00 0x07 0x05 0x81 0x03 0x40 0x00 0x0A 0x07 0x05 0x01 0x03 0x40 0x00 0x0A ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 0x72 0xE0 tx=2 tx2=3 rx=3 rx2=2 端点0的【OUT】分组接收完成 端点0读取【8】字节数据: -------------------------------------------------------------------------------- 0x00 0x09 0x01 0x00 0x00 0x00 0x00 0x00 -------------------------------------------------------------------------------- rx=2 rx2=3 端点0【SETUP】分组接收完成 端点0读取【8】字节数据: -------------------------------------------------------------------------------- 0x00 0x09 0x01 0x00 0x00 0x00 0x00 0x00 -------------------------------------------------------------------------------- USB标准输出请求:设置配置 端点0发送【0】字节数据: ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 0x72 0xE0 tx=2 tx2=3 rx=3 rx2=3 ****************端点0的IN分组发送完成**************** rx=3 rx2=3 端点0【SETUP】分组接收完成 端点0读取【8】字节数据: -------------------------------------------------------------------------------- 0x21 0x0A 0x00 0x00 0x00 0x00 0x00 0x00 -------------------------------------------------------------------------------- USB类请求:端点0发送【0】字节数据: ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 0x62 0x60 tx=2 tx2=3 rx=2 rx2=3 ****************端点0的IN分组发送完成**************** rx=2 rx2=3 端点0【SETUP】分组接收完成 端点0读取【8】字节数据: -------------------------------------------------------------------------------- 0x81 0x06 0x00 0x22 0x00 0x00 0x5B 0x00 -------------------------------------------------------------------------------- USB标准输入请求:获取描述符——报告描述符 端点0发送【27】字节数据: ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 0x05 0x01 0x09 0x00 0xA1 0x01 0x15 0x00 0x25 0xFF 0x19 0x01 0x29 0x08 0x95 0x08 0x75 0x08 0x81 0x02 0x19 0x01 0x29 0x08 0x91 0x02 0xC0 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 0x72 0x60 tx=2 tx2=3 rx=3 rx2=3 ****************端点0的IN分组发送完成**************** rx=2 rx2=3 端点0的【OUT】分组接收完成 端点0读取【0】字节数据: -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- //////////////////////////自此枚举完成,下面是端点1通信 rx=3 rx2=3 端点1数据完成传输 端点1读取【8】字节数据: -------------------------------------------------------------------------------- 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08 -------------------------------------------------------------------------------- rx=3 rx2=3 上位 机 因篇幅问题不能全部显示,请点此查看更多更全内容