各位好 我原来用CH374S做了键盘 用到现在很正常 这次想添加接收PC的NUMLOCK SCROLLLOCK灯的状态 该如何入手 有没有例程可提供啊 谢谢各位啦
你可以到这个里面去下载例子程序: /bbs/View.asp?S=101&I=19463 发送SET_REPORT命令就可以点灯了。
链接里的都是作为主机来点灯的例子,我想要的是有没有作为设备接收点灯信号的例子
引用回复: 各位好 我原来用CH374S做了键盘 用到现在很正常 这次想添加接收PC的NUMLOCK SCROLLLOCK灯的状态 该如何入手 有没有例程可提供啊 谢谢各位啦
在接收到PC的set_report中断后该怎么做,在下面的中断程序中怎么改 void USB_DeviceInterrupt( void ) { UCHAR8 s, l,j; static UCHAR8 SetupLen,SetupReq,i=0,k=0; static PUINT8 pDescr; s = Read374Byte( REG_INTER_FLAG ); // 获取中断状态 if ( s & BIT_IF_BUS_RESET )// USB总线复位 { Write374Byte( REG_USB_ADDR, 0x00 ); // 清USB设备地址 Write374Byte( REG_USB_ENDP0, M_SET_EP0_TRAN_NAK( 0 ) );//清端点0缓冲区 Write374Byte( REG_USB_ENDP1, M_SET_EP1_TRAN_NAK( 0 ) );//清端点1缓冲区 Write374Byte( REG_USB_ENDP2, M_SET_EP2_TRAN_NAK( 0 ) );//清端点2缓冲区 Write374Byte( REG_INTER_FLAG, BIT_IF_USB_PAUSE | BIT_IF_BUS_RESET ); // 清中断标志 } else if ( s & BIT_IF_TRANSFER ) // USB传输完成 { s = Read374Byte( REG_USB_STATUS ); //获取中断状态 switch( s & BIT_STAT_PID_ENDP ) //分析USB设备中断状态;本例未用端点2;所以就不包含端点2的中断事务 { case USB_INT_EP2_OUT: // 批量端点下传成功 { if ( s & BIT_STAT_TOG_MATCH ) // 仅同步包 { l = Read374Byte( REG_USB_LENGTH ); Read374Block( RAM_ENDP2_RECV, l, gBuf ); } break; } case USB_INT_EP2_IN:// 批量端点上传成功,未处理 { Write374Byte( REG_USB_ENDP2, M_SET_EP2_TRAN_NAK( Read374Byte( REG_USB_ENDP2 ) ) ^ BIT_EP2_TRAN_TOG ); break; } case USB_INT_EP1_IN:// 中断端点上传成功,未处理 { Write374Byte( REG_USB_ENDP1, M_SET_EP1_TRAN_NAK( Read374Byte( REG_USB_ENDP1 ) ) ^ BIT_EP1_TRAN_TOG ); break; } case USB_INT_EP1_OUT: // 端点1下传成功,未处理 { Write374Byte( REG_USB_ENDP1, M_SET_EP1_TRAN_NAK( Read374Byte( REG_USB_ENDP1 ) ) ^ BIT_EP1_TRAN_TOG ); break; } case USB_INT_EP0_SETUP: // 端点0下传成功 { // USB_SETUP_REQ SetupReqBuf; //定义结构体,存储接收的主机命令,结构体的说明在头文件中 l = Read374Byte( REG_USB_LENGTH ); //首先读取的是数据的长度;因为数据传输首先传输的就是数据长度; if ( l == sizeof( USB_SETUP_REQ ) ) { //sizeof( USB_SETUP_REQ )求出的长度应该为8 //按协议,只有长度为8的命令才算是USB主机发送的命令 Read374Block( RAM_ENDP0_RECV, l, (PUINT8)&SetupReqBuf ); //读取数据放入结构体中 SetupLen = SetupReqBuf.wLengthL; if ( SetupReqBuf.wLengthH || SetupLen > 0x7F ) { SetupLen = 0x7F; // 限制总长度 } l = 0; // 默认为成功并且上传0长度 if ( SetupReqBuf.bType==0x40) { //厂商请求,未处理 } if ( SetupReqBuf.bType&0x20 ) {//类请求,未处理 if( SetupReqBuf.bReq==0x0a ) { } if( SetupReqBuf.bReq==0x09 ) { SetupReq = 0x09; // Read374Block( RAM_ENDP0_RECV , 1, gInBuf ); // 演示回传,使用端点0的中断传输 // Write374Block( RAM_ENDP0_TRAN, l, pDescr ); /* 加载上传数据 */ // Write374Byte( REG_USB_ENDP0, M_SET_EP1_RECV_ACK( Read374Byte( REG_USB_ENDP1 ) ) ^ BIT_EP1_TRAN_TOG ); // Write374Byte( REG_USB_ENDP0, M_SET_EP1_RECV_ACK( Read374Byte( REG_USB_ENDP1 ) ) ); if(gInBuf[0]!=0) { Delay1ms(100); } } } else if ( ( SetupReqBuf.bType & DEF_USB_REQ_TYPE )== DEF_USB_REQ_STAND ) { // 标准请求 SetupReq = SetupReqBuf.bReq; // 请求码 switch( SetupReq ) { case DEF_USB_GET_DESCR: { switch( SetupReqBuf.wValueH ) {//获取描述符的偏移量和描述符的长度 case 1: { pDescr = (PUINT8)( &MyDevDescr[0] ); l = sizeof( MyDevDescr ); break; } case 2: { pDescr = (PUINT8)( &MyCfgDescr[0] ); l = sizeof( MyCfgDescr ); break; } case 34: { pDescr = (PUINT8)( &Hid_des[0] ); l = sizeof( Hid_des ); break; } default: { l = 0xFF; // 操作失败 break; } } if ( SetupLen > l ) SetupLen = l; // 限制总长度 l = SetupLen >= RAM_ENDP0_SIZE ? RAM_ENDP0_SIZE : SetupLen; // 本次传输长度 Write374Block( RAM_ENDP0_TRAN, l, pDescr ); /* 加载上传数据 */ SetupLen -= l; pDescr += l; break; } case DEF_USB_SET_ADDRESS: { SetupLen = SetupReqBuf.wValueL; // 暂存USB设备地址 break; } case DEF_USB_GET_CONFIG: { Write374Byte( RAM_ENDP0_TRAN, UsbConfig ); if ( SetupLen >= 1 ) l = 1; break; } case DEF_USB_SET_CONFIG: { UsbConfig = SetupReqBuf.wValueL; break; } case DEF_USB_CLR_FEATURE: { if ( ( SetupReqBuf.bType & 0x1F ) == 0x02 ) { // 不是端点不支持 switch( SetupReqBuf.wIndexL ) {//对于CLR_FEATURE命令按照不同的端点,置位端点的发送或者接收状态 case 0x82: { Write374Byte( REG_USB_ENDP2, M_SET_EP2_TRAN_NAK( Read374Byte( REG_USB_ENDP2 ) ) ); break; } case 0x02: { Write374Byte( REG_USB_ENDP2, M_SET_EP2_RECV_ACK( Read374Byte( REG_USB_ENDP2 ) ) ); break; } case 0x81: { Write374Byte( REG_USB_ENDP1, M_SET_EP1_TRAN_NAK( Read374Byte( REG_USB_ENDP1 ) ) ); break; } case 0x01: { Write374Byte( REG_USB_ENDP1, M_SET_EP1_RECV_ACK( Read374Byte( REG_USB_ENDP1 ) ) ); break; } default: { l = 0xFF; // 操作失败 break; } } } else l = 0xFF; // 操作失败 break; } case DEF_USB_GET_INTERF: { Write374Byte( RAM_ENDP0_TRAN, 0 ); // 上传接口号 if ( SetupLen >= 1 ) l = 1; break; } case DEF_USB_GET_STATUS: { Write374Byte( RAM_ENDP0_TRAN, 0 ); Write374Byte( RAM_ENDP0_TRAN + 1, 0 ); if ( SetupLen >= 2 ) l = 2; else l = SetupLen; break; } default: { l = 0xFF; // 操作失败 break; } } } //else l=0xff; } else // 操作失败 { l = 0xFF; } if ( l == 0xFF )// 操作失败 { Write374Byte( REG_USB_ENDP0, M_SET_EP0_RECV_STA( M_SET_EP0_TRAN_STA( 0 ) ) ); // STALL } else if ( l <= RAM_ENDP0_SIZE )// 上传数据 { Write374Byte( REG_USB_ENDP0, M_SET_EP0_TRAN_ACK( M_SET_EP0_RECV_ACK( Read374Byte( REG_USB_ENDP0 ) ), l ) | BIT_EP0_TRAN_TOG ); // DATA1 } else // 下传数据或其它 { Write374Byte( REG_USB_ENDP0, M_SET_EP0_TRAN_NAK( M_SET_EP0_RECV_ACK( Read374Byte( REG_USB_ENDP0 ) ) ) | BIT_EP0_RECV_TOG ); // DATA1 } break; } case USB_INT_EP0_IN: { switch( SetupReq ) { case DEF_USB_GET_DESCR: { l = SetupLen >= RAM_ENDP0_SIZE ? RAM_ENDP0_SIZE : SetupLen; // 本次传输长度 Write374Block( RAM_ENDP0_TRAN, l, pDescr ); // 加载上传数据 SetupLen -= l; pDescr += l; Write374Byte( REG_USB_ENDP0, M_SET_EP0_TRAN_ACK( Read374Byte( REG_USB_ENDP0 ), l ) ^ BIT_EP0_TRAN_TOG );//同步切换 break; } case 0x09: { goto ag; } case DEF_USB_SET_ADDRESS: { Write374Byte( REG_USB_ADDR, SetupLen ); } default: { ag: Write374Byte( REG_USB_ENDP0, M_SET_EP0_TRAN_NAK( 0 ) ); // 结束
已经搞定了 通过仿真 找到了收发信息的步骤 现已解决 谢谢
不过还有一个问题,为什么设置Set_Report()键盘数字灯只是亮一下 就熄灭了 请问什么原因, buf[0]=LED_SCRL*4+LED_CAPS*2+LED_NUM; s=Set_Report(buf); //设置报表 if(s==USB_INT_SUCCESS) { printf("Set_Report success\n"); } else { printf("Set_Report Err=%02x\n",(unsigned short)s); //设置报告出错 //if(s&0x0f==USB_INT_RET_STALL) goto next_operate2; //返回STALL可能本身不支持 }
PC发来Set_Report(),你接收数据,怎么点灯是您软件做的事情
例子里面不是有点灯的范例么?!