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

📄 usbcore.lst

📁 单片机上实现USB转串口程序
💻 LST
📖 第 1 页 / 共 4 页
字号:
 588   2        {
 589   3         if(NeedZeroPacket==1) //如果需要发送0长度数据
 590   3         {
 591   4          D12WriteEndpointBuffer(1,0,pSendData); //发送0长度数据包
 592   4          NeedZeroPacket=0; //清需要发送0长度数据包标志
 593   4         }
 594   3        }
 595   2       }
 596   1      }
 597          ////////////////////////End of function//////////////////////////////
 598          
 599          /********************************************************************
 600          函数功能:USB端点0数据过程数据处理函数。
 601          入口参数:无。
 602          返    回:无。
 603          备    注:该函数用来处理0端点控制传输的数据或状态过程。
 604          ********************************************************************/
 605          void UsbEp0DataOut(void)
 606          {
 607   1       //由于本程序中只有一个请求输出数据,所以可以直接使用if语句判断条件,
 608   1       //如果有很多请求的话,使用if语句就不方便了,而应该使用switch语句散转。
 609   1       if((bmRequestType==0x21)&&(bRequest==SET_LINE_CODING))
 610   1       {
 611   2        uint32 BitRate;
 612   2        uint8 Length;
 613   2        
C51 COMPILER V7.06   USBCORE                                                               11/16/2008 16:00:07 PAGE 11  

 614   2        //读回7字节的LineCoding值
 615   2        Length=D12ReadEndpointBuffer(0,7,LineCoding);
 616   2        D12ClearBuffer(); //清除缓冲区
 617   2        
 618   2        if(Length==7) //如果长度正确
 619   2        {
 620   3         //从LineCoding计算设置的波特率
 621   3         BitRate=LineCoding[3];
 622   3         BitRate=(BitRate<<8)+LineCoding[2];
 623   3         BitRate=(BitRate<<8)+LineCoding[1];
 624   3         BitRate=(BitRate<<8)+LineCoding[0];
 625   3        #ifdef DEBUG0
                 Prints("波特率设置为:");
                 PrintLongInt(BitRate);
                 Prints("bps\r\n");
                #endif
 630   3         //设置串口的波特率
 631   3         BitRate=UartSetBitRate(BitRate);
 632   3         
 633   3         //将LineCoding的值设置为实际的设置值
 634   3         LineCoding[0]=BitRate&0xFF;
 635   3         LineCoding[1]=(BitRate>>8)&0xFF;
 636   3         LineCoding[2]=(BitRate>>16)&0xFF;
 637   3         LineCoding[3]=(BitRate>>24)&0xFF;
 638   3        
 639   3         //由于只支持一停止位、无校验、8位数据位,
 640   3         //所以固定这些数据。
 641   3         LineCoding[4]=0x00;
 642   3         LineCoding[5]=0x00;
 643   3         LineCoding[6]=0x08;
 644   3        }
 645   2        //返回0长度的状态数据包。
 646   2        D12WriteEndpointBuffer(1,0,0);
 647   2       }
 648   1       else  //其它请求的数据过程或者状态过程
 649   1       {
 650   2        D12ReadEndpointBuffer(0,16,Buffer);
 651   2        D12ClearBuffer();
 652   2       }
 653   1      }
 654          ////////////////////////End of function//////////////////////////////
 655          
 656          /********************************************************************
 657          函数功能:端点0输出中断处理函数。
 658          入口参数:无。
 659          返    回:无。
 660          备    注:无。
 661          ********************************************************************/
 662          void UsbEp0Out(void)
 663          {
 664   1      #ifdef DEBUG0
               Prints("USB端点0输出中断。\r\n");
              #endif
 667   1       //读取端点0输出最后传输状态,该操作清除中断标志
 668   1       //并判断第5位是否为1,如果是,则说明是建立包
 669   1       if(D12ReadEndpointLastStatus(0)&0x20)
 670   1       {
 671   2        D12ReadEndpointBuffer(0,16,Buffer); //读建立过程数据
 672   2        D12AcknowledgeSetup(); //应答建立包
 673   2        D12ClearBuffer(); //清缓冲区
 674   2        //将缓冲数据填到设备请求的各字段中
 675   2        bmRequestType=Buffer[0];
C51 COMPILER V7.06   USBCORE                                                               11/16/2008 16:00:07 PAGE 12  

 676   2        bRequest=Buffer[1];
 677   2        wValue=Buffer[2]+(((uint16)Buffer[3])<<8);
 678   2        wIndex=Buffer[4]+(((uint16)Buffer[5])<<8);
 679   2        wLength=Buffer[6]+(((uint16)Buffer[7])<<8);
 680   2        //下面的代码判断具体的请求,并根据不同的请求进行相关操作
 681   2        //如果D7位为1,则说明是输入请求
 682   2        if((bmRequestType&0x80)==0x80)
 683   2        {
 684   3         //根据bmRequestType的D6~5位散转,D6~5位表示请求的类型
 685   3         //0为标准请求,1为类请求,2为厂商请求。
 686   3         switch((bmRequestType>>5)&0x03)
 687   3         {
 688   4          case 0:  //标准请求
 689   4           #ifdef DEBUG0
                    Prints("USB标准输入请求:");
                   #endif
 692   4           //USB协议定义了几个标准输入请求,我们实现这些标准请求即可
 693   4           //请求的代码在bRequest中,对不同的请求代码进行散转
 694   4           //事实上,我们还需要对接收者进行散转,因为不同的请求接收者
 695   4           //是不一样的。接收者在bmRequestType的D4~D0位中定义。
 696   4           //我们这里为了简化操作,有些就省略了对接收者的判断。
 697   4           //例如获取描述符的请求,只根据描述符的类型来区别。
 698   4           switch(bRequest)
 699   4           {
 700   5            case GET_CONFIGURATION: //获取配置
 701   5             #ifdef DEBUG0
                      Prints("获取配置。\r\n");
                     #endif
 704   5            break;
 705   5            
 706   5            case GET_DESCRIPTOR:  //获取描述符
 707   5             #ifdef DEBUG0
                      Prints("获取描述符——");
                     #endif
 710   5             //对描述符类型进行散转,对于全速设备,
 711   5             //标准请求只支持发送到设备的设备、配置、字符串三种描述符
 712   5             switch((wValue>>8)&0xFF)
 713   5              {
 714   6               case DEVICE_DESCRIPTOR: //设备描述符
 715   6                #ifdef DEBUG0
                         Prints("设备描述符。\r\n");
                        #endif
 718   6                pSendData=DeviceDescriptor;  //需要发送的数据
 719   6                //判断请求的字节数是否比实际需要发送的字节数多
 720   6                //这里请求的是设备描述符,因此数据长度就是
 721   6                //DeviceDescriptor[0]。如果请求的比实际的长,
 722   6                //那么只返回实际长度的数据
 723   6                if(wLength>DeviceDescriptor[0])
 724   6                {
 725   7                 SendLength=DeviceDescriptor[0];
 726   7                 if(SendLength%DeviceDescriptor[7]==0) //并且刚好是整数个数据包时
 727   7                 {
 728   8                  NeedZeroPacket=1; //需要返回0长度的数据包
 729   8                 }
 730   7                }
 731   6                else
 732   6                {
 733   7                 SendLength=wLength;
 734   7                }
 735   6                //将数据通过EP0返回
 736   6                UsbEp0SendData();
 737   6               break;
C51 COMPILER V7.06   USBCORE                                                               11/16/2008 16:00:07 PAGE 13  

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

 800   7                  SendLength=SerialNumberStringDescriptor[0];
 801   7                 break;
 802   7                 
 803   7                 default :
 804   7                  #ifdef DEBUG0
                           Prints("(未知的索引值)。\r\n");
                          #endif
 807   7                  //对于未知索引值的请求,返回一个0长度的包
 808   7                  SendLength=0;
 809   7                  NeedZeroPacket=1;
 810   7                 break;
 811   7                }
 812   6                //判断请求的字节数是否比实际需要发送的字节数多
 813   6                //如果请求的比实际的长,那么只返回实际长度的数据
 814   6                if(wLength>SendLength)
 815   6                {
 816   7                 if(SendLength%DeviceDescriptor[7]==0) //并且刚好是整数个数据包时
 817   7                 {
 818   8                  NeedZeroPacket=1; //需要返回0长度的数据包
 819   8                 }
 820   7                }
 821   6                else
 822   6                {
 823   7                 SendLength=wLength;
 824   7                }
 825   6                //将数据通过EP0返回
 826   6                UsbEp0SendData();         
 827   6               break;
 828   6                       
 829   6               default:  //其它描述符
 830   6                #ifdef DEBUG0
                         Prints("其他描述符,描述符代码:");
                         PrintHex((wValue>>8)&0xFF);
                         Prints("\r\n");
                        #endif
 835   6               break;
 836   6              }
 837   5             break;
 838   5            
 839   5            case GET_INTERFACE: //获取接口
 840   5             #ifdef DEBUG0
                      Prints("获取接口。\r\n");
                     #endif
 843   5            break;
 844   5            
 845   5            case GET_STATUS: //获取状态
 846   5             #ifdef DEBUG0
                      Prints("获取状态。\r\n");
                     #endif
 849   5            break;
 850   5            
 851   5            case SYNCH_FRAME: //同步帧
 852   5             #ifdef DEBUG0
                      Prints("同步帧。\r\n");
                     #endif
 855   5            break;
 856   5            
 857   5            default:  //未定义的标准请求
 858   5             #ifdef DEBUG0
                      Prints("错误:未定义的标准输入请求。\r\n");
                     #endif       
 861   5            break;
C51 COMPILER V7.06   USBCORE                                                               11/16/2008 16:00:07 PAGE 15  

 862   5           }
 863   4          break;
 864   4          
 865   4          case 1:  //类请求
 866   4           #ifdef DEBUG0
                    Prints("USB类输入请求:");
                   #endif
 869   4           switch(bRequest)
 870   4           {
 871   5            case GET_LINE_CODING: //GET_LINE_CODING请求
 872   5             #ifdef DEBUG0
                      Prints("GET_LINE_CODING。\r\n");
                     #endif
 875   5             SendLength=0x07; //7字节的LineCoding
 876   5             pSendData=LineCoding;
 877   5            break;
 878   5            
 879   5            case SERIAL_STATE: //获取SERIAL_STATE请求
 880   5             //本来该请求是获取串口状态的,但是圈圈在实际使用中,
 881   5             //发现主机从来未发送过该请求,因而这里并不对它进行处理,
 882   5             //只是简单地发送一个0长度的数据包。
 883   5             #ifdef DEBUG0
                      Prints("SERIAL_STATE。\r\n");

⌨️ 快捷键说明

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