/******************************************Copyright(C)WCH1999-2009****Web:********************************************USB1.1HostExamplesforCH376****KC7.0@MCS-51****Version:v1.0****Author:tech14****Time:2009/11/18*******************************************//*用CH376操作HID设备,比如键盘,鼠标,兼容HID复合设备*/#includestdio.h#includereg52.h#includestring.h#includeCH376INC.H#includehid.h//获取设备描述符constunsignedcharcodeSetupGetDevDescr[]={0x80,0x06,0x00,0x01,0x00,0x00,0x12,0x00};//获取配置描述符constunsignedcharcodeSetupGetCfgDescr[]={0x80,0x06,0x00,0x02,0x00,0x00,0x09,0x00};//设置USB地址constunsignedcharcodeSetupSetUsbAddr[]={0x00,0x05,0x02,0x00,0x00,0x00,0x00,0x00};//设置USB配置//constunsignedcharcodeSetupSetUsbConfig[]={0x00,0x09,0x00,0x00,0x00,0x00,0x00,0x00};//SETIDLEconstunsignedcharcodeSetupSetidle[]={0x21,0x0a,0x00,0x00,0x00,0x00,0x00,0x00};//获取HID报告描述符constunsignedcharcodeSetupGetHidDes[]={0x81,0x06,0x00,0x22,0x00,0x00,0x81,0x00};//SETREPORTconstunsignedcharcodeSetupSetReport[]={0x21,0x09,0x00,0x02,0x00,0x00,0x01,0x00};//单片机总线方式操作CH376#defineCH376_CMD_PORT*(unsignedcharvolatilexdata*)0xBDF1#defineCH376_DAT_PORT*(unsignedcharvolatilexdata*)0xBCF0#defineCH376_INT_WIREINT0//定义CH376中断引脚,可省略;struct_Device_Atti{UINT8Device_connect;//设备连接状态1:连接,0:断开UINT8Device_compat;//0:非复合设备,1表示复合设备UINT8Cfg_value;//设备配置描述符中配置值struct_Device{UINT8Device_type;//设备类型1:键盘,2:鼠标UINT8Device_inf;//设备接口号默认为0最多支持两个接口设备UINT8Device_endp;//设备端点地址最多支持一个端点UINT8Device_size;//设备端点大小UINT16Device_report_len;//设备报表长度UINT8tog;//端点的同步标志}Device[2];}Device_Atti={0};UINT8receive_mode=0x00,send_mode=0x00;UINT8data_buf[160];UINT8status;bitflag_config_2;//第二次获取配置描述符标志UINT8report_cou;//实际获取的报表长度//**********************************************//*NAME:mDelay2uS()//*FUCTION:延时2us子函数//*输入参数:无//*输出参数:无//*说明:根据单片机的主频进行调整//**********************************************voidmDelay2uS(){UINT8i;for(i=1;i!=0;i--);}//**********************************************//*NAME:mDelay50mS()//*FUCTION:延时50ms子函数//*输入参数:无//*输出参数:无//*说明:根据单片机的主频进行调整//**********************************************voidmDelay50mS(){UINT8i,j;for(i=250;i!=0;i--)for(j=250;j!=0;j--);}voidmDelaymS(UINT8delay){unsignedchari;do{for(i=0;i!=250;i++){;}for(i=0;i!=250;i++){;}for(i=0;i!=150;i++){;}}while(--delay);}//**********************************************//*NAME:CH376_WR_CMD_PORT(UINT8cmd)//*FUCTION:写CH376命令子函数//*输入参数:8位命令码//*输出参数:无//*说明:对于速度较快的单片机,则需要1.5uS延时//**********************************************voidCH376_WR_CMD_PORT(UINT8cmd){CH376_CMD_PORT=cmd;//mDelay2uS();//对于高速单片机需要2us的延时}//**********************************************//*NAME:CH376_WR_DAT_PORT(UINT8dat)//*FUCTION:写CH376数据子函数//*输入参数:8位数据//*输出参数:无//*说明:对于速度较快的单片机,则需要0.6uS延时//**********************************************voidCH376_WR_DAT_PORT(UINT8dat){CH376_DAT_PORT=dat;}//**********************************************//*NAME:CH376_RD_DAT_PORT(void)//*FUCTION:读CH376数据子函数//*输入参数:无//*输出参数:8位数据//*说明:对于速度较快的单片机,则需要0.6uS延时//**********************************************UINT8CH376_RD_DAT_PORT(void){return(CH376_DAT_PORT);}//**********************************************//*NAME:StdioInit(void)//*FUCTION:单片机串口初始化,用于检测程序//*输入参数:无//*输出参数:无//*说明:单片机主频24M使用定时器1波特率9600//**********************************************voidStdioInit(){SCON=0x50;PCON=0x80;TL2=RCAP2L=0-12;/*22.1184MHz晶振,57600bps*/TH2=RCAP2H=0xFF;T2CON=0x34;/*定时器2用于串口的波特率发生器*/TI=1;}//**********************************************//*NAME:Set_USB_Mode(UINT8mode)//*FUCTION:设置CH376的工作模式0x06为主机模式//*输入参数:模式代码//*输出参数:操作状态TRUE:成功,FALSE失败//*说明:设置CH376的工作模式//**********************************************UINT8Set_USB_Mode(UINT8mode){UINT8i;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++){//等待设置模式操作完成,不超过30uSif(CH376_RD_DAT_PORT()==CMD_RET_SUCCESS)return(TRUE);//成功}return(FALSE);//CH376出错,例如芯片型号错或者处于串口方式或者不支持}//*****************************************************//*NAME:set_freq(void)//*FUCTION:设置CH376的进入低速模式//*输入参数:无//*输出参数:无//*说明:对于鼠标键盘等低速设备,要先设置ch376为低速模式//******************************************************voidset_freq(void){CH376_WR_CMD_PORT(0x0b);//切换使375B进入低速模式CH376_WR_DAT_PORT(0x17);CH376_WR_DAT_PORT(0xd8);}//*****************************************************//*NAME:RD_USB_DATA(UINT8*buf)//*FUCTION:从CH376的端点缓冲区读取接收到的数据//*输入参数:数据缓冲区的地址//*输出参数:返回接收的数据长度//*说明:从CH376的主机端点缓冲区中读取接收到的数据//******************************************************UINT8RD_USB_DATA(UINT8*buf){UINT8i,len;CH376_WR_CMD_PORT(CMD01_RD_USB_DATA0);//从CH37X读取数据块len=CH376_RD_DAT_PORT();//后续数据长度for(i=0;i!=len;i++)*buf++=CH376_RD_DAT_PORT();return(len);}//*****************************************************//*NAME:WR_USB_DATA(UINT8len,UINT8*buf)//*FUCTION:往CH376的端点缓冲区写入数据块//*输入参数:要写入数据块的长度,写入数据缓冲区的地址//*输出参数:无//*说明:往CH376的主机端点缓冲区中写入要发送的数据块//******************************************************voidWR_USB_DATA(UINT8len,UINT8*buf){CH376_WR_CMD_PORT(CMD10_WR_HOST_DATA);//向CH376的端点缓冲区写入准备发送的数据CH376_WR_DAT_PORT(len);//后续数据长度,len不能大于64while(len--)CH376_WR_DAT_PORT(*b