[求助] stm32驱动ch375b读usb条码枪能热插拔读不出条码请高手帮下什么地方错了

xs19820727   2014-12-3 22:14 楼主
#include "stm32f10x.h"
#include "stm32f10x_gpio.h"
#include "CH375.H"
#include
unsigned  char  ch,ch1,dat1;
UINT8 status;
GPIO_InitTypeDef GPIO_InitStructure;
  unsigned char a,temp3,temp4,num,i;
  unsigned char fs,tmpformt;
  unsigned char suju[32];
UINT8 data_buf[90];
unsigned char   flag_config_2; //第二次获取配置描述符标志
// 获取设备描述符
unsigned char SetupGetDevDescr[] = { 0x80, 0x06, 0x00, 0x01, 0x00, 0x00, 0x12, 0x00 };
// 获取配置描述符
unsigned char SetupGetCfgDescr[] = { 0x80, 0x06, 0x00, 0x02, 0x00, 0x00, 0x09, 0x00 };
// 设置USB地址
unsigned char SetupSetUsbAddr[] = { 0x00, 0x05, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00 };
// 设置USB配置
//const        unsigned char code SetupSetUsbConfig[] = { 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
// SET IDLE
unsigned char SetupSetidle[]={0x21,0x0a,0x00,0x00,0x00,0x00,0x00,0x00};        
// 获取HID 报告描述符
unsigned char SetupGetHidDes[]={0x81,0x06,0x00,0x22,0x00,0x00,0x81,0x00};   
// SET REPORT
unsigned char SetupSetReport[]={0x21,0x09,0x00,0x02,0x00,0x00,0x01,0x00};
#define  ch375_a0      GPIO_Pin_12          //ao=1写命令
#define  ch375_rd      GPIO_Pin_11
#define  ch375_wr      GPIO_Pin_10
#define  ch375_cs      GPIO_Pin_9
#define  ch375_int     GPIO_Pin_8
#define CH375_INT_WIRE_IN   ((GPIOC->IDR&GPIO_Pin_8)>>1)
//#define USB_DBA GPIOC
//#define LCD_DBB GPIOB
#define USB1_DB0_H GPIOC->BSRR=GPIO_Pin_0
#define USB1_DB0_L GPIOC->BRR=GPIO_Pin_0
#define USB1_DB1_H GPIOC->BSRR=GPIO_Pin_1
#define USB1_DB1_L GPIOC->BRR=GPIO_Pin_1
#define USB1_DB2_H GPIOC->BSRR=GPIO_Pin_2
#define USB1_DB2_L GPIOC->BRR=GPIO_Pin_2
#define USB1_DB3_H GPIOC->BSRR=GPIO_Pin_3
#define USB1_DB3_L GPIOC->BRR=GPIO_Pin_3
#define USB1_DB4_H GPIOC->BSRR=GPIO_Pin_4
#define USB1_DB4_L GPIOC->BRR=GPIO_Pin_4
#define USB1_DB5_H GPIOC->BSRR=GPIO_Pin_5
#define USB1_DB5_L GPIOC->BRR=GPIO_Pin_5
#define USB1_DB6_H GPIOC->BSRR=GPIO_Pin_6
#define USB1_DB6_L GPIOC->BRR=GPIO_Pin_6
#define USB1_DB7_H GPIOC->BSRR=GPIO_Pin_7
#define USB1_DB7_L GPIOC->BRR=GPIO_Pin_7

/* 常用USB结构和相关常量 */

typedef struct _USB_SETUP_REQ {
        UINT8        bType;
        UINT8        bReq;
        UINT8        wValueL;
        UINT8        wValueH;
        UINT8        wIndexL;
        UINT8        wIndexH;
        UINT8        wLengthL;
        UINT8        wLengthH;
} USB_SETUP_REQ, *PUSB_SETUP_REQ;

typedef struct _USB_DEVICE_DESCRIPTOR {
    UINT8 bLength;
    UINT8 bDescriptorType;
    UINT8 bcdUSBL;
    UINT8 bcdUSBH;
    UINT8 bDeviceClass;
    UINT8 bDeviceSubClass;
    UINT8 bDeviceProtocol;
    UINT8 bMaxPacketSize0;
    UINT8 idVendorL;
    UINT8 idVendorH;
    UINT8 idProductL;
    UINT8 idProductH;
    UINT8 bcdDeviceL;
    UINT8 bcdDeviceH;
    UINT8 iManufacturer;
    UINT8 iProduct;
    UINT8 iSerialNumber;
    UINT8 bNumConfigurations;
} USB_DEV_DESCR, *PUSB_DEV_DESCR;

typedef struct _USB_CONFIG_DESCRIPTOR {
    UINT8 bLength;
    UINT8 bDescriptorType;
    UINT8 wTotalLengthL;
    UINT8 wTotalLengthH;
    UINT8 bNumInterfaces;
    UINT8 bConfigurationValue;
    UINT8 iConfiguration;
    UINT8 bmAttributes;
    UINT8 MaxPower;
} USB_CFG_DESCR, *PUSB_CFG_DESCR;

typedef struct _USB_INTERF_DESCRIPTOR {
    UINT8 bLength;
    UINT8 bDescriptorType;
    UINT8 bInterfaceNumber;
    UINT8 bAlternateSetting;
    UINT8 bNumEndpoints;
    UINT8 bInterfaceClass;
    UINT8 bInterfaceSubClass;
    UINT8 bInterfaceProtocol;
    UINT8 iInterface;
} USB_ITF_DESCR, *PUSB_ITF_DESCR;

typedef struct _USB_ENDPOINT_DESCRIPTOR {
    UINT8 bLength;
    UINT8 bDescriptorType;
    UINT8 bEndpointAddress;
    UINT8 bmAttributes;
    UINT8 wMaxPacketSize;
    UINT8 wMaxPacketSize1;
    UINT8 bInterval;
} USB_ENDP_DESCR, *PUSB_ENDP_DESCR;

typedef struct _USB_CONFIG_DESCRIPTOR_LONG {
        USB_CFG_DESCR        cfg_descr;
        USB_ITF_DESCR        itf_descr;
        USB_ENDP_DESCR        endp_descr[2];
} USB_CFG_DESCR_LONG, *PUSB_CFG_DESCR_LONG;


typedef struct _USB_HID_CLASS_DESCRIPTOR{
    UINT8  bLength;
        UINT8  bDescriptorType;
        UINT16 bcdHID;
        UINT8  bCountryCode;
        UINT8  bNumDescriptors;
        UINT8  bDescriptType;
        UINT16 wDescriptorLength;
}USB_HID_CLASS_DESCR,*PUSB_HID_CLASS_DESCR;



typedef struct _HID_DEVICE{
           USB_CFG_DESCR        hid_cfg_descr;
        USB_ITF_DESCR        hid_itf_descr;
        USB_HID_CLASS_DESCR         hid_class_descr;
        USB_ENDP_DESCR       endp_descr;
}HID_DEVICE,*PHID_DEVICE;


typedef struct _USB_HID_COMPOSITE_DEVICE1{
        USB_CFG_DESCR        hid_cfg_descr;
        USB_ITF_DESCR        hid_itf_descr1;
        USB_HID_CLASS_DESCR         hid_class_descr1;
        USB_ENDP_DESCR       endp_descr1;
        USB_ITF_DESCR        hid_itf_descr2;
        USB_HID_CLASS_DESCR         hid_class_descr2;
        USB_ENDP_DESCR       endp_descr2;
}HID_COMPOSITE_DEVICE1,*PHID_COMPOSITE_DEVICE1;

typedef struct _USB_HID_COMPOSITE_DEVICE2{
   USB_CFG_DESCR        hid_cfg_descr;
   USB_ITF_DESCR        hid_itf_descr1;
   USB_HID_CLASS_DESCR        hid_class_descr1;
   USB_ENDP_DESCR       endp_descr1;
   USB_ITF_DESCR        hid_itf_descr1_1;
   USB_ENDP_DESCR       endp_descr1_1;

   USB_ITF_DESCR        hid_itf_descr2;
   USB_HID_CLASS_DESCR        hid_class_descr2;
   USB_ENDP_DESCR       endp_descr2;
   USB_ITF_DESCR        hid_itf_descr2_1;
   USB_ENDP_DESCR       endp_descr2_1;

}HID_COMPOSITE_DEVICE2,*PHID_COMPOSITE_DEVICE2;

struct _Device_Atti{
          UINT8 Device_connect;      //设备连接状态 1:连接,0:断开
          UINT8 Device_compat;       //0:非复合设备,1表示复合设备  
          UINT8 Cfg_value;           //设备配置描述符中配置值
  struct _Device{
          UINT8 Device_type;               //设备类型 1:键盘,2:鼠标
          UINT8 Device_inf;               //设备接口号 默认为0  最多支持两个接口设备
          UINT8 Device_endp;         //设备端点地址 最多支持一个端点
          UINT8 Device_size;         //设备端点大小
          UINT16 Device_report_len;   //设备报表长度
        UINT8 tog;                                   //端点的同步标志
  }Device[2];
}Device_Atti = { 0 };
UINT8 receive_mode = 0x00,send_mode = 0x00;
void mDelay1_2uS(void)  /* 至少延时1uS,根据单片机主频调整 */
{
        UINT32        i;
        for ( i = 25; i != 0; i -- );  /* 本例由于模拟I/O较慢故只需少量延时 */
}
/****************************************************************************
* 名    称:delay_us(u32 nus)
* 功    能:微秒延时函数
* 入口参数:u32  nus
* 出口参数:无
* 说    明:
* 调用方法:无
****************************************************************************/
void delay_us(u32 nus)//延时一微秒
{
         u32 temp;
         SysTick->LOAD = 9*nus;
         SysTick->VAL=0X00;//清空计数器
         SysTick->CTRL=0X01;//使能,减到零是无动作,采用外部时钟源
         do
         {
          temp=SysTick->CTRL;//读取当前倒计数值
         }while((temp&0x01)&&(!(temp&(1<<16))));//等待时间到达
         
         SysTick->CTRL=0x00; //关闭计数器
         SysTick->VAL =0X00; //清空计数器
}
//1秒等1000毫秒,一毫秒等1000微秒
/****************************************************************************
* 名    称:delay_ms(u16 nms)
* 功    能:毫秒延时函数
* 入口参数:u16 nms
* 出口参数:无
* 说    明:
* 调用方法:无
****************************************************************************/
void delay_ms(u16 nms)//延时一毫秒
{
         u32 temp;
         SysTick->LOAD = 9000*nms;
         SysTick->VAL=0X00;//清空计数器
         SysTick->CTRL=0X01;//使能,减到零是无动作,采用外部时钟源
         do
         {
          temp=SysTick->CTRL;//读取当前倒计数值
         }while((temp&0x01)&&(!(temp&(1<<16))));//等待时间到达
         SysTick->CTRL=0x00; //关闭计数器
         SysTick->VAL =0X00; //清空计数器
}
//ch375 data input
void ch375_data_input(void)
{
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|
                                                                  GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_0;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
  GPIO_Init(GPIOC, &GPIO_InitStructure);  
}
//ch375 data output
void ch375_data_output(void)
{
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|
                                                                  GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_0;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
  GPIO_Init(GPIOC, &GPIO_InitStructure);  
}
void myinit(void)
{
  uint32_t i;
  //ch375 控制
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10|GPIO_Pin_11|GPIO_Pin_12;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
  GPIO_Init(GPIOC, &GPIO_InitStructure);
   
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;                 //cs
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_Init(GPIOC, &GPIO_InitStructure);
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;                  //int
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_10MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
  GPIO_Init(GPIOC, &GPIO_InitStructure);   
   
  USART_Cmd(USART1, ENABLE);
  for(i=0;i<200000;i++);                                                     
  //USART_SendData(USART1, 0x99);         
}
  void CH376_DATA_DAT_OUT (UINT8 data) /* 写并口低八位输出数据 */
  {
//ch375_data_output();
if(data&0x01)
{
   USB1_DB0_H;
}
else
{
   USB1_DB0_L;
}

if(data&0x02)
{
   USB1_DB1_H;
}
else
{
   USB1_DB1_L;
}
     
if(data&0x04)
{
   USB1_DB2_H;
}
else
{
   USB1_DB2_L;
}

if(data&0x08)
{
   USB1_DB3_H;
}
else
{
   USB1_DB3_L;
}

if(data&0x10)
{
   USB1_DB4_H;
}
else
{
   USB1_DB4_L;
}

if(data&0x20)
{
   USB1_DB5_H;
}
else
{
   USB1_DB5_L;
}

if(data&0x40)
{
   USB1_DB6_H;
}
else
{
   USB1_DB6_L;
}

if(data&0x80)
{
   USB1_DB7_H;
}
else
{
   USB1_DB7_L;
}
}
/*{
unsigned int D_Temp = 0;
D_Temp = D_Temp + d;
GPIO_Write(GPIOC,D_Temp);
} */

UINT8 CH376_DATA_DAT_IN(void ) /* 读并口低八位输入数据 */
/*{ UINT8 db_data=0x00;
// data_io_in();
if(GPIOC->BSRR&GPIO_Pin_0)
{
  db_data|=GPIO_Pin_0;
}

  if(GPIOC->BSRR&GPIO_Pin_1)
{
  db_data|=GPIO_Pin_1;
}

  if(GPIOC->BSRR&GPIO_Pin_2)
{
  db_data|=GPIO_Pin_2;
}

  if(GPIOC->BSRR&GPIO_Pin_3)
{
  db_data|=GPIO_Pin_3;
}

  if(GPIOC->BSRR&GPIO_Pin_4)
{
  db_data|=GPIO_Pin_4;
}

  if(GPIOC->BSRR&GPIO_Pin_5)
{
  db_data|=GPIO_Pin_5;
}

  if(GPIOC->BSRR&GPIO_Pin_6)
{
  db_data|=GPIO_Pin_6;
}

  if(GPIOC->BSRR&GPIO_Pin_7)
{
  db_data|=GPIO_Pin_7;
}

return db_data; }*/
{
unsigned int D_Temp;
UINT8 d;
D_Temp = GPIO_ReadInputData(GPIOC);
d = (UINT8)D_Temp;
return d;
}

//**********************************************
//*        NAME:    CH376_WR_CMD_PORT( UINT8 cmd )                                                                         
//*        FUCTION: 写CH376命令子函数                                                                         
//*        输入参数:8位命令码
//* 输出参数:无                                                                         
//*        说明:对于速度较快的单片机,则需要1.5uS延时                                                                         
//**********************************************
void CH376_WR_CMD_PORT( UINT8 cmd )
{
        uint16_t i;
        //GPIO_WriteBit(GPIOE, ch375_cs, Bit_RESET);
       
    for(i=0;i<1000;i++);
        ch375_data_output();  //定义端口
        //for(i=0;i<5;i++);
       
       
        CH376_DATA_DAT_OUT (cmd);
        GPIO_WriteBit(GPIOC, ch375_a0, Bit_SET);
        GPIO_WriteBit(GPIOC, ch375_rd, Bit_SET);                       
    GPIO_WriteBit(GPIOC, ch375_wr, Bit_RESET);
    for(i=0;i<100;i++);
        GPIO_WriteBit(GPIOC, ch375_wr, Bit_SET);
    //for(i=0;i<100;i++);
}

//**********************************************
//*        NAME:    CH376_WR_DAT_PORT( UINT8 dat )                                                                         
//*        FUCTION: 写CH376数据子函数                                                                         
//*        输入参数:8位数据
//* 输出参数:无                                                                         
//*        说明:对于速度较快的单片机,则需要0.6uS延时                                                                         
//**********************************************

void CH376_WR_DAT_PORT( UINT8 dat )
{
    uint16_t i;
        //GPIO_WriteBit(GPIOE, ch375_cs, Bit_RESET);
        for(i=0;i<1000;i++);
    ch375_data_output();  //定义端口
       
        GPIO_WriteBit(GPIOC, ch375_a0, Bit_RESET);
        GPIO_WriteBit(GPIOC, ch375_rd, Bit_SET);
        CH376_DATA_DAT_OUT(dat);                        
    GPIO_WriteBit(GPIOC, ch375_wr, Bit_RESET);
    for(i=0;i<100;i++);          
        GPIO_WriteBit(GPIOC, ch375_wr, Bit_SET);  
        //for(i=0;i<100;i++);
}

//**********************************************
//*        NAME:    CH376_RD_DAT_PORT( void )                                                                         
//*        FUCTION: 读CH376数据子函数                                                                         
//*        输入参数:无
//* 输出参数:8位数据                                                                         
//*        说明:对于速度较快的单片机,则需要0.6uS延时                                                                         
//**********************************************

UINT8 CH376_RD_DAT_PORT( void )
{
        uint8_t temp;
        uint16_t  i;
        //GPIO_WriteBit(GPIOE, ch375_cs, Bit_RESET);
    for(i=0;i<1000;i++);
        ch375_data_input();  //定义端口
        //for ( i = 5; i != 0; i -- );
        GPIO_WriteBit(GPIOC, ch375_a0, Bit_RESET);
        GPIO_WriteBit(GPIOC, ch375_wr, Bit_SET);   
    GPIO_WriteBit(GPIOC, ch375_rd, Bit_RESET);
        for(i=0;i<10;i++);
        temp = CH376_DATA_DAT_IN();
   // USART_SendData(USART1,temp);
        //for(i=0;i<50;i++);
    GPIO_WriteBit(GPIOC, ch375_rd, Bit_SET);
  return( temp );
}
void StdioInit( void ) //串口初始化
{ GPIO_InitTypeDef GPIO_InitStructure;//io口配置结构体
NVIC_InitTypeDef NVIC_InitStructure;//优先级配置结构体
USART_InitTypeDef  USART_InitStructure;//串口配置结构体       


    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);       
         //打开GPIOA的时钟打开串口一的时钟打开io口复用功能的时钟
                   
        GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;//TX        串口输出用GPIOA9
        GPIO_InitStructure.GPIO_Speed=GPIO_Speed_2MHz;//输出速度50MHz
        GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;//使用复用推挽输出
        GPIO_Init(GPIOA,&GPIO_InitStructure);//初始化GPIO9

        GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10;//RX串口输入用GPIOA10
        GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;//使用浮空输入
        GPIO_Init(GPIOA,&GPIO_InitStructure); //初始化GPIO10

            

        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);//中断优先级分组,分到1组

        NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;//使用中断对应的入口函数
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;//抢占优先级为0
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;//响应优先级为1
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//打开优先级的使能
        NVIC_Init(&NVIC_InitStructure);        //优先级初始化


           USART_InitStructure.USART_BaudRate=9600; //串口波特率9600
        USART_InitStructure.USART_WordLength=USART_WordLength_8b;//数据位8位
        USART_InitStructure.USART_StopBits=USART_StopBits_1;//停止位1
        USART_InitStructure.USART_Parity=USART_Parity_No;//不效验
        USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None;//硬件控制流无
        USART_InitStructure.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;//指定使能收发模式都打开

        USART_Init(USART1,&USART_InitStructure);//串口初始化
        USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);//配置打开接收中断函数
        USART_Cmd(USART1,ENABLE);//打开串口1全部使能
        USART_ClearFlag(USART1,USART_FLAG_TC);//清除中断USART_FLAG_TC发送完成标志位清空
        }
  void PrintCom(unsigned char *DAT)//串口字符口串输出
{
        while(*DAT)
        { USART_SendData(USART1,*DAT++);
        while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);
                
        }
        USART_SendData(USART1,0x0a);
        while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);       
}
//**********************************************
//*        NAME:    Set_USB_Mode( UINT8 mode )                                                                         
//*        FUCTION: 设置CH376的工作模式 0x06 为主机模式                                                                         
//*        输入参数:模式代码
//* 输出参数:操作状态 TRUE:成功,FALSE失败                                                                         
//*        说明: 设置CH376的工作模式                                                                         
//**********************************************

UINT8 Set_USB_Mode( UINT8 mode ) {  
        UINT8 i;
        CH376_WR_CMD_PORT( CMD_SET_USB_MODE );
        CH376_WR_DAT_PORT( mode );
        receive_mode=send_mode=0x00;  //主机端复位USB数据同步标志
        for( i=0; i!=100; i++ ) {    //等待设置模式操作完成,不超过30uS
                if ( CH376_RD_DAT_PORT()==CMD_RET_SUCCESS ) return( 1 );  //成功
        }
        return( 0 );              //CH376出错,例如芯片型号错或者处于串口方式或者不支持
}


//*****************************************************
//*        NAME:    set_freq(void)                                                                         
//*        FUCTION: 设置CH376的进入低速模式                                                                         
//*        输入参数:无
//* 输出参数:无                                                                         
//*        说明: 对于鼠标键盘等低速设备,要先设置ch376为低速模式                                                                         
//******************************************************

void set_freq(void)
{       
        CH376_WR_CMD_PORT(0x0b);    // 切换使375B进入低速模式
         delay_us(1);
        CH376_WR_DAT_PORT(0x17);
          delay_us(1);
        CH376_WR_DAT_PORT(0xd8);
        delay_us(1);
}



//*****************************************************
//*        NAME:     RD_USB_DATA( UINT8 *buf )                                                                         
//*        FUCTION:  从CH376的端点缓冲区读取接收到的数据                                                                         
//*        输入参数: 数据缓冲区的地址
//* 输出参数:返回接收的数据长度                                                                         
//*        说明:    从CH376的主机端点缓冲区中读取接收到的数据                                                                         
//******************************************************

UINT8 RD_USB_DATA( UINT8 *buf ) {  
        UINT8 i, len;
        CH376_WR_CMD_PORT( 0x27 );                  // 从CH37X读取数据块
        delay_us(3);
        len=CH376_RD_DAT_PORT();                             // 后续数据长度
        delay_us(1);
        for ( i=0; i!=len; i++ ) *buf++=CH376_RD_DAT_PORT();
        return( len );
}


//*****************************************************
//*        NAME:     WR_USB_DATA( UINT8 len, UINT8 *buf )                                                                         
//*        FUCTION:  往CH376的端点缓冲区写入数据块                                                                 
//*        输入参数: 要写入数据块的长度,写入数据缓冲区的地址
//* 输出参数:无                                                                         
//*        说明:    往CH376的主机端点缓冲区中写入要发送的数据块                                                                         
//******************************************************

void WR_USB_DATA( UINT8 len, UINT8 *buf ) {  
        CH376_WR_CMD_PORT( 0x2B );     // 向CH376的端点缓冲区写入准备发送的数据
          delay_us(2);
        CH376_WR_DAT_PORT( len );                    // 后续数据长度, len不能大于64
        delay_us(1);
        while( len-- ) CH376_WR_DAT_PORT( *buf++ );
}


//*****************************************************
//*        NAME:     issue_token(UINT8 endptog, UINT8 endp_and_pid )                                                                 
//*        FUCTION:  执行USB事务                                                                 
//*        输入参数: 同步标志,端点号和令牌
//* 输出参数:无                                                                         
//*        说明:    高4位目的端点号, 低4位令牌PID                                                                         
//******************************************************

void issue_token(UINT8 endptog, UINT8 endp_and_pid ) {  
        CH376_WR_CMD_PORT( 0x4E );
        delay_us(3);
        CH376_WR_DAT_PORT( endptog );
        delay_us(3);
        CH376_WR_DAT_PORT( endp_and_pid );
        delay_us(3) ;
}


//*****************************************************
//*        NAME:     wait_interrupt( )                                                                 
//*        FUCTION:  等待中断,并且获取中断状态                                                                 
//*        输入参数: 无
//* 输出参数:中断状态                                                                         
//*        说明:    CH376操作完成中断(INT#低电平)                                                                            
//******************************************************
  
UINT8 wait_interrupt( )
{  uint16_t i;
  while(1)  // 查询等待CH375操作完成中断(INT#低电平)
          {if(GPIO_ReadInputDataBit(GPIOC, ch375_int)==0)       
                {
                        //LED 熄灭
                   break;       
                }
                }
          
          delay_ms(2);
  CH376_WR_CMD_PORT(0x22);  // 产生操作完成中断,获取中断状态
//   PrintCom("\n 产生操作完成中断,获取中断状  \n");
  for ( i = 1000; i!= 0; i -- );
  return( CH376_RD_DAT_PORT( ) );
}


//*****************************************************
//*        NAME:     Get_Dev_Descr( )                                                                 
//*        FUCTION:  获取设备描述符                                                                 
//*        输入参数: 无
//* 输出参数:成功返回1,否则返回0                                                                         
//*        说明:    该程序采用外置固件模式获取设备描述符                                                                            
//******************************************************

UINT8 Get_Dev_Descr( )
{       
    UINT8 descr_len;
        UINT8  *p=data_buf;
        send_mode=0x00;
        WR_USB_DATA(8,SetupGetDevDescr);

        issue_token(send_mode,( 0 << 4 ) | DEF_USB_PID_SETUP);status=wait_interrupt();
        if(status==USB_INT_SUCCESS)                                                      //SETUP阶段操作成功
        {
                receive_mode=0x80;
        }
        else return(0);

        issue_token(receive_mode,( 0 << 4 ) | DEF_USB_PID_IN);status=wait_interrupt();
        if(status==USB_INT_SUCCESS)                                                                                                                //DATA阶段操作成功
        {
                descr_len=data_buf[0]-RD_USB_DATA(data_buf);       
                while(descr_len>0)
                {       
                        receive_mode ^= 0x80;
                        p+=0x08;
                        issue_token(receive_mode,( 0 << 4 ) | DEF_USB_PID_IN);status=wait_interrupt();
                        if(status==USB_INT_SUCCESS)                                                                                                //DATA阶段操作成功
                                descr_len-=RD_USB_DATA(p);       
                        else return(0);
                       
                }
        }
        else return(0);

        send_mode=0x40;
        WR_USB_DATA(0,SetupGetDevDescr);
        issue_token(send_mode,( 0 << 4 ) | DEF_USB_PID_OUT);status=wait_interrupt();
        if(status==USB_INT_SUCCESS)                                                                                                                //状态阶段操作成功
                return(1);       
        else return(0);
}



//*****************************************************
//*        NAME:     Get_Cfg_Descr( PUINT8 buf )                                                                 
//*        FUCTION:  获取配置描述符                                                                 
//*        输入参数: 接收缓冲区地址
//* 输出参数:成功返回1,否则返回0                                                                         
//*        说明:    该程序采用外置固件模式获取配置描述符                                                                            
//******************************************************

UINT8 Get_Cfg_Descr( PUINT8 buf )
{
        unsigned char descr_len;
        unsigned char *p=data_buf;
        send_mode=0x00;
        WR_USB_DATA(8,buf);
        issue_token(send_mode,( 0 << 4 ) | DEF_USB_PID_SETUP);status=wait_interrupt();
        if(status==USB_INT_SUCCESS)                                                                                                                //SETUP阶段操作成功
        {
                receive_mode=0x80;
        }
        else return(0);
        issue_token(receive_mode,( 0 << 4 ) | DEF_USB_PID_IN);status=wait_interrupt();
        if(status==USB_INT_SUCCESS)                                                                                                                //DATA阶段操作成功
        {       
            receive_mode ^= 0x80;
                if(flag_config_2)                                                                                                                    //第二次获取设备的配置描述符
                 descr_len=data_buf[2]-RD_USB_DATA(data_buf);
                else descr_len=data_buf[0]-RD_USB_DATA(data_buf);       
                while(descr_len>0)
                {       
                        p+=0x08;
                        issue_token(receive_mode,( 0 << 4 ) | DEF_USB_PID_IN);status=wait_interrupt();
                        if(status==USB_INT_SUCCESS)                                                                                                //DATA阶段操作成功
                          {
                            receive_mode ^= 0x80;
                                descr_len-=RD_USB_DATA(p);       
                           }
                        else return(0);
                       
                }
        }
        else return(0);
        send_mode = 0x40;
        WR_USB_DATA(0,SetupGetCfgDescr);
        issue_token(send_mode,( 0 << 4 ) | DEF_USB_PID_OUT);status=wait_interrupt();
        if(status==USB_INT_SUCCESS)                                                                                                                //状态阶段操作成功
                return(1);       
        else return(0);
}

//*****************************************************
//*        NAME:     parse_config_descr( )                                                                 
//*        FUCTION:  简单的分析配置描述符中的相关信息,并保存                                                                 
//*        输入参数: 无
//* 输出参数:无                                                                         
//*        说明:    保存设备的接口号,端点地址,报表长度,支持复合设备                                                                            
//******************************************************

void parse_config_descr( )
{
  Device_Atti.Device_connect = 1;                                                                    //表示设备连接
  Device_Atti.Cfg_value = ((PUSB_CFG_DESCR)data_buf)->bConfigurationValue;  //保留配置描述符中的配置值

if(((PUSB_CFG_DESCR)data_buf)->bNumInterfaces==1)                                                          //只有一个接口设备
  {
    Device_Atti.Device_compat = 0;                                                                                          //非复合设备

#define HID_Dev  ((PHID_DEVICE)data_buf)
   
          Device_Atti.Device[0].Device_type =  HID_Dev->hid_itf_descr.bInterfaceProtocol;        //设备类型:0x01 键盘,0x02 鼠标
        Device_Atti.Device[0].Device_inf  =  HID_Dev->hid_itf_descr.bInterfaceNumber;        //设备的接口号
        Device_Atti.Device[0].Device_endp =  HID_Dev->endp_descr.bEndpointAddress;                //设备端点地址
          Device_Atti.Device[0].Device_size =  HID_Dev->endp_descr.wMaxPacketSize;                //设备端点大小
        Device_Atti.Device[0].Device_report_len =  (HID_Dev->hid_class_descr.wDescriptorLength>>8)|(HID_Dev->hid_class_descr.wDescriptorLength<<8);           //报表长度,大小端数据格式转换
  
  }

else if(((PUSB_CFG_DESCR)data_buf)->bNumInterfaces==2)                                                  //2个接口设备
  {
    Device_Atti.Device_compat = 1;                                                                                          //复合设备

#define HID_Dev1  ((PHID_COMPOSITE_DEVICE1)data_buf)
   
          Device_Atti.Device[0].Device_type =  HID_Dev1->hid_itf_descr1.bInterfaceProtocol;
        Device_Atti.Device[0].Device_inf  =  HID_Dev1->hid_itf_descr1.bInterfaceNumber;
        Device_Atti.Device[0].Device_endp =  HID_Dev1->endp_descr1.bEndpointAddress;
          Device_Atti.Device[0].Device_size =  HID_Dev1->endp_descr1.wMaxPacketSize;
        Device_Atti.Device[0].Device_report_len =  (HID_Dev1->hid_class_descr1.wDescriptorLength>>8)|(HID_Dev1->hid_class_descr1.wDescriptorLength<<8);         //报表长度,大小端数据格式转换
  
          Device_Atti.Device[1].Device_type =  HID_Dev1->hid_itf_descr2.bInterfaceProtocol;
        Device_Atti.Device[1].Device_inf  =  HID_Dev1->hid_itf_descr2.bInterfaceNumber;
        Device_Atti.Device[1].Device_endp =  HID_Dev1->endp_descr2.bEndpointAddress;
          Device_Atti.Device[1].Device_size =  HID_Dev1->endp_descr2.wMaxPacketSize;
        Device_Atti.Device[1].Device_report_len =  (HID_Dev1->hid_class_descr2.wDescriptorLength>>8)|(HID_Dev1->hid_class_descr2.wDescriptorLength<<8);         //报表长度,大小端数据格式转换

  }

}


//*****************************************************
//*        NAME:     set_config( UINT8 cfg )                                                                 
//*        FUCTION:  配置USB设备                                                                 
//*        输入参数: 配置值
//* 输出参数:操作状态 成功返回0x14                                                                         
//*        说明:    该配置值取自配置描述符中                                                                            
//******************************************************

UINT8 set_config( UINT8 cfg ) {  
        CH376_WR_CMD_PORT( CMD_SET_CONFIG );
        delay_us(3);  
        CH376_WR_DAT_PORT( cfg );
        delay_us(2);  
        return( wait_interrupt() );  
}

//*****************************************************
//*        NAME:     set_idle( UINT8 inf )                                                                 
//*        FUCTION:  设置HID设备的IDLE                                                                 
//*        输入参数: 接口号
//* 输出参数:操作状态 成功返回1                                                                         
//*        说明:                                                                                
//******************************************************

UINT8 set_idle( UINT8 inf )
{
        send_mode=0x00;
        memcpy(data_buf,SetupSetidle,8);
        data_buf[4] = inf;
        WR_USB_DATA(8,data_buf);                                                                //SETUP数据总是8字节
        issue_token(send_mode,( 0 << 4 ) | DEF_USB_PID_SETUP);
        status=wait_interrupt();
        if(status==USB_INT_SUCCESS)                                                                //SETUP阶段操作成功
        {
                receive_mode=0x80;
                issue_token(receive_mode,( 0 << 4 ) | DEF_USB_PID_IN );status=wait_interrupt();
                if(status==USB_INT_SUCCESS)                                                        //状态阶段操作成功
                {
                        if(RD_USB_DATA(data_buf)!=0)
                        return(0);
                }
                else return(0);
        }
        else return(0);
        return(1);       
}


//*****************************************************
//*        NAME:     get_report_descr_ex( UINT8 inf,UINT16 len)                                                                 
//*        FUCTION:  获取HID类设备的报表描述符                                                                 
//*        输入参数: 接口号,报表长度
//* 输出参数:操作状态 成功返回1                                                                         
//*        说明:    获取HID类的报表,报表长度取自HID类描述符中                                                                            
//******************************************************

UINT8 get_report_descr_ex( UINT8 inf,UINT16 len)               
{
        unsigned char descr_len;
        unsigned char *p=data_buf;
        unsigned char report_cou_temp=0;
        send_mode=0x00;
        memcpy(data_buf,SetupGetHidDes,8);
        data_buf[4] = inf;
        data_buf[6] = len+0x40;
        descr_len = len;                                       
        WR_USB_DATA(8,data_buf);               
        issue_token(send_mode,( 0 << 4 ) | DEF_USB_PID_SETUP);status=wait_interrupt();       
        if(status==USB_INT_SUCCESS)                                                                                                                //SETUP阶段操作成功
        {       
            receive_mode=0x80;       
        }
        else return(0);
        issue_token(receive_mode,( 0 << 4 ) | DEF_USB_PID_IN);status=wait_interrupt();
        if(status==USB_INT_SUCCESS)                                                                                                                //DATA阶段操作成功
        {       
          
           RD_USB_DATA( p );
                descr_len -= 0x08;                                                                                                        //剩余描述符长度计算
                while(descr_len>0)
                {       
                        receive_mode ^= 0x80;
                        p+=0x08;
                        issue_token(receive_mode,( 0 << 4 ) | DEF_USB_PID_IN);status=wait_interrupt();
                        if(status==USB_INT_SUCCESS)                                                                                                // DATA阶段操作成功
                        {       
                            report_cou_temp=RD_USB_DATA(p);
                                if(report_cou_temp!=0x08){ descr_len -= report_cou_temp; break;}
                                else {descr_len-=0x08; }
                        }
                        else return(0);
                       
                }
        }
        else return(0);
        send_mode=0x40;
        WR_USB_DATA(0,data_buf);
        issue_token(send_mode,( 0 << 4 ) | DEF_USB_PID_OUT);status=wait_interrupt();
        if(status==USB_INT_SUCCESS)                                                                                                                //状态阶段操作成功
                return(1);       
        else return(0);
}


//*****************************************************
//*        NAME:     set_report( )                                                                 
//*        FUCTION:  对于键盘设备,则可以设置报表                                                                 
//*        输入参数: 无
//* 输出参数:操作状态 成功返回1                                                                         
//*        说明:    可以通过设置报表,点亮键盘指示灯                                                                            
//******************************************************

UINT8 set_report( )
{       
        send_mode=0x00;
        WR_USB_DATA(8,SetupSetReport);                                                                                                        //SETUP数据总是8字节
        issue_token(send_mode,( 0 << 4 ) | DEF_USB_PID_SETUP);status=wait_interrupt();
        if(status==USB_INT_SUCCESS)                                                                                                                //SETUP阶段操作成功
        {       
            send_mode ^= 0x40;
                data_buf[0]=0x01;
                WR_USB_DATA(1,data_buf);
                issue_token(send_mode,( 0 << 4 ) | DEF_USB_PID_OUT);status=wait_interrupt();
                if(status==USB_INT_SUCCESS)                                                                                                 //DATA阶段操作成功
                {       
                    receive_mode=0x80;
                        issue_token(receive_mode,( 0 << 4 ) | DEF_USB_PID_IN);status=wait_interrupt();
                        if(status==USB_INT_SUCCESS)                                                                                                //状态阶段操作成功
                        {       
                            if(RD_USB_DATA(data_buf)!=0)
                                return(0);
                        }
                        else return(0);
                }
                else return(0);
        }       
        else return(0);
       
       
        return(1);
}
void tmpfssj()
{           if(a==0)
             { num=0;
                //UARTSendByte(temp3);
                //UARTSendByte(tmpformt);
                                suju[num]=temp3;
                                num++;
                a=1;
               }
              if(a==1)
             {if(tmpformt!=0x0b)
                {//UARTSendByte(tmpformt);
                                 suju[num]=tmpformt;
                                num++;
                                }
              else
             {//delay();
             // UARTSendByte(tmpformt);
             // UARTSendByte(temp4);
                           suju[num]=tmpformt;
                                num++;
                                suju[num]=temp4;
                                num++;
                                   for(i=0;i                                 {  //send_data1(prdata[i]);
                                        // UARTSendByte(suju[i]) ;
                                        USART_SendData(USART1,suju[i]);
                                  while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);
                                }
              a=0;
                       }}}

//*****************************************************
//*        NAME:     get_int_in(UINT8 tog,UINT8 endp_int)                                                                 
//*        FUCTION:  获取HID类设备的数据                                                                 
//*        输入参数: 该设备的同步标志,端点号
//* 输出参数:操作状态                                                                         
//*        说明:    支持复合设备的操作                                                                           
//******************************************************

UINT8 get_int_in(UINT8 tog,UINT8 endp_int)
{
        UINT8 s,t,j;
//        tog = tog ? 0x80 : 0x00;
//        issue_token(tog,( endp_int << 4 ) | DEF_USB_PID_IN);//CMD10_SET_ENDP2
         CH376_WR_CMD_PORT( CMD_ISSUE_TOKEN );
         CH376_WR_DAT_PORT( CMD10_SET_ENDP2 ); /* 高4位目的端点号, 低4位令牌PID */
        s = wait_interrupt( );
          
         if(s == USB_INT_SUCCESS)
           {
                  t = RD_USB_DATA(data_buf);                                                                               
                  //键盘中断端点数据长度一般为8字节,鼠标为4字节               
        for(j=0;j!=t;j++) //条码枪数据来源hdi解码键盘码转asc码
                {       
                        fs=data_buf[j];
                          switch(fs)
                         {case 0x27:tmpformt='0';tmpfssj();break;
                          case 0x1e:tmpformt='1';tmpfssj();break;
                          case 0x1f:tmpformt='2';tmpfssj();break;
                          case 0x20:tmpformt='3';tmpfssj();break;
                          case 0x21:tmpformt='4';tmpfssj();break;
                          case 0x22:tmpformt='5';tmpfssj();break;
                          case 0x23:tmpformt='6';tmpfssj();break;
                          case 0x24:tmpformt='7';tmpfssj();break;
                          case 0x25:tmpformt='8';tmpfssj();break;
                          case 0x26:tmpformt='9';tmpfssj();break;
                          case 0x04:tmpformt='A';tmpfssj();break;
                          case 0x05:tmpformt='B';tmpfssj();break;
                          case 0x06:tmpformt='C';tmpfssj();break;
                          case 0x07:tmpformt='D';tmpfssj();break;
                          case 0x08:tmpformt='E';tmpfssj();break;
                          case 0x09:tmpformt='F';tmpfssj();break;
                          case 0x0a:tmpformt='G';tmpfssj();break;
                          case 0x0b:tmpformt='H';tmpfssj();break;
                          case 0x0c:tmpformt='I';tmpfssj();break;
                          case 0x0d:tmpformt='J';tmpfssj();break;
                          case 0x0e:tmpformt='K';tmpfssj();break;
                          case 0x0f:tmpformt='L';tmpfssj();break;
                          case 0x10:tmpformt='M';tmpfssj();break;
                          case 0x11:tmpformt='N';tmpfssj();break;
                          case 0x12:tmpformt='O';tmpfssj();break;
                          case 0x13:tmpformt='P';tmpfssj();break;
                          case 0x14:tmpformt='Q';tmpfssj();break;
                          case 0x15:tmpformt='R';tmpfssj();break;
                          case 0x16:tmpformt='S';tmpfssj();break;
                          case 0x17:tmpformt='T';tmpfssj();break;
                          case 0x18:tmpformt='U';tmpfssj();break;
                          case 0x19:tmpformt='V';tmpfssj();break;
                          case 0x1a:tmpformt='W';tmpfssj();break;
                          case 0x1b:tmpformt='X';tmpfssj();break;
                          case 0x1c:tmpformt='Y';tmpfssj();break;
                          case 0x1d:tmpformt='Z';tmpfssj();break;
                          case 0x2d:tmpformt='-';tmpfssj();break;
                          case 0x28:tmpformt=0x0b;tmpfssj();break;
                          }       
                          }       
                         
                  if( endp_int == Device_Atti.Device[0].Device_endp )       
                 Device_Atti.Device[0].tog = Device_Atti.Device[0].tog ? FALSE : TRUE;
              else
                 Device_Atti.Device[1].tog = Device_Atti.Device[1].tog ? FALSE : TRUE;
                }
        //return s;
        return 1;
}


//*****************************************************
//*        NAME:     Reset_Device( )                                                                 
//*        FUCTION:  复位USB设备,并且将CH376设置成主机模式                                                                 
//*        输入参数: 无
//* 输出参数:无                                                                         
//*        说明:    USB规范中未要求USB设备插入后必须复位该设备,
//*           有些USB设备也要求在插入后必须先复位才能工作                                                                           
//******************************************************

void Reset_Device( )
{       
        Set_USB_Mode( 7 );                                                                                                          //复位USB设备,CH376向USB信号线的D+和D-输出低电平
        delay_ms(10);
        Set_USB_Mode( 6 );                                                                                                          //结束复位,将CH376设置成主机模式
        while ( wait_interrupt()!=USB_INT_CONNECT );                                                          //等待复位之后的设备端再次连接上来

}

//*****************************************************
//*        NAME:     set_addr( UINT8 addr )                                                                 
//*        FUCTION:  设置USB设备地址,并且设置USB主机端要操作的USB设备地址                                                                 
//*        输入参数: 地址值(1~127)
//* 输出参数:操作状态                                                                         
//*        说明:   
//******************************************************

UINT8 set_addr( UINT8 addr ) {
        UINT8 status;
       
        CH376_WR_CMD_PORT( CMD_SET_ADDRESS );  
        CH376_WR_DAT_PORT( addr );  
        status=wait_interrupt();                                                                                                  //等待CH376操作完成
        if ( status==USB_INT_SUCCESS ) {                                                                                  //操作成功
                CH376_WR_CMD_PORT( CMD_SET_USB_ADDR );                                                          //设置USB主机端的USB地址
                CH376_WR_DAT_PORT( addr );                                                                                  //当目标USB设备的地址成功修改后,应该同步修改主机端的USB地址
        }
        return( status );
}



//**********************************************
//*        NAME:    main( void )                                                                         
//*        FUCTION: 通过CH376操作鼠标键盘以及复合HID设备的数据                                                                         
//*        输入参数:无
//* 输出参数:无                                                                         
//*        说明:只适用普通的USB键盘,支持复合设备
//*       键盘,不支持带有HUB接口的USB键盘                                                                         
//**********************************************

int main(void)
{
UINT8 i,s,tt,check;
    a=0;temp3='{';temp4='}';
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);
        myinit();
  delay_ms(50);           //CH376上电之后需要延时40ms左右
    StdioInit();
  PrintCom("start \n");
//做测试命令,检测单片机和CH376硬件连接,以及读写时序是否正确  
  CH376_WR_CMD_PORT( 0x06 );

  CH376_WR_DAT_PORT( 0x55 );

  s = CH376_RD_DAT_PORT( );
  USART_SendData(USART1,(UINT16)s);
  while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);
          USART_SendData(USART1,0x0a);
          while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);
  Set_USB_Mode( 6 );                                                                          //设置USB主机模式, 如果设备端是CH37X, 那么5和6均可
        CH376_WR_CMD_PORT( 0x0a );
        //检测是全速设备还是低速设备
   CH376_WR_DAT_PORT( 0x07 );
   check=CH376_RD_DAT_PORT();
   if( check&0x10 )
   {     
    set_freq( );   // 切换使375B进入低速模式
//    led3=0;
   }

//set_freq( );                                                                                       //使376进入低速模式
         
while(1)
{        PrintCom(" \n wait usb device : \n");
           

        while ( wait_interrupt()!=USB_INT_CONNECT );
delay_ms(50);
        Reset_Device();                                                                                //复位usb设备
        delay_ms(50);
   // set_freq( );                                                                               //使376进入低速模式
   CH376_WR_CMD_PORT( 0x0a ); //检测是全速设备还是低速设备
   CH376_WR_DAT_PORT( 0x07 );
   check=CH376_RD_DAT_PORT();
   if( check&0x10 )
   {     
    set_freq( );   // 切换使375B进入低速模式
//    led3=0;
   }
        delay_ms(20);

//获取设备描述符
        if(Get_Dev_Descr()==1)
        {
                for(i=0;i!=data_buf[0];i++)
        //        UARTSendByte((unsigned int)data_buf[i]);
         USART_SendData(USART1,(unsigned int)data_buf[i]);       
                PrintCom("设备描述符\n");
        }
        else PrintCom("\n get device descr failed \n");

//设置地址               
        set_addr(5);                                                                               

//获取配置描述符
        if( Get_Cfg_Descr( SetupGetCfgDescr ) == 1)
         {
                   for(i=0;i!=data_buf[0];i++)
                   USART_SendData(USART1,(unsigned int)data_buf[i]);
                PrintCom("\n");       
               
         }
         s = ((PUSB_CFG_DESCR)data_buf)->wTotalLengthL;
         memcpy( data_buf,SetupGetCfgDescr,8);
     data_buf[6] = s;

         flag_config_2 = 1;
        if( Get_Cfg_Descr( data_buf ) == 1)
         {
                   for(i=0;i!=((PUSB_CFG_DESCR)data_buf)->wTotalLengthL;i++)
           USART_SendData(USART1,(unsigned int)data_buf[i]);
                PrintCom("\n");
         }
        flag_config_2 = 0;
//保存配置描述符中设备信息
        parse_config_descr( );


//设置USB配置   
   s = set_config( Device_Atti.Cfg_value );
   USART_SendData(USART1,(UINT16)s);
   

//设置HID类设备的IDLE
s = set_idle( Device_Atti.Device[0].Device_inf );
   if(s == 1)
    {PrintCom("\n set idle success \n");}
   else
   {PrintCom("\n set idle error \n");}
        PrintCom("\n errrrr\n");

//获取HID类设备的报表描述符
   s = get_report_descr_ex( Device_Atti.Device[0].Device_inf,Device_Atti.Device[0].Device_report_len);       
PrintCom("\n azx\n");       
        if( s == 1)
         {
           for(i=0;i!=Device_Atti.Device[0].Device_report_len;i++)
                USART_SendData(USART1,(unsigned int)data_buf[i]);
                PrintCom("\n eaaaaaa\n");
        // printf(" %x ",(UINT16)data_buf[i]);

         
         }
        else        {USART_SendData(USART1,(unsigned int)data_buf[i]);;
        PrintCom("\n ebbbbb\n");}
//如果该HID类设备是键盘,则可以设置报表
        if(Device_Atti.Device[0].Device_type == 0x01)
        {
        s = set_report( );
        if(s==1) PrintCom("\n set report success \n");
        else PrintCom("\n set report error \n");
        }

//如果该设备是复合设备,则需要配置另外一个接口设备
#if 1
        if(Device_Atti.Device_compat == 1)
        {
//设置IDLE
         s = set_idle( Device_Atti.Device[1].Device_inf );
      if(s == 1)
             PrintCom("\n set idle success \n");
     else //UARTSendByte((UINT16)s);
         USART_SendData(USART1,(UINT16)s);

//获取报表描述符
     s = get_report_descr_ex( Device_Atti.Device[1].Device_inf,Device_Atti.Device[1].Device_report_len);
          if( s == 1)
           {
            for(i=0;i!=Device_Atti.Device[1].Device_report_len;i++)
                        USART_SendData(USART1,(unsigned int)data_buf[i]);

           }

//如果该设备是键盘,则可以设置报表
        if(Device_Atti.Device[1].Device_type == 0x01)
         {
          s = set_report( );
          if(s==1) PrintCom("\n set report success \n");
          else PrintCom("\n set report error \n");

         }

   }
#endif


        CH376_WR_CMD_PORT( CMD20_SET_RETRY );                 //设置CH376重试次数
        CH376_WR_DAT_PORT( 0x25 );
        CH376_WR_DAT_PORT( 0x00 );                                         //为了保证兼容性对于部分鼠标键盘需要设置有限次重试(0xc0),而对于复合设备,
                                                     //比如USB转PS2的设备,复合键盘,则不需要重试(0x00)


        Device_Atti.Device[0].tog = FALSE;                         //设置设备的同步标志,默认0
        Device_Atti.Device[1].tog = FALSE;
           PrintCom("\n 主循环 \n");
       
   while(1)
   {   
//获取设备1的数据
          s = get_int_in( Device_Atti.Device[0].tog,Device_Atti.Device[0].Device_endp);
//        USART_SendData(USART1,s);
//        while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);
//如果该设备是符合设备,则需要获取设备2的数据
        if( Device_Atti.Device_compat )
        {        PrintCom("\n 主循环 \n");
         s = get_int_in( Device_Atti.Device[1].tog,Device_Atti.Device[1].Device_endp);
        }

//以下是检测设备插拔状态
        CH376_WR_CMD_PORT(0x22);//获取中断并取消请求               
                //检测设备插拔CMD01_GET_STATUS,0x22/* 获取中断状态并取消中断请求 */               

         tt = CH376_RD_DAT_PORT( );//读回数据

         if(tt == USB_INT_DISCONNECT )//判段是不是USB_INT_DISCONNECT,0x16/* 检测到USB设备断开事件 */
         {       
      Device_Atti.Device_connect = 0;


          break;//设备断开也就是跳出循环重新进入usb等待
            }

           }  
         }        
         }

回复评论 (3)

程序太长,无法帮你,说具体问题,可以帮忙分析。。。。。。
我的博客
点赞  2014-12-4 09:47
对 USB 不太熟,不过我觉得你可以参考一些 ST 的官方例程,USB 的开发看起来复杂,实际上就那么几个类。
点赞  2014-12-5 09:07

lz搞定了吗?

点赞  2020-2-10 18:50
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复