stm32驅(qū)動ch375b讀usb條碼槍能熱插拔讀不出條碼請高手幫看下什么地方錯了

#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; //第二次獲取配置描述符標志 // 獲取設(shè)備描述符 unsigned char SetupGetDevDescr[] = { 0x80, 0x06, 0x00, 0x01, 0x00, 0x00, 0x12, 0x00 }; // 獲取配置描述符 unsigned char SetupGetCfgDescr[] = { 0x80, 0x06, 0x00, 0x02, 0x00, 0x00, 0x09, 0x00 }; // 設(shè)置USB地址 unsigned char SetupSetUsbAddr[] = { 0x00, 0x05, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00 }; // 設(shè)置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結(jié)構(gòu)和相關(guān)常量 */

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; //設(shè)備連接狀態(tài) 1:連接,0:斷開 UINT8 Device_compat; //0:非復(fù)合設(shè)備,1表示復(fù)合設(shè)備 UINT8 Cfg_value; //設(shè)備配置描述符中配置值 struct _Device{ UINT8 Device_type; //設(shè)備類型 1:鍵盤,2:鼠標 UINT8 Device_inf; //設(shè)備接口號 默認為0 最多支持兩個接口設(shè)備 UINT8 Device_endp; //設(shè)備端點地址 最多支持一個端點 UINT8 Device_size; //設(shè)備端點大小 UINT16 Device_report_len; //設(shè)備報表長度 UINT8 tog; //端點的同步標志 }Device[2]; }Device_Atti = { 0 }; UINT8 receive_mode = 0x00,send_mode = 0x00; void mDelay1_2uS(void) /* 至少延時1uS,根據(jù)單片機主頻調(diào)整 */ { UINT32 i; for ( i = 25; i != 0; i -- ); /* 本例由于模擬I/O較慢故只需少量延時 */ } /**************************************************************************** * 名 稱:delay_us(u32 nus) * 功 能:微秒延時函數(shù) * 入口參數(shù):u32 nus * 出口參數(shù):無 * 說 明: * 調(diào)用方法:無 ****************************************************************************/ void delay_us(u32 nus)//延時一微秒 { u32 temp; SysTick->LOAD = 9*nus; SysTick->VAL=0X00;//清空計數(shù)器 SysTick->CTRL=0X01;//使能,減到零是無動作,采用外部時鐘源 do { temp=SysTick->CTRL;//讀取當(dāng)前倒計數(shù)值 }while((temp&0x01)&&(!(temp&(1<<16))));//等待時間到達 SysTick->CTRL=0x00; //關(guān)閉計數(shù)器 SysTick->VAL =0X00; //清空計數(shù)器 } //1秒等1000毫秒,一毫秒等1000微秒 /**************************************************************************** * 名 稱:delay_ms(u16 nms) * 功 能:毫秒延時函數(shù) * 入口參數(shù):u16 nms * 出口參數(shù):無 * 說 明: * 調(diào)用方法:無 ****************************************************************************/ void delay_ms(u16 nms)//延時一毫秒 { u32 temp; SysTick->LOAD = 9000*nms; SysTick->VAL=0X00;//清空計數(shù)器 SysTick->CTRL=0X01;//使能,減到零是無動作,采用外部時鐘源 do { temp=SysTick->CTRL;//讀取當(dāng)前倒計數(shù)值 }while((temp&0x01)&&(!(temp&(1<<16))));//等待時間到達 SysTick->CTRL=0x00; //關(guān)閉計數(shù)器 SysTick->VAL =0X00; //清空計數(shù)器 } //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) /* 寫并口低八位輸出數(shù)據(jù) */ { //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 ) /* 讀并口低八位輸入數(shù)據(jù) */ /*{ 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命令子函數(shù) //* 輸入?yún)?shù):8位命令碼 //* 輸出參數(shù):無 //* 說明:對于速度較快的單片機,則需要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數(shù)據(jù)子函數(shù) //* 輸入?yún)?shù):8位數(shù)據(jù) //* 輸出參數(shù):無 //* 說明:對于速度較快的單片機,則需要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數(shù)據(jù)子函數(shù) //* 輸入?yún)?shù):無 //* 輸出參數(shù):8位數(shù)據(jù) //* 說明:對于速度較快的單片機,則需要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口配置結(jié)構(gòu)體 NVIC_InitTypeDef NVIC_InitStructure;//優(yōu)先級配置結(jié)構(gòu)體 USART_InitTypeDef USART_InitStructure;//串口配置結(jié)構(gòu)體

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); //打開GPIOA的時鐘打開串口一的時鐘打開io口復(fù)用功能的時鐘 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;//使用復(fù)用推挽輸出 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);//中斷優(yōu)先級分組,分到1組

NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;//使用中斷對應(yīng)的入口函數(shù) NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;//搶占優(yōu)先級為0 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;//響應(yīng)優(yōu)先級為1 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//打開優(yōu)先級的使能 NVIC_Init(&NVIC_InitStructure); //優(yōu)先級初始化

USART_InitStructure.USART_BaudRate=9600; //串口波特率9600 USART_InitStructure.USART_WordLength=USART_WordLength_8b;//數(shù)據(jù)位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;//指定使能收發(fā)模式都打開

USART_Init(USART1,&USART_InitStructure);//串口初始化 USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);//配置打開接收中斷函數(shù) USART_Cmd(USART1,ENABLE);//打開串口1全部使能 USART_ClearFlag(USART1,USART_FLAG_TC);//清除中斷USART_FLAG_TC發(fā)送完成標志位清空 } 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: 設(shè)置CH376的工作模式 0x06 為主機模式 //* 輸入?yún)?shù):模式代碼 //* 輸出參數(shù):操作狀態(tài) TRUE:成功,F(xiàn)ALSE失敗 //* 說明: 設(shè)置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; //主機端復(fù)位USB數(shù)據(jù)同步標志 for( i=0; i!=100; i++ ) { //等待設(shè)置模式操作完成,不超過30uS if ( CH376_RD_DAT_PORT()==CMD_RET_SUCCESS ) return( 1 ); //成功 } return( 0 ); //CH376出錯,例如芯片型號錯或者處于串口方式或者不支持 }

//***************************************************** //* NAME: set_freq(void) //* FUCTION: 設(shè)置CH376的進入低速模式 //* 輸入?yún)?shù):無 //* 輸出參數(shù):無 //* 說明: 對于鼠標鍵盤等低速設(shè)備,要先設(shè)置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的端點緩沖區(qū)讀取接收到的數(shù)據(jù) //* 輸入?yún)?shù): 數(shù)據(jù)緩沖區(qū)的地址 //* 輸出參數(shù):返回接收的數(shù)據(jù)長度 //* 說明: 從CH376的主機端點緩沖區(qū)中讀取接收到的數(shù)據(jù) //******************************************************

UINT8 RD_USB_DATA( UINT8 *buf ) { UINT8 i, len; CH376_WR_CMD_PORT( 0x27 ); // 從CH37X讀取數(shù)據(jù)塊 delay_us(3); len=CH376_RD_DAT_PORT(); // 后續(xù)數(shù)據(jù)長度 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的端點緩沖區(qū)寫入數(shù)據(jù)塊 //* 輸入?yún)?shù): 要寫入數(shù)據(jù)塊的長度,寫入數(shù)據(jù)緩沖區(qū)的地址 //* 輸出參數(shù):無 //* 說明: 往CH376的主機端點緩沖區(qū)中寫入要發(fā)送的數(shù)據(jù)塊 //******************************************************

void WR_USB_DATA( UINT8 len, UINT8 *buf ) { CH376_WR_CMD_PORT( 0x2B ); // 向CH376的端點緩沖區(qū)寫入準備發(fā)送的數(shù)據(jù) delay_us(2); CH376_WR_DAT_PORT( len ); // 后續(xù)數(shù)據(jù)長度, len不能大于64 delay_us(1); while( len-- ) CH376_WR_DAT_PORT( *buf++ ); }

//***************************************************** //* NAME: issue_token(UINT8 endptog, UINT8 endp_and_pid ) //* FUCTION: 執(zhí)行USB事務(wù) //* 輸入?yún)?shù): 同步標志,端點號和令牌 //* 輸出參數(shù):無 //* 說明: 高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: 等待中斷,并且獲取中斷狀態(tài) //* 輸入?yún)?shù): 無 //* 輸出參數(shù):中斷狀態(tài) //* 說明: 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); // 產(chǎn)生操作完成中斷,獲取中斷狀態(tài) // PrintCom("\n 產(chǎn)生操作完成中斷,獲取中斷狀 \n"); for ( i = 1000; i!= 0; i -- ); return( CH376_RD_DAT_PORT( ) ); }

//***************************************************** //* NAME: Get_Dev_Descr( ) //* FUCTION: 獲取設(shè)備描述符 //* 輸入?yún)?shù): 無 //* 輸出參數(shù):成功返回1,否則返回0 //* 說明: 該程序采用外置固件模式獲取設(shè)備描述符 //******************************************************

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) //狀態(tài)階段操作成功 return(1); else return(0); }

//***************************************************** //* NAME: Get_Cfg_Descr( PUINT8 buf ) //* FUCTION: 獲取配置描述符 //* 輸入?yún)?shù): 接收緩沖區(qū)地址 //* 輸出參數(shù):成功返回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) //第二次獲取設(shè)備的配置描述符 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) //狀態(tài)階段操作成功 return(1); else return(0); }

//***************************************************** //* NAME: parse_config_descr( ) //* FUCTION: 簡單的分析配置描述符中的相關(guān)信息,并保存 //* 輸入?yún)?shù): 無 //* 輸出參數(shù):無 //* 說明: 保存設(shè)備的接口號,端點地址,報表長度,支持復(fù)合設(shè)備 //******************************************************

void parse_config_descr( ) { Device_Atti.Device_connect = 1; //表示設(shè)備連接 Device_Atti.Cfg_value = ((PUSB_CFG_DESCR)data_buf)->bConfigurationValue; //保留配置描述符中的配置值

if(((PUSB_CFG_DESCR)data_buf)->bNumInterfaces==1) //只有一個接口設(shè)備 { Device_Atti.Device_compat = 0; //非復(fù)合設(shè)備

#define HID_Dev ((PHID_DEVICE)data_buf) Device_Atti.Device[0].Device_type = HID_Dev->hid_itf_descr.bInterfaceProtocol; //設(shè)備類型:0x01 鍵盤,0x02 鼠標 Device_Atti.Device[0].Device_inf = HID_Dev->hid_itf_descr.bInterfaceNumber; //設(shè)備的接口號 Device_Atti.Device[0].Device_endp = HID_Dev->endp_descr.bEndpointAddress; //設(shè)備端點地址 Device_Atti.Device[0].Device_size = HID_Dev->endp_descr.wMaxPacketSize; //設(shè)備端點大小 Device_Atti.Device[0].Device_report_len = (HID_Dev->hid_class_descr.wDescriptorLength>>8)|(HID_Dev->hid_class_descr.wDescriptorLength<<8); //報表長度,大小端數(shù)據(jù)格式轉(zhuǎn)換 }

else if(((PUSB_CFG_DESCR)data_buf)->bNumInterfaces==2) //2個接口設(shè)備 { Device_Atti.Device_compat = 1; //復(fù)合設(shè)備

#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); //報表長度,大小端數(shù)據(jù)格式轉(zhuǎn)換 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); //報表長度,大小端數(shù)據(jù)格式轉(zhuǎn)換

}

}

//***************************************************** //* NAME: set_config( UINT8 cfg ) //* FUCTION: 配置USB設(shè)備 //* 輸入?yún)?shù): 配置值 //* 輸出參數(shù):操作狀態(tài) 成功返回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: 設(shè)置HID設(shè)備的IDLE //* 輸入?yún)?shù): 接口號 //* 輸出參數(shù):操作狀態(tài) 成功返回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數(shù)據(jù)總是8字節(jié) 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) //狀態(tài)階段操作成功 { 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類設(shè)備的報表描述符 //* 輸入?yún)?shù): 接口號,報表長度 //* 輸出參數(shù):操作狀態(tài) 成功返回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) //狀態(tài)階段操作成功 return(1); else return(0); }

//***************************************************** //* NAME: set_report( ) //* FUCTION: 對于鍵盤設(shè)備,則可以設(shè)置報表 //* 輸入?yún)?shù): 無 //* 輸出參數(shù):操作狀態(tài) 成功返回1 //* 說明: 可以通過設(shè)置報表,點亮鍵盤指示燈 //******************************************************

UINT8 set_report( ) { send_mode=0x00; WR_USB_DATA(8,SetupSetReport); //SETUP數(shù)據(jù)總是8字節(jié) 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) //狀態(tài)階段操作成功 { 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類設(shè)備的數(shù)據(jù) //* 輸入?yún)?shù): 該設(shè)備的同步標志,端點號 //* 輸出參數(shù):操作狀態(tài) //* 說明: 支持復(fù)合設(shè)備的操作 //******************************************************

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); //鍵盤中斷端點數(shù)據(jù)長度一般為8字節(jié),鼠標為4字節(jié) for(j=0;j!=t;j++) //條碼槍數(shù)據(jù)來源hdi解碼鍵盤碼轉(zhuǎn)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: 復(fù)位USB設(shè)備,并且將CH376設(shè)置成主機模式 //* 輸入?yún)?shù): 無 //* 輸出參數(shù):無 //* 說明: USB規(guī)范中未要求USB設(shè)備插入后必須復(fù)位該設(shè)備, //* 有些USB設(shè)備也要求在插入后必須先復(fù)位才能工作 //******************************************************

void Reset_Device( ) { Set_USB_Mode( 7 ); //復(fù)位USB設(shè)備,CH376向USB信號線的D+和D-輸出低電平 delay_ms(10); Set_USB_Mode( 6 ); //結(jié)束復(fù)位,將CH376設(shè)置成主機模式 while ( wait_interrupt()!=USB_INT_CONNECT ); //等待復(fù)位之后的設(shè)備端再次連接上來

}

//***************************************************** //* NAME: set_addr( UINT8 addr ) //* FUCTION: 設(shè)置USB設(shè)備地址,并且設(shè)置USB主機端要操作的USB設(shè)備地址 //* 輸入?yún)?shù): 地址值(1~127) //* 輸出參數(shù):操作狀態(tài) //* 說明: //******************************************************

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 ); //設(shè)置USB主機端的USB地址 CH376_WR_DAT_PORT( addr ); //當(dāng)目標USB設(shè)備的地址成功修改后,應(yīng)該同步修改主機端的USB地址 } return( status ); }

//********************************************** //* NAME: main( void ) //* FUCTION: 通過CH376操作鼠標鍵盤以及復(fù)合HID設(shè)備的數(shù)據(jù) //* 輸入?yún)?shù):無 //* 輸出參數(shù):無 //* 說明:只適用普通的USB鍵盤,支持復(fù)合設(shè)備 //* 鍵盤,不支持帶有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 ); //設(shè)置USB主機模式, 如果設(shè)備端是CH37X, 那么5和6均可 CH376_WR_CMD_PORT( 0x0a ); //檢測是全速設(shè)備還是低速設(shè)備 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(); //復(fù)位usb設(shè)備 delay_ms(50); // set_freq( ); //使376進入低速模式 CH376_WR_CMD_PORT( 0x0a ); //檢測是全速設(shè)備還是低速設(shè)備 CH376_WR_DAT_PORT( 0x07 ); check=CH376_RD_DAT_PORT(); if( check&0x10 ) { set_freq( ); // 切換使375B進入低速模式 // led3=0; } delay_ms(20);

//獲取設(shè)備描述符 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("設(shè)備描述符\n"); } else PrintCom("\n get device descr failed \n");

//設(shè)置地址 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; //保存配置描述符中設(shè)備信息 parse_config_descr( );

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

//設(shè)置HID類設(shè)備的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類設(shè)備的報表描述符 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類設(shè)備是鍵盤,則可以設(shè)置報表 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"); }

//如果該設(shè)備是復(fù)合設(shè)備,則需要配置另外一個接口設(shè)備 #if 1 if(Device_Atti.Device_compat == 1) { //設(shè)置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]);

}

//如果該設(shè)備是鍵盤,則可以設(shè)置報表 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 ); //設(shè)置CH376重試次數(shù) CH376_WR_DAT_PORT( 0x25 ); CH376_WR_DAT_PORT( 0x00 ); //為了保證兼容性對于部分鼠標鍵盤需要設(shè)置有限次重試(0xc0),而對于復(fù)合設(shè)備, //比如USB轉(zhuǎn)PS2的設(shè)備,復(fù)合鍵盤,則不需要重試(0x00)

Device_Atti.Device[0].tog = FALSE; //設(shè)置設(shè)備的同步標志,默認0 Device_Atti.Device[1].tog = FALSE; PrintCom("\n 主循環(huán) \n"); while(1) { //獲取設(shè)備1的數(shù)據(jù) 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); //如果該設(shè)備是符合設(shè)備,則需要獲取設(shè)備2的數(shù)據(jù) if( Device_Atti.Device_compat ) { PrintCom("\n 主循環(huán) \n"); s = get_int_in( Device_Atti.Device[1].tog,Device_Atti.Device[1].Device_endp); }

//以下是檢測設(shè)備插拔狀態(tài) CH376_WR_CMD_PORT(0x22);//獲取中斷并取消請求 //檢測設(shè)備插拔CMD01_GET_STATUS,0x22/* 獲取中斷狀態(tài)并取消中斷請求 */

tt = CH376_RD_DAT_PORT( );//讀回數(shù)據(jù)

if(tt == USB_INT_DISCONNECT )//判段是不是USB_INT_DISCONNECT,0x16/* 檢測到USB設(shè)備斷開事件 */ { Device_Atti.Device_connect = 0;

break;//設(shè)備斷開也就是跳出循環(huán)重新進入usb等待 }

} } }

首先你確保你前面枚舉部分都能正確獲取描述符,然后根據(jù)獲取到的配置描述符分析數(shù)據(jù)發(fā)送端點,然后在對應(yīng)端點獲取數(shù)據(jù)。


只有登錄才能回復(fù),可以選擇微信賬號登錄

国产91精品新入口,国产成人综合网在线播放,九热这里只有精品,本道在线观看,美女视频a美女视频,韩国美女激情视频,日本美女pvp视频