晶振的频率问题

如果你不理解USB协议,那么协议栈部分建议你别去修改.否则很麻烦.控制传输部分按照我们的程序去做就可以了.如果设备驱动都没有安装成功,你抓取的数据是没有意义的.除非你有比较低层的USB总线分析仪.


请问在端点0的SETUP阶段时,端点0需要发送18个字节,那么数据送入发送缓冲区后,如何通知芯片开始传输?发送8个字节后,缓冲区会不会清空?在发送前后与之相关的寄存器有哪些变化?因为我发现中断标志寄存器的BIT_IF_TRANSFER 位一直为1,不知道是什么问题?


(1)数据送入发送缓冲区后,则等待PC发送IN事务来取,单片机端不需要关系何时传输,缓冲区不会清空 (2)REG_INTER_FLAG、REG_USB_STATUS会有变化,BIT_IF_TRANSFER表示传输完成,即CH374已收到或发送数据,如果有数据数据收发,那么为1是正常的,下载CH374EVT.ZIP,参考例程就可以了。


先说下现在的具体情况,那就是打印机连上PC后,收到主机一个中断,这时按照USB协议,应该返回18个字节的数据,说明现在设备的状态,但是在发送完8个字节之后却没有任何中断了。由于编程环境是在Linux下,中断程序在逻辑功能上是按Device.c设计的,会不会跟硬件有关?同时用调试信息跟踪发现中断标志寄存器中的数据为0xd9,清中断之后还是为0xd9,这是什么原因?


实际上这8个字节是没有发出去的,如果发出去,则一定会产生端点0上传完成中断.没有上传完成有可能SETUP包没有应答好.或者端点0上传没有启动.基本也就是这两个问题. 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 } 这句话有没有进去执行呢?


这句话有写,不知道有没有执行。不过有个疑问那就是清中断之前中断标志寄存器中的数据为0xd9,清中断之后还是为0xd9,这是什么原因?


如果是这个中断,那前面的SETUP包是怎么接收到的呢?明显设备挂起了. 首先你务必确保可以正常的读写寄存器.否则初始话都不正确.建议你验证一下. 你把代码以附件的形式贴出来,看看代码流程有没有问题.另外你检测一下,产生中断的顺序是什么.


寄存器的读写都是正确的,程序改了,完全是按示例程序写的,有个问题一直存在就是不能清除中断


你的CH374的UEN引脚(第5脚)是怎么接的,我们提供的例程当中,对应的UEN引脚是悬空的


该引脚(pin5)我们是接了3.3V的电压,整个芯片是3.3V供电的


你用的是CH374T 应该没有什么问题。检查你的程序的流程,或者把程序发到技术支持信箱tech@wch.cn


static void usbRX_Handler(int irq, void *dev_id, struct pt_regs *regs) { unsigned char s = 0; unsigned char *tmpBuf; unsigned short retLen;

s=Read374Byte( REG_INTER_FLAG ); if (s & BIT_IF_BUS_RESET ) { // Reset device irq flag // USB总线复位

Write374Byte( REG_USB_ADDR, 0x00 ); Write374Byte( REG_USB_ENDP0, M_SET_EP0_TRAN_NAK( 0 ) ); Write374Byte( REG_USB_ENDP1, M_SET_EP1_TRAN_NAK( 0 ) ); Write374Byte( REG_USB_ENDP2, M_SET_EP2_TRAN_NAK( 0 ) ); Write374Byte( REG_INTER_FLAG, BIT_IF_USB_PAUSE | BIT_IF_INTER_FLAG ); // 清所有中断标志 CH_BusReset(); } else if (s & BIT_IF_TRANSFER) { switch( s & BIT_STAT_PID_ENDP ) { // USB设备中断状态 case USB_INT_EP2_OUT: { // 批量端点下传成功 CH374_ep02_rx(); break; } case USB_INT_EP2_IN: { // 批量端点上传成功,未处理 CH374_ep02_tx(); break; } case USB_INT_EP1_IN: { // 中断端点上传成功,未处理 CH374_ep01_tx(); break; } case USB_INT_EP0_SETUP: { // 控制传输 Write374Byte( REG_USB_ENDP0, M_SET_EP0_TRAN_ACK( M_SET_EP0_RECV_ACK( Read374Byte( REG_USB_ENDP0 )), 0x08)|BIT_EP0_TRAN_TOG ); // DATA1 Write374Byte( REG_INTER_FLAG, BIT_IF_USB_PAUSE | BIT_IF_TRANSFER ); break; } case USB_INT_EP0_IN: { struct usb_endpoint_instance *endpoint; endpoint = ep_endpoints[0]; tmpBuf = endpoint->tx_urb->buffer + endpoint->last; retLen = CH374_WriteEndpoint(USB_INT_EP0_IN,tmpBuf,endpoint->tx_urb->actual_length-endpoint->last); endpoint->last += retLen; Write374Byte( REG_USB_ENDP0, M_SET_EP0_TRAN_ACK( M_SET_EP0_RECV_ACK( Read374Byte( REG_USB_ENDP0 ) ), retLen ) ^ BIT_EP0_TRAN_TOG ); // DATA1 Write374Byte( REG_INTER_FLAG, BIT_IF_USB_PAUSE | BIT_IF_TRANSFER ); break; } case USB_INT_EP0_OUT: { break; } default: { break; } } Write374Byte( REG_INTER_FLAG, BIT_IF_USB_PAUSE | BIT_IF_TRANSFER ); // 清中断标志 } else if (s & BIT_IF_USB_SUSPEND) { Write374Byte( REG_INTER_FLAG, BIT_IF_USB_PAUSE | BIT_IF_USB_SUSPEND ); // 清中断标志 Write374Byte( REG_SYS_CTRL, Read374Byte( REG_SYS_CTRL ) | BIT_CTRL_OSCIL_OFF ); // 时钟振荡器停止振荡,进入睡眠状态 }

else if (s & BIT_IF_WAKE_UP) { Write374Byte( REG_INTER_FLAG, BIT_IF_USB_PAUSE | BIT_IF_WAKE_UP ); // 清中断标志 usbd_device_event(udc_device, DEVICE_BUS_ACTIVITY, 0);

} else { // 意外的中断,不可能发生的情况,除了硬件损坏 //对照ch374添加 Write374Byte( REG_INTER_FLAG, BIT_IF_USB_PAUSE | BIT_IF_INTER_FLAG ); // 清中断标志 } }


case USB_INT_EP0_SETUP: { // 控制传输 Write374Byte( REG_USB_ENDP0, M_SET_EP0_TRAN_ACK( M_SET_EP0_RECV_ACK( Read374Byte( REG_USB_ENDP0 )), 0x08)|BIT_EP0_TRAN_TOG ); // DATA1 Write374Byte( REG_INTER_FLAG, BIT_IF_USB_PAUSE | BIT_IF_TRANSFER ); break; } 这边怎么没有上传数据?你要把数据写到缓冲区里面啊,怎么没有写数据直接就传了,那上传什么样的数据呢?程序中好象看不到


原来是这样的 case USB_INT_EP0_SETUP: { // 控制传输 struct usb_endpoint_instance *endpoint; endpoint = ep_endpoints[0]; endpoint->ep0_interrupts++; Write374Byte( REG_USB_ENDP0, M_SET_EP0_TRAN_ACK( M_SET_EP0_RECV_ACK( Read374Byte( REG_USB_ENDP0 )), 0x08)|BIT_EP0_TRAN_TOG ); // DATA1 Write374Byte( REG_INTER_FLAG, BIT_IF_USB_PAUSE | BIT_IF_TRANSFER ); break; }


endpoint->ep0_interrupts++;

//在这里你读一下RAM_ENDP0_TRAN这个缓冲区,看看数据是否被你写进去了.

Write374Byte( REG_USB_ENDP0, M_SET_EP0_TRAN_ACK( M_SET_EP0_RECV_ACK( Read374Byte( REG_USB_ENDP0 )), 0x08)|BIT_EP0_TRAN_TOG ); // DATA1 USB控制传输部分我们已经写好了,而且流程正确,建议不要这样修改,会您的浪费时间.你你这样写还要加很多代码. 前面已经告诉你,你只要把374读写完成,直接用我们提供的函数就可以了.不会有什么问题的.如果数据根本没有写进去的话,PC上会出现无法识别的设备.怀疑你这种方式是怎么写进去数据的.


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