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

📄 usbcore.lst

📁 此代码为USB键盘开发的相关源代码
💻 LST
📖 第 1 页 / 共 4 页
字号:
 552          ********************************************************************/
 553          void UsbConnect(void)
 554          {
 555   1      #ifdef DEBUG0
 556   1       Prints("连接USB。\r\n");
 557   1      #endif
 558   1       D12WriteCommand(D12_SET_MODE);  //写设置模式命令
 559   1       D12WriteByte(0x16); //设置模式的第一字节
 560   1       D12WriteByte(0x47); //设置模式的第二字节
 561   1      }
 562          ////////////////////////End of function//////////////////////////////
 563          
 564          /********************************************************************
 565          函数功能:总线挂起中断处理函数。
 566          入口参数:无。
 567          返    回:无。
 568          备    注:无。
 569          ********************************************************************/
 570          void UsbBusSuspend(void)
 571          {
 572   1      #ifdef DEBUG0
 573   1       Prints("USB总线挂起。\r\n");
 574   1      #endif
 575   1      }
 576          ////////////////////////End of function//////////////////////////////
 577          
 578          /********************************************************************
 579          函数功能:总线复位中断处理函数。
 580          入口参数:无。
 581          返    回:无。
 582          备    注:无。
 583          ********************************************************************/
 584          void UsbBusReset(void)
 585          {
 586   1      #ifdef DEBUG0
 587   1       Prints("USB总线复位。\r\n");
 588   1      #endif
 589   1       Ep1InIsBusy=0; //复位后端点1输入缓冲区空闲。
 590   1      }
 591          ////////////////////////End of function//////////////////////////////
 592          
 593          /********************************************************************
 594          函数功能:根据pData和SendLength将数据发送到端点0的函数。
 595          入口参数:无。
 596          返    回:无。
 597          备    注:无。
 598          ********************************************************************/
 599          void UsbEp0SendData(void)
 600          {
 601   1       //将数据写到端点中去准备发送
 602   1       //写之前要先判断一下需要发送的数据是否比端点0
 603   1       //最大长度大,如果超过端点大小,则一次只能发送
 604   1       //最大包长的数据。端点0的最大包长在DeviceDescriptor[7]
 605   1       if(SendLength>DeviceDescriptor[7])
 606   1       {
 607   2        //按最大包长度发送
 608   2        D12WriteEndpointBuffer(1,DeviceDescriptor[7],pSendData);
 609   2        //发送后剩余字节数减少最大包长
 610   2        SendLength-=DeviceDescriptor[7];
 611   2        //发送一次后指针位置要调整
 612   2        pSendData+= DeviceDescriptor[7];
 613   2       }
C51 COMPILER V7.06   USBCORE                                                               11/16/2008 16:00:31 PAGE 11  

 614   1       else
 615   1       {
 616   2        if(SendLength!=0)
 617   2        {
 618   3         //不够最大包长,可以直接发送
 619   3         D12WriteEndpointBuffer(1,SendLength,pSendData);
 620   3         //发送完毕后,SendLength长度变为0
 621   3         SendLength=0;
 622   3        }
 623   2        else //如果要发送的数据包长度为0
 624   2        {
 625   3         if(NeedZeroPacket==1) //如果需要发送0长度数据
 626   3         {
 627   4          D12WriteEndpointBuffer(1,0,pSendData); //发送0长度数据包
 628   4          NeedZeroPacket=0; //清需要发送0长度数据包标志
 629   4         }
 630   3        }
 631   2       }
 632   1      }
 633          ////////////////////////End of function//////////////////////////////
 634          
 635          /********************************************************************
 636          函数功能:端点0输出中断处理函数。
 637          入口参数:无。
 638          返    回:无。
 639          备    注:无。
 640          ********************************************************************/
 641          void UsbEp0Out(void)
 642          {
 643   1      #ifdef DEBUG0
 644   1       Prints("USB端点0输出中断。\r\n");
 645   1      #endif
 646   1       //读取端点0输出最后传输状态,该操作清除中断标志
 647   1       //并判断第5位是否为1,如果是,则说明是建立包
 648   1       if(D12ReadEndpointLastStatus(0)&0x20)
 649   1       {
 650   2        D12ReadEndpointBuffer(0,16,Buffer); //读建立过程数据
 651   2        D12AcknowledgeSetup(); //应答建立包
 652   2        D12ClearBuffer(); //清缓冲区
 653   2        //将缓冲数据填到设备请求的各字段中
 654   2        bmRequestType=Buffer[0];
 655   2        bRequest=Buffer[1];
 656   2        wValue=Buffer[2]+(((uint16)Buffer[3])<<8);
 657   2        wIndex=Buffer[4]+(((uint16)Buffer[5])<<8);
 658   2        wLength=Buffer[6]+(((uint16)Buffer[7])<<8);
 659   2        //下面的代码判断具体的请求,并根据不同的请求进行相关操作
 660   2        //如果D7位为1,则说明是输入请求
 661   2        if((bmRequestType&0x80)==0x80)
 662   2        {
 663   3         //根据bmRequestType的D6~5位散转,D6~5位表示请求的类型
 664   3         //0为标准请求,1为类请求,2为厂商请求。
 665   3         switch((bmRequestType>>5)&0x03)
 666   3         {
 667   4          case 0:  //标准请求
 668   4           #ifdef DEBUG0
 669   4            Prints("USB标准输入请求:");
 670   4           #endif
 671   4           //USB协议定义了几个标准输入请求,我们实现这些标准请求即可
 672   4           //请求的代码在bRequest中,对不同的请求代码进行散转
 673   4           //事实上,我们还需要对接收者进行散转,因为不同的请求接收者
 674   4           //是不一样的。接收者在bmRequestType的D4~D0位中定义。
 675   4           //我们这里为了简化操作,有些就省略了对接收者的判断。
C51 COMPILER V7.06   USBCORE                                                               11/16/2008 16:00:31 PAGE 12  

 676   4           //例如获取描述符的请求,只根据描述符的类型来区别。
 677   4           switch(bRequest)
 678   4           {
 679   5            case GET_CONFIGURATION: //获取配置
 680   5             #ifdef DEBUG0
 681   5              Prints("获取配置。\r\n");
 682   5             #endif
 683   5            break;
 684   5            
 685   5            case GET_DESCRIPTOR:  //获取描述符
 686   5             #ifdef DEBUG0
 687   5              Prints("获取描述符——");
 688   5             #endif
 689   5             //对描述符类型进行散转,对于全速设备,
 690   5             //标准请求只支持发送到设备的设备、配置、字符串三种描述符
 691   5             switch((wValue>>8)&0xFF)
 692   5              {
 693   6               case DEVICE_DESCRIPTOR: //设备描述符
 694   6                #ifdef DEBUG0
 695   6                 Prints("设备描述符。\r\n");
 696   6                #endif
 697   6                pSendData=DeviceDescriptor;  //需要发送的数据
 698   6                //判断请求的字节数是否比实际需要发送的字节数多
 699   6                //这里请求的是设备描述符,因此数据长度就是
 700   6                //DeviceDescriptor[0]。如果请求的比实际的长,
 701   6                //那么只返回实际长度的数据
 702   6                if(wLength>DeviceDescriptor[0])
 703   6                {
 704   7                 SendLength=DeviceDescriptor[0];
 705   7                 if(SendLength%DeviceDescriptor[7]==0) //并且刚好是整数个数据包时
 706   7                 {
 707   8                  NeedZeroPacket=1; //需要返回0长度的数据包
 708   8                 }
 709   7                }
 710   6                else
 711   6                {
 712   7                 SendLength=wLength;
 713   7                }
 714   6                //将数据通过EP0返回
 715   6                UsbEp0SendData();
 716   6               break;
 717   6               
 718   6               case CONFIGURATION_DESCRIPTOR:  //配置描述符
 719   6                #ifdef DEBUG0
 720   6                 Prints("配置描述符。\r\n");
 721   6                #endif
 722   6                pSendData=ConfigurationDescriptor; //需要发送的数据为配置描述符
 723   6                //判断请求的字节数是否比实际需要发送的字节数多
 724   6                //这里请求的是配置描述符集合,因此数据长度就是
 725   6                //ConfigurationDescriptor[3]*256+ConfigurationDescriptor[2]。
 726   6                //如果请求的比实际的长,那么只返回实际长度的数据
 727   6                SendLength=ConfigurationDescriptor[3];
 728   6                SendLength=SendLength*256+ConfigurationDescriptor[2];
 729   6                if(wLength>SendLength)
 730   6                {
 731   7                 if(SendLength%DeviceDescriptor[7]==0) //并且刚好是整数个数据包时
 732   7                 {
 733   8                  NeedZeroPacket=1; //需要返回0长度的数据包
 734   8                 }
 735   7                }
 736   6                else
 737   6                {
C51 COMPILER V7.06   USBCORE                                                               11/16/2008 16:00:31 PAGE 13  

 738   7                 SendLength=wLength;
 739   7                }
 740   6                //将数据通过EP0返回
 741   6                UsbEp0SendData();
 742   6               break;
 743   6               
 744   6               case STRING_DESCRIPTOR:  //字符串描述符
 745   6                #ifdef DEBUG0
 746   6                 Prints("字符串描述符");
 747   6                #endif
 748   6                switch(wValue&0xFF)  //根据wValue的低字节(索引值)散转
 749   6                {
 750   7                 case 0:  //获取语言ID
 751   7                  #ifdef DEBUG0
 752   7                   Prints("(语言ID)。\r\n");
 753   7                  #endif
 754   7                  pSendData=LanguageId;
 755   7                  SendLength=LanguageId[0];
 756   7                 break;
 757   7                 
 758   7                 case 1:  //厂商字符串的索引值为1,所以这里为厂商字符串
 759   7                 #ifdef DEBUG0
 760   7                   Prints("(厂商描述)。\r\n");
 761   7                  #endif
 762   7                  pSendData=ManufacturerStringDescriptor;
 763   7                  SendLength=ManufacturerStringDescriptor[0];
 764   7                 break;
 765   7                 
 766   7                 case 2:  //产品字符串的索引值为2,所以这里为产品字符串
 767   7                 #ifdef DEBUG0
 768   7                   Prints("(产品描述)。\r\n");
 769   7                  #endif
 770   7                  pSendData=ProductStringDescriptor;
 771   7                  SendLength=ProductStringDescriptor[0];
 772   7                 break;
 773   7                 
 774   7                 case 3:  //产品序列号的索引值为3,所以这里为序列号
 775   7                 #ifdef DEBUG0
 776   7                   Prints("(产品序列号)。\r\n");
 777   7                  #endif
 778   7                  pSendData=SerialNumberStringDescriptor;
 779   7                  SendLength=SerialNumberStringDescriptor[0];
 780   7                 break;
 781   7                 
 782   7                 default :
 783   7                  #ifdef DEBUG0
 784   7                   Prints("(未知的索引值)。\r\n");
 785   7                  #endif
 786   7                  //对于未知索引值的请求,返回一个0长度的包
 787   7                  SendLength=0;
 788   7                  NeedZeroPacket=1;
 789   7                 break;
 790   7                }
 791   6                //判断请求的字节数是否比实际需要发送的字节数多
 792   6                //如果请求的比实际的长,那么只返回实际长度的数据
 793   6                if(wLength>SendLength)
 794   6                {
 795   7                 if(SendLength%DeviceDescriptor[7]==0) //并且刚好是整数个数据包时
 796   7                 {
 797   8                  NeedZeroPacket=1; //需要返回0长度的数据包
 798   8                 }
 799   7                }
C51 COMPILER V7.06   USBCORE                                                               11/16/2008 16:00:31 PAGE 14  

 800   6                else
 801   6                {
 802   7                 SendLength=wLength;
 803   7                }
 804   6                //将数据通过EP0返回
 805   6                UsbEp0SendData();         
 806   6               break;
 807   6      
 808   6               case REPORT_DESCRIPTOR:  //报告描述符
 809   6                #ifdef DEBUG0
 810   6                 Prints("报告描述符。\r\n");
 811   6                #endif
 812   6                pSendData=ReportDescriptor; //需要发送的数据为报告描述符
 813   6                SendLength=sizeof(ReportDescriptor); //需要返回的数据长度         
 814   6                //判断请求的字节数是否比实际需要发送的字节数多
 815   6                //如果请求的比实际的长,那么只返回实际长度的数据
 816   6                if(wLength>SendLength)
 817   6                {
 818   7                 if(SendLength%DeviceDescriptor[7]==0) //并且刚好是整数个数据包时
 819   7                 {
 820   8                  NeedZeroPacket=1; //需要返回0长度的数据包
 821   8                 }
 822   7                }
 823   6                else
 824   6                {
 825   7                 SendLength=wLength;
 826   7                }
 827   6                //将数据通过EP0返回
 828   6                UsbEp0SendData();
 829   6               break;
 830   6                       
 831   6               default:  //其它描述符
 832   6                #ifdef DEBUG0

⌨️ 快捷键说明

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