⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 usbcore.lst

📁 单片机上实现U盘功能
💻 LST
📖 第 1 页 / 共 4 页
字号:
 498   2        //如果D7位为1,则说明是输入请求
 499   2        if((bmRequestType&0x80)==0x80)
 500   2        {
 501   3         //根据bmRequestType的D6~5位散转,D6~5位表示请求的类型
 502   3         //0为标准请求,1为类请求,2为厂商请求。
 503   3         switch((bmRequestType>>5)&0x03)
 504   3         {
 505   4          case 0:  //标准请求
 506   4           #ifdef DEBUG0
                    Prints("USB标准输入请求:");
                   #endif
 509   4           //USB协议定义了几个标准输入请求,我们实现这些标准请求即可
 510   4           //请求的代码在bRequest中,对不同的请求代码进行散转
 511   4           //事实上,我们还需要对接收者进行散转,因为不同的请求接收者
 512   4           //是不一样的。接收者在bmRequestType的D4~D0位中定义。
 513   4           //我们这里为了简化操作,有些就省略了对接收者的判断。
 514   4           //例如获取描述符的请求,只根据描述符的类型来区别。
 515   4           switch(bRequest)
 516   4           {
 517   5            case GET_CONFIGURATION: //获取配置
 518   5             #ifdef DEBUG0
                      Prints("获取配置。\r\n");
                     #endif
 521   5            break;
 522   5            
 523   5            case GET_DESCRIPTOR:  //获取描述符
 524   5             #ifdef DEBUG0
                      Prints("获取描述符——");
                     #endif
 527   5             //对描述符类型进行散转,对于全速设备,
 528   5             //标准请求只支持发送到设备的设备、配置、字符串三种描述符
 529   5             switch((wValue>>8)&0xFF)
 530   5              {
 531   6               case DEVICE_DESCRIPTOR: //设备描述符
 532   6                #ifdef DEBUG0
                         Prints("设备描述符。\r\n");
                        #endif
 535   6                pSendData=DeviceDescriptor;  //需要发送的数据
 536   6                //判断请求的字节数是否比实际需要发送的字节数多
 537   6                //这里请求的是设备描述符,因此数据长度就是
 538   6                //DeviceDescriptor[0]。如果请求的比实际的长,
 539   6                //那么只返回实际长度的数据
 540   6                if(wLength>DeviceDescriptor[0])
 541   6                {
 542   7                 SendLength=DeviceDescriptor[0];
 543   7                 if(SendLength%DeviceDescriptor[7]==0) //并且刚好是整数个数据包时
 544   7                 {
 545   8                  NeedZeroPacket=1; //需要返回0长度的数据包
 546   8                 }
 547   7                }
 548   6                else
 549   6                {
 550   7                 SendLength=wLength;
 551   7                }
C51 COMPILER V7.06   USBCORE                                                               11/16/2008 16:00:19 PAGE 10  

 552   6                //将数据通过EP0返回
 553   6                UsbEp0SendData();
 554   6               break;
 555   6               
 556   6               case CONFIGURATION_DESCRIPTOR:  //配置描述符
 557   6                #ifdef DEBUG0
                         Prints("配置描述符。\r\n");
                        #endif
 560   6                pSendData=ConfigurationDescriptor; //需要发送的数据为配置描述符
 561   6                //判断请求的字节数是否比实际需要发送的字节数多
 562   6                //这里请求的是配置描述符集合,因此数据长度就是
 563   6                //ConfigurationDescriptor[3]*256+ConfigurationDescriptor[2]。
 564   6                //如果请求的比实际的长,那么只返回实际长度的数据
 565   6                SendLength=ConfigurationDescriptor[3];
 566   6                SendLength=SendLength*256+ConfigurationDescriptor[2];
 567   6                if(wLength>SendLength)
 568   6                {
 569   7                 if(SendLength%DeviceDescriptor[7]==0) //并且刚好是整数个数据包时
 570   7                 {
 571   8                  NeedZeroPacket=1; //需要返回0长度的数据包
 572   8                 }
 573   7                }
 574   6                else
 575   6                {
 576   7                 SendLength=wLength;
 577   7                }
 578   6                //将数据通过EP0返回
 579   6                UsbEp0SendData();
 580   6               break;
 581   6               
 582   6               case STRING_DESCRIPTOR:  //字符串描述符
 583   6                #ifdef DEBUG0
                         Prints("字符串描述符");
                        #endif
 586   6                switch(wValue&0xFF)  //根据wValue的低字节(索引值)散转
 587   6                {
 588   7                 case 0:  //获取语言ID
 589   7                  #ifdef DEBUG0
                           Prints("(语言ID)。\r\n");
                          #endif
 592   7                  pSendData=LanguageId;
 593   7                  SendLength=LanguageId[0];
 594   7                 break;
 595   7                 
 596   7                 case 1:  //厂商字符串的索引值为1,所以这里为厂商字符串
 597   7                 #ifdef DEBUG0
                           Prints("(厂商描述)。\r\n");
                          #endif
 600   7                  pSendData=ManufacturerStringDescriptor;
 601   7                  SendLength=ManufacturerStringDescriptor[0];
 602   7                 break;
 603   7                 
 604   7                 case 2:  //产品字符串的索引值为2,所以这里为产品字符串
 605   7                 #ifdef DEBUG0
                           Prints("(产品描述)。\r\n");
                          #endif
 608   7                  pSendData=ProductStringDescriptor;
 609   7                  SendLength=ProductStringDescriptor[0];
 610   7                 break;
 611   7                 
 612   7                 case 3:  //产品序列号的索引值为3,所以这里为序列号
 613   7                 #ifdef DEBUG0
C51 COMPILER V7.06   USBCORE                                                               11/16/2008 16:00:19 PAGE 11  

                           Prints("(产品序列号)。\r\n");
                          #endif
 616   7                  pSendData=SerialNumberStringDescriptor;
 617   7                  SendLength=SerialNumberStringDescriptor[0];
 618   7                 break;
 619   7                 
 620   7                 default :
 621   7                  #ifdef DEBUG0
                           Prints("(未知的索引值)。\r\n");
                          #endif
 624   7                  //对于未知索引值的请求,返回一个0长度的包
 625   7                  SendLength=0;
 626   7                  NeedZeroPacket=1;
 627   7                 break;
 628   7                }
 629   6                //判断请求的字节数是否比实际需要发送的字节数多
 630   6                //如果请求的比实际的长,那么只返回实际长度的数据
 631   6                if(wLength>SendLength)
 632   6                {
 633   7                 if(SendLength%DeviceDescriptor[7]==0) //并且刚好是整数个数据包时
 634   7                 {
 635   8                  NeedZeroPacket=1; //需要返回0长度的数据包
 636   8                 }
 637   7                }
 638   6                else
 639   6                {
 640   7                 SendLength=wLength;
 641   7                }
 642   6                //将数据通过EP0返回
 643   6                UsbEp0SendData();         
 644   6               break;
 645   6      
 646   6               case REPORT_DESCRIPTOR:  //报告描述符
 647   6                #ifdef DEBUG0
                         Prints("报告描述符。\r\n");
                        #endif
 650   6               break;
 651   6                       
 652   6               default:  //其它描述符
 653   6                #ifdef DEBUG0
                         Prints("其他描述符,描述符代码:");
                         PrintHex((wValue>>8)&0xFF);
                         Prints("\r\n");
                        #endif
 658   6               break;
 659   6              }
 660   5             break;
 661   5            
 662   5            case GET_INTERFACE: //获取接口
 663   5             #ifdef DEBUG0
                      Prints("获取接口。\r\n");
                     #endif
 666   5            break;
 667   5            
 668   5            case GET_STATUS: //获取状态
 669   5             #ifdef DEBUG0
                      Prints("获取状态。\r\n");
                     #endif
 672   5            break;
 673   5            
 674   5            case SYNCH_FRAME: //同步帧
 675   5             #ifdef DEBUG0
C51 COMPILER V7.06   USBCORE                                                               11/16/2008 16:00:19 PAGE 12  

                      Prints("同步帧。\r\n");
                     #endif
 678   5            break;
 679   5            
 680   5            default:  //未定义的标准请求
 681   5             #ifdef DEBUG0
                      Prints("错误:未定义的标准输入请求。\r\n");
                     #endif       
 684   5            break;
 685   5           }
 686   4          break;
 687   4          
 688   4          case 1:  //类请求
 689   4           #ifdef DEBUG0
                    Prints("USB类输入请求:");
                   #endif
 692   4           switch(bRequest)
 693   4           {
 694   5            case GET_MAX_LUN: //请求为GET_MAX_LUN(0xFE)
 695   5             #ifdef DEBUG0
                      Prints("获取最大逻辑单元。\r\n");
                     #endif
 698   5             
 699   5             pSendData=MaxLun; //要返回的数据位置
 700   5             SendLength=1;     //长度为1字节
 701   5             //如果请求的长度比实际长度短,则仅返回请求长度
 702   5             if(wLength<SendLength) 
 703   5             {
 704   6              SendLength=wLength;
 705   6             }
 706   5             //将数据通过EP0返回
 707   5             UsbEp0SendData();
 708   5            break;
 709   5            
 710   5            default:
 711   5             #ifdef DEBUG0
                      Prints("未知请求。\r\n");
                     #endif
 714   5            break;
 715   5           }
 716   4          break;
 717   4          
 718   4          case 2:  //厂商请求
 719   4           #ifdef DEBUG0
                    Prints("USB厂商输入请求:\r\n");
                   #endif
 722   4          break;
 723   4          
 724   4          default: //未定义的请求。这里只显示一个报错信息。
 725   4           #ifdef DEBUG0
                    Prints("错误:未定义的输入请求。\r\n");
                   #endif
 728   4          break;
 729   4         }
 730   3        }
 731   2        //否则说明是输出请求
 732   2        else //if(bmRequestType&0x80==0x80)之else
 733   2        {
 734   3         //根据bmRequestType的D6~5位散转,D6~5位表示请求的类型
 735   3         //0为标准请求,1为类请求,2为厂商请求。
 736   3         switch((bmRequestType>>5)&0x03)
 737   3         {
C51 COMPILER V7.06   USBCORE                                                               11/16/2008 16:00:19 PAGE 13  

 738   4          case 0:  //标准请求
 739   4           #ifdef DEBUG0
                    Prints("USB标准输出请求:");
                   #endif
 742   4           //USB协议定义了几个标准输出请求,我们实现这些标准请求即可
 743   4           //请求的代码在bRequest中,对不同的请求代码进行散转
 744   4           switch(bRequest)
 745   4           {
 746   5            case CLEAR_FEATURE: //清除特性
 747   5             #ifdef DEBUG0
                      Prints("清除特性。\r\n");
                     #endif
 750   5            break;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -