CH374S读取键盘数据问题求助,盼复

用STM32+CH374S驱动USB键盘,出现一个非常奇怪的问题。刚烧写完程序(不断电)进去的可以正常读取键盘数据,也非常稳定。但如果断一次电再去读取键盘时发现就无法获取到数据了。

对比一下启动后调试信息,烧写后未断电重启,endp_in_addr = 01;如果断电后再重启发现endp_in_addr = 04。不知道这是什么情况,请版主指教,非常感谢!

 

int UsbKey(void)
{  
    UINT8   i, s,close_bit_flag=0;
 //由于报告描述符大小不定,缓冲区的大小最好定义大些
    UINT8   buf[80]; 
 // 等待CH374复位完成         
    mDelaymS( 50 ); 
 // CH374接口初始化
    CH374_PORT_INIT( );   
 // 初始化USB主机
    Init374Host( ); 
 //设置主机空闲
    HostSetBusFree( );
 // 由于USB设备刚插入尚未稳定,故等待USB设备数百毫秒,消除插拔抖动
    if(ch374_flag == 1)
    { 
     ch374_flag = 0;
     //while(1)
        //{  
        //    if ( Query374Interrupt( ) ) HostDetectInterrupt( ); 
        //    if ( Query374DeviceIn( ) ) break;      
        //}  
       mDelaymS( 10 );                                        
        if ( Query374Interrupt( ) ) HostDetectInterrupt( );      // 如果有USB主机中断则处理
  
        LCDprintf( "Reset Device\n" );  
        HostSetBusReset( );                                      // USB总线复位
        for ( i = 0; i < 100; i ++ )                             // 等待USB设备复位后重新连接
        {  
            if ( Query374DeviceIn( ) ) break;                    // 有USB设备
            mDelaymS( 1 );  
        }  
        if ( Query374Interrupt( ) ) HostDetectInterrupt( );      // 如果有USB主机中断则处理
        if ( Query374DeviceIn( ) )                               // 有USB设备
        {    
            if ( Query374DevFullSpeed( ) )  
            {  
                LCDprintf( "Start Full-Speed Device\n" );  
                HostSetFullSpeed( );                            // 检测到全速USB设备
                LOW_SPEED_BIT=0; 
            }  
            else   
            {  
                LCDprintf( "Start Low-Speed Device\n" );  
                HostSetLowSpeed( );                            // 检测到低速USB设备
                LOW_SPEED_BIT=1;  
            }  
        }  
        else   
        {  
            return -1;                                            // 设备已经断开,继续等待
        }  
        mDelaymS( 50 );  
        close_bit_flag=0;  
        LCDprintf( "GetDeviceDescr: " );  
        s = GetDeviceDescr( buf );                             // 获取设备描述符
        LCDprintf("device_status=%x \n",(unsigned short)s);  
        if ( s != USB_INT_SUCCESS )  
        {  
            goto WaitDeviceOut;                                // 终止操作,等待USB设备拔出
        }  
        for ( i = 0; i < ( (PUSB_SETUP_REQ)SetupGetDevDescr ) -> wLengthL; i ++ ) LCDprintf( "%x ", (UINT16)( buf[i] ) );  
        LCDprintf( "\n" );  
        s = SetUsbAddress( 0x02 );                             // 设置USB设备地址
        LCDprintf("address_status=%x\n",(unsigned short)s);  
        if ( s != USB_INT_SUCCESS )   
        {  
            goto WaitDeviceOut;                                 // 终止操作,等待USB设备拔出
        }  
        s = GetConfigDescr( buf );                             // 获取配置描述符
        LCDprintf("config_status=%x\n",(unsigned short)s);  
        if ( s != USB_INT_SUCCESS )   
        {  
            goto WaitDeviceOut;                                // ????,??USB????  
        }  
  
 // 分析配置描述符,获取端点数据/各端点地址/各端点大小等,更新变量endp_addr和endp_size等
   s = SetUsbConfig( ( (PUSB_CFG_DESCR)buf ) -> bConfigurationValue );   // 设置USB设备配置
        if ( s != USB_INT_SUCCESS )   
        {  
//          LCDprintf( "ERROR = %x\n", (UINT16)s );  
            goto WaitDeviceOut;                              // 终止操作,等待USB设备拔出
        }  
        else    LCDprintf( "SetUsbConfig_success\n" );  
  
 //-------------------------以下进行HID类的简单操作-----------------------------------------------------------
        LCDprintf("Set_Idle\n");  
        s=Set_Idle( );                                        //设置IDLE,这个步骤是按照HID类的协议来做的
        if(s!=USB_INT_SUCCESS)  
        {  
            LCDprintf("Set_Idle_Err=%x\n",(unsigned short)s);  
            if(s&0x0f==USB_INT_RET_STALL)  goto next_operate1; //返回STALL可能本身不支持
        }  
        else LCDprintf("Set_idle success\n");  
next_operate1:  
        LCDprintf("Get_Hid_Des\n");  
        s=Get_Hid_Des(buf);                                  // 获取报表描述符描述符
        if(s==USB_INT_SUCCESS)  
        {  
            LCDprintf("HID_Desc: ");  
            for(i=0;i!=hid_des_leng;i++)  LCDprintf("%x ",(unsigned short)buf[i]);  
            LCDprintf("\n");  
        }  
        else  
        {  
            goto WaitDeviceOut;                             //出错退出
        }  
  
        LCDprintf("Set_Report \n");                           
  //对于键盘发Set_Report来点亮灯,对于鼠标则不需要这一步
        buf[0]=0x01;  
        s=Set_Report(buf);                                 //设置报表
        if(s==USB_INT_SUCCESS)     
        {  
             LCDprintf("Set_Report success\n");  
        }  
        else  
        {   
              LCDprintf("Set_Report Err=%x\n",(unsigned short)s);       //设置报告出错
              if(s&0x0f==USB_INT_RET_STALL) 
      goto next_operate2;      //返回STALL可能本身不支持 
        }  
next_operate2:  
  // 下面开始读取数据
  //实际在读取数据的时候,
  //要先发送中断端点的令牌来读取数据,
  //接着才能获取到数据
  //LCD_Clear(0x001F);
    tog1=FALSE;          //开始取DATA0 
    while(1)  
    { 
     s=Interrupt_Data_Trans(buf);  
  //   printf("s:%x \n",(unsigned short)s);  
     if(s==USB_INT_SUCCESS) 
     { 
      for(i=0;i!=8;i++) LCDprintf("%02x ",(unsigned short)buf[i]);  
      LCDprintf("\n"); 
     } 
     else if(s==USB_INT_DISCONNECT)     //  这个是为了知道设备拔出产生的中断状态 
     { 
      close_bit_flag=1; 
      break;      
     } 
    } 

  
        return 0;
  
WaitDeviceOut:                                       //  这个是为了知道设备拔出产生的中断状态
        LCDprintf( "Wait Device Out\n" );  
  usbrst_flag = 1;
        if(close_bit_flag==0){  
            while ( 1 )  
            {  
                 if ( Query374Interrupt( ) ) HostDetectInterrupt( );  // 如果有USB主机中断则处理
                 if ( Query374DeviceIn( ) == FALSE ) break;           // 没有USB设备
            }  
        }  
        mDelaymS( 100 );                                             // 等待设备完全断开,消除插拔抖动
  return -2;      
 }
 else
     return -3;      
}

 

你好:
endp_in_addr 的数值来自你获取的完整“配置描述符”中的端点描述符,你自己检查一下,这个变量被赋值的情况,什么时候发生的变化就能找到问题了。


只有登录才能回复,可以选择微信账号登录