我用Ch375控制usb打印机,在发送数据时,模拟了沁恒的发送函数,如下: UINT8 SendUsbData( UINT16 len, UINT8 *buf ) { UINT8 length, rstatus; while(!CheckPrtStatus()) { if(TestConnect() == USB_INT_DISCONNECT) return; DelayNms(10); } while( len ) //连续输出数据块给USB打印机 { length = len >= device_info.endp_out_size ? device_info.endp_out_size : len; //单次发送不能超过端点尺寸 ToggleSend( device_info.tog_send ); WriteUsbData( length, buf ); // 将数据先复制到CH375芯片中 rstatus = IssueToken( ( device_info.endp_out_addr << 4 ) | DEF_USB_PID_OUT ); if(rstatus==USB_INT_SUCCESS) { len -= length; // 计数 buf += length; device_info.tog_send = ~ device_info.tog_send; } else {// 操作失败 SoftRestPrint(); // 打印机出现意外错误,软复位 ClearStall(device_info.endp_out_addr); device_info.tog_send = 0; // 操作失败 } } } 当我的数据大于64B时,调试没有任何问题。但是当我的数据小于64字节时,连续发送,打印机只能收到一次。请问这是为什么? 例如: for(i=0; i<20; i++) SendUsbData( 32, buf ); 打印机只收到32字节数据; for(i=0; i<20; i++) SendUsbData( 128, buf ); 可以收到全部数据。
批量传输每次都必须以满包发送(满包大小由打印机的批量端点大小决定),只有最后一次可以为非满包。假如满包大小为64,若包小于64字节,那么打印机则认为本次传输结束。...(先前解释有误,更正: 如果本次传输结束,仍然要切换同步标志,再进行下一次传输)
哦,原来如此。可是我改成如下: UINT8 SendUsbData( UINT16 len, UINT8 *buf ) { UINT8 length, rstatus; while(!CheckPrtStatus()) { if(TestConnect() == USB_INT_DISCONNECT) return; DelayNms(10); } while( len ) //连续输出数据块给USB打印机 { length = len >= device_info.endp_out_size ? device_info.endp_out_size : len; //单次发送不能超过端点尺寸 ToggleSend( device_info.tog_send ); WriteUsbData( length, buf ); // 将数据先复制到CH375芯片中 rstatus = IssueToken( ( device_info.endp_out_addr << 4 ) | DEF_USB_PID_OUT ); if(rstatus==USB_INT_SUCCESS) { len -= length; // 计数 buf += length; if(len > 0) //如果小于64字节,不发送DATA1 device_info.tog_send = ~ device_info.tog_send; } else {// 操作失败 ClearStall(device_info.endp_out_addr); SoftRestPrint(); // 打印机出现意外错误,软复位 device_info.tog_send = 0; // 操作失败 } } } 怎么还是不可以? 这样的话,我该如何启用下一次传送?
另外,每次发送前,调用一次ClearStall(device_info.endp_out_addr);就没有问题了。 可是这不是个解决问题的好办法。主要怕量产后稳定性差。
都改成这样了,还是不行。我该怎么办?帮我想想办法好吗? UINT8 SendUsbData( UINT16 len, UINT8 *buf ) { UINT8 length, rstatus; while(!CheckPrtStatus()) { if(TestConnect() == USB_INT_DISCONNECT) return; DelayNms(10); } while( len ) //连续输出数据块给USB打印机 { length = len >= device_info.endp_out_size ? device_info.endp_out_size : len; //单次发送不能超过端点尺寸 //ToggleSend( device_info.tog_send ); ToggleSend( 0); WriteUsbData( length, buf ); // 将数据先复制到CH375芯片中 rstatus = IssueToken( ( device_info.endp_out_addr << 4 ) | DEF_USB_PID_OUT ); if(rstatus==USB_INT_SUCCESS) { len -= length; // 计数 buf += length; //device_info.tog_send = ~ device_info.tog_send; } else {// 操作失败 ClearStall(device_info.endp_out_addr); SoftRestPrint(); // 打印机出现意外错误,软复位 device_info.tog_send = 0; // 操作失败 } } }
自己顶一下,烦请沁恒多留意一下,快点给个答复。谢谢了!
IssueToken( ( device_info.endp_out_addr << 4 ) | DEF_USB_PID_OUT ); 执行完之后,返回的错误代码是什么?对照CH375DS1的说明,分析原因
返回0x14,没有问题呀,就是打印机只能收到前32个数据。你们有试验过发送小于64字节的数据吗? 下面是我用串口返回的数据: 44 65 76 69 63 65 20 43 6C 61 73 73 3A 0A 0D 75 73 62 20 50 72 69 6E 74 65 72 2E 0A 0D 55 73 62 20 56 65 72 73 69 6F 6E 3A 0A 0D 30 31 2E 31 30 20 0A 0D 54 68 65 20 70 61 63 6B 65 74 20 73 69 7A 65 20 69 73 3A 0A 0D 30 30 34 30 42 79 74 65 0A 0D 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14 14
怎么没有人回复呢?
你说的返回的0X14的状态码是哪个给你返回的?还有就是你第一次返回的状态码是多少?你串口发送的状态码是打印机端的还是主机端的?
哦,是我说的不明白。我是通过超级终端观察程序运行情况的。实验板和ouravr上阿永的mp3板(不知道版主是否见过此板,广东地区ch375芯片最初应该就是阿莫推荐的)ch375部分接法一致,通过并口控制ch375。
我在 rstatus = IssueToken( ( device_info.endp_out_addr << 4 ) | DEF_USB_PID_OUT ); 后加入了 一句putchar(rstatus ); 如下: UINT8 SendUsbData( UINT16 len, UINT8 *buf ) { UINT8 length, rstatus; while(!CheckPrtStatus()) { if(TestConnect() == USB_INT_DISCONNECT) return; DelayNms(10); } while( len ) //连续输出数据块给USB打印机 { length = len >= device_info.endp_out_size ? device_info.endp_out_size : len; //单次发送不能超过端点尺寸 //ToggleSend( device_info.tog_send ); ToggleSend( 0 ); WriteUsbData( length, buf ); // 将数据先复制到CH375芯片中 rstatus = IssueToken( ( device_info.endp_out_addr << 4 ) | DEF_USB_PID_OUT ); //==================================================================================== Putchar(rstatus); //此处返回状态码:0x14 //==================================================================================== if(rstatus==USB_INT_SUCCESS) { len -= length; // 计数 buf += length; //device_info.tog_send = ~ device_info.tog_send; } else {// 操作失败 ClearStall(device_info.endp_out_addr); SoftRestPrint(); // 打印机出现意外错误,软复位 device_info.tog_send = 0; // 操作失败 } } } 我在ch375并口上也D0到D7也读到了正确数据,可打印机就是接受不到。缓冲改为64字节以上就没有问题了。 可惜我不能给它分配这么大内存。 执行这句for(i=0; i<20; i++) SendUsbData( 32, buf );可以得到20个状态码0x14。 恳请帮忙分析一下。
找到答案了,不过好像解释很牵强,如下 UINT8 SetupStage(flash UINT8 *pag)//设置事务 { //device_info.tog_send=device_info.tog_recv=0;//复位USB数据同步标志 ToggleSend(0);//发送 WriteUsbFlashData(8,pag);//SETUP数据总是8字节 return (IssueToken((0<<4)|DEF_USB_PID_SETUP)); } 删除此句:device_info.tog_send=device_info.tog_recv=0;//复位USB数据同步标志 就没有问题。故我认为: 1、数据DATA0,DATA1切换,不一定要够64字节才可以,只要你乐意,发送一个字换一次都行,我查了usb协议,没有提到对DATA0/DATA1切换时包大小的要求(或者我没有看到); 2、如果批量发送数据,发送完DATA0,就要发送DATA1,故沁恒提供的设置同步标志函数不够严谨,动不动就更改了同步标志;
我的理解不知道是否正确。不知道沁恒有没有做过类似的试验?应该给个明确的答复啊!
你上面的理解没有任何问题啊,但是我们的程序就是按照你说的那样写的啊,你每次写的时候都需要给一个同步标志的。
你好,我也在做USB打印机的程序,请问一下,你用的是什么型号的打印机? 我的联系方法是个人信息保护,已隐藏,希望能够交流一下