CH375驱动HP-1022激光打印机的问题???

你将你的打印机接在1.1的计算机上,看发的数据和你在单片机里的数据是不是一样,看下有没有打印机给计算机返回数据之类的数据


你用我们的CH375HST.ZIP文件是什么时间的,因为我们的这个文件已经更新过,要不你发个邮件将你的程序发过来帮你查下.


这个文件(CH375HST.ZIP)那里有的下载?个人信息保护,已隐藏


在网站上面就有下载


是用网上最新的那个呀 /* 2004.03.05, 2004.8.18, 2005.12.29 **************************************** ** Copyright (C) W.ch 1999-2005 ** ** Web: http://www.winchiphead.com ** **************************************** ** USB 1.1 Host Examples for CH375 ** ** KC7.0@MCS-51 ** **************************************** */ /* 单片机通过CH375控制USB打印机 */ /* 程序示例,C语言,CH375中断为查询方式,只负责数据传输,不涉及打印格式及打印描述语言 */ /* 另可提供多台计算机共享一台USB打印机的方案 */

/* 以下定义适用于MCS-51单片机,其它单片机参照修改,为了提供C语言的速度需要对本程序进行优化 */ #include unsigned char volatile xdata CH375_CMD_PORT _at_ 0xf001;//0xBDF1; /* CH375命令端口的I/O地址 */ unsigned char volatile xdata CH375_DAT_PORT _at_ 0xf000;//0xBCF0; /* CH375数据端口的I/O地址 */ sbit CH375_INT_WIRE = 0xB0^4; /* P3.2, INT0, 连接CH375的INT#引脚,用于查询中断状态 */ unsigned char volatile xdata bell _at_ 0x8001;//蜂 unsigned char volatile xdata pio1cm _at_ 0x8003; typedef unsigned char BOOL1; /* typedef bit BOOL1; */

/* 以下为通用的单片机C程序 */ #include #include

/* 定义CH375命令代码及返回状态 */ #include "CH375INC.H" void be(); typedef unsigned char UCHAR; typedef unsigned short USHORT;

typedef struct _USB_DEVICE_DESCRIPTOR { UCHAR bLength; UCHAR bDescriptorType; USHORT bcdUSB; UCHAR bDeviceClass; UCHAR bDeviceSubClass; UCHAR bDeviceProtocol; UCHAR bMaxPacketSize0; USHORT idVendor; USHORT idProduct; USHORT bcdDevice; UCHAR iManufacturer; UCHAR iProduct; UCHAR iSerialNumber; UCHAR bNumConfigurations; } USB_DEV_DESCR, *PUSB_DEV_DESCR;

typedef struct _USB_CONFIG_DESCRIPTOR { UCHAR bLength; UCHAR bDescriptorType; USHORT wTotalLength; UCHAR bNumInterfaces; UCHAR bConfigurationValue; UCHAR iConfiguration; UCHAR bmAttributes; UCHAR MaxPower; } USB_CFG_DESCR, *PUSB_CFG_DESCR;

typedef struct _USB_INTERF_DESCRIPTOR { UCHAR bLength; UCHAR bDescriptorType; UCHAR bInterfaceNumber; UCHAR bAlternateSetting; UCHAR bNumEndpoints; UCHAR bInterfaceClass; UCHAR bInterfaceSubClass; UCHAR bInterfaceProtocol; UCHAR iInterface; } USB_ITF_DESCR, *PUSB_ITF_DESCR;

typedef struct _USB_ENDPOINT_DESCRIPTOR { UCHAR bLength; UCHAR bDescriptorType; UCHAR bEndpointAddress; UCHAR bmAttributes; UCHAR wMaxPacketSize; UCHAR wMaxPacketSize1; UCHAR 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[4]; } USB_CFG_DESCR_LONG, *PUSB_CFG_DESCR_LONG;

unsigned char buffer[64]; /* 公用缓冲区 */

/* 延时2微秒,不精确 */ void delay2us( ) { unsigned char i; for ( i = 2; i != 0; i -- ); }

/* 延时1微秒,不精确 */ void delay1us( ) { unsigned char i; for ( i = 1; i != 0; i -- ); }

/* 以毫秒为单位延时,不精确,适用于24MHz时钟 */ void mDelaymS( unsigned char delay ) { unsigned char i, j, c; for ( i = delay; i != 0; i -- ) { for ( j = 200; j != 0; j -- ) c += 3; /* 在24MHz时钟下延时500uS */ for ( j = 200; j != 0; j -- ) c += 3; /* 在24MHz时钟下延时500uS */ } }

/* 基本操作 */

void CH375_WR_CMD_PORT( unsigned char cmd ) { /* 向CH375的命令端口写入命令,周期不小于4uS,如果单片机较快则延时 */ // delay2us(); CH375_CMD_PORT=cmd; delay2us(); }

void CH375_WR_DAT_PORT( unsigned char dat ) { /* 向CH375的数据端口写入数据,周期不小于1.5uS,如果单片机较快则延时 */ CH375_DAT_PORT=dat; // delay1us(); /* 因为MCS51单片机较慢所以实际上无需延时 */ }

unsigned char CH375_RD_DAT_PORT() { /* 从CH375的数据端口读出数据,周期不小于1.5uS,如果单片机较快则延时 */ // delay1us(); /* 因为MCS51单片机较慢所以实际上无需延时 */ return( CH375_DAT_PORT ); }

unsigned char wait_interrupt() { /* 主机端等待操作完成, 返回操作状态 */ unsigned short i; // while( CH375_INT_WIRE ); /* 查询等待CH375操作完成中断(INT#低电平) */ for ( i = 0; CH375_INT_WIRE != 0; i ++ ) { /* 如果CH375的中断引脚输出高电平则等待,通过计数防止超时 */ // delay1us(); if ( i == 0xF000 ) CH375_WR_CMD_PORT( CMD_ABORT_NAK ); /* 如果超时达61mS以上则强行终止NAK重试,中断返回USB_INT_RET_NAK */ }

CH375_WR_CMD_PORT( CMD_GET_STATUS ); /* 产生操作完成中断, 获取中断状态 */ return( CH375_RD_DAT_PORT() ); }

#define TRUE 1 #define FALSE 0 unsigned char set_usb_mode( unsigned char mode ) { /* 设置CH375的工作模式 */ unsigned char i; CH375_WR_CMD_PORT( CMD_SET_USB_MODE ); CH375_WR_DAT_PORT( mode ); for( i=0; i!=100; i++ ) { /* 等待设置模式操作完成,不超过30uS */ if ( CH375_RD_DAT_PORT()==CMD_RET_SUCCESS ) return( TRUE ); /* 成功 */ } return( FALSE ); /* CH375出错,例如芯片型号错或者处于串口方式或者不支持 */ }

/* 数据同步 */ /* USB的数据同步通过切换DATA0和DATA1实现: 在设备端, USB打印机可以自动切换; 在主机端, 必须由SET_ENDP6和SET_ENDP7命令控制CH375切换DATA0与DATA1. 主机端的程序处理方法是为设备端的各个端点分别提供一个全局变量, 初始值均为DATA0, 每执行一次成功事务后取反, 每执行一次失败事务后将其复位为DATA1 */

void toggle_recv( BOOL1 tog ) { /* 主机接收同步控制:0=DATA0,1=DATA1 */ CH375_WR_CMD_PORT( CMD_SET_ENDP6 ); CH375_WR_DAT_PORT( tog ? 0xC0 : 0x80 ); // delay2us(); }

void toggle_send( BOOL1 tog ) { /* 主机发送同步控制:0=DATA0,1=DATA1 */ CH375_WR_CMD_PORT( CMD_SET_ENDP7 ); CH375_WR_DAT_PORT( tog ? 0xC0 : 0x80 ); // delay2us(); }

unsigned char clr_stall( unsigned char endp_addr ) { /* USB通讯失败后,复位设备端的指定端点到DATA0 */ CH375_WR_CMD_PORT( CMD_CLR_STALL ); CH375_WR_DAT_PORT( endp_addr ); return( wait_interrupt() ); }

/* 数据读写, 单片机读写CH375芯片中的数据缓冲区 */

unsigned char rd_usb_data( unsigned char *buf ) { /* 从CH37X读出数据块 */ unsigned char i, len; CH375_WR_CMD_PORT( CMD_RD_USB_DATA ); /* 从CH375的端点缓冲区读取接收到的数据 */ len=CH375_RD_DAT_PORT(); /* 后续数据长度 */ for ( i=0; i!=len; i++ ) *buf++=CH375_RD_DAT_PORT(); return( len ); }

void wr_usb_data( unsigned char len, unsigned char *buf ) { /* 向CH37X写入数据块 */ CH375_WR_CMD_PORT( CMD_WR_USB_DATA7 ); /* 向CH375的端点缓冲区写入准备发送的数据 */ CH375_WR_DAT_PORT( len ); /* 后续数据长度, len不能大于64 */ while( len-- ) CH375_WR_DAT_PORT( *buf++ ); }

/* 主机操作 */ unsigned char endp_out_addr; /* 打印机数据接收端点的端点地址 */ unsigned char endp_out_size; /* 打印机数据接收端点的端点尺寸 */ BOOL1 tog_send; /* 打印机数据接收端点的同步标志 */ unsigned char endp_in_addr; /* 双向打印机发送端点的端点地址,一般不用 */ BOOL1 tog_recv; /* 双向打印机发送端点的同步标志,一般不用 */

unsigned char issue_token( unsigned char endp_and_pid ) { /* 执行USB事务 */ /* 执行完成后, 将产生中断通知单片机, 如果是USB_INT_SUCCESS就说明操作成功 */ CH375_WR_CMD_PORT( CMD_ISSUE_TOKEN ); CH375_WR_DAT_PORT( endp_and_pid ); /* 高4位目的端点号, 低4位令牌PID */ return( wait_interrupt() ); /* 等待CH375操作完成 */ }

unsigned char issue_token_X( unsigned char endp_and_pid, unsigned char tog ) { /* 执行USB事务,适用于CH375A */ /* 执行完成后, 将产生中断通知单片机, 如果是USB_INT_SUCCESS就说明操作成功 */ CH375_WR_CMD_PORT( CMD_ISSUE_TKN_X ); CH375_WR_DAT_PORT( tog ); /* 同步标志的位7为主机端点IN的同步触发位, 位6为主机端点OUT的同步触发位, 位5~位0必须为0 */ CH375_WR_DAT_PORT( endp_and_pid ); /* 高4位目的端点号, 低4位令牌PID */ return( wait_interrupt() ); /* 等待CH375操作完成 */ }

void soft_reset_print( ) { /* 控制传输:软复位打印机 */ tog_send=tog_recv=0; /* 复位USB数据同步标志 */ toggle_send( 0 ); /* SETUP阶段为DATA0 */ buffer[0]=0x21; buffer[1]=2; buffer[2]=buffer[3]=buffer[4]=buffer[5]=buffer[6]=buffer[7]=0; /* SETUP数据,SOFT_RESET */ wr_usb_data( 8, buffer ); /* SETUP数据总是8字节 */ if ( issue_token( ( 0 << 4 ) | DEF_USB_PID_SETUP )==USB_INT_SUCCESS ) { /* SETUP阶段操作成功 */ toggle_recv( 1 ); /* STA


你将void wr_usb_data( unsigned char len, unsigned char *buf ) { /* 向CH37X写入数据块 */ 函数改为void wr_usb_data( unsigned char len, unsigned char xdata *buf ) { /* 向CH37X写入数据块 */ 试下


改了是一样的.还有我用SL811试过,速度还是很慢,传一两个数据包(64)后就反回NAK了, 可能真的要看看USB2.0的协议,看高速和全速有什么区别,我英文不好呀,老大能帮忙看看吗?


要不你用USB1.1的计算机接上你的打印机,用BUSHOUND抓下看下你要打印的数据和你要发的数据是不是一样的,同时你要看下在计算机给打印机发送数据的过程中,打印机有没有什么返回给计算机的数据.


我用USBHOUND抓过了,1.1电脑的数据和2.0的是一样的,只是慢了一点,4096字节要250ms,而2.0的只要2ms, 不过比用单片机的600/S的快得多了,当中也没什么其它的数据,就只有DO,


那和你SEND_TO_DATA缓冲区的数据是一样的吗??


是一样的,


你在 else if ( s==USB_INT_RET_NAK ) { /* USB打印机正忙,如果未执行SET_RETRY命令则CH375自动重试,所以不会返回USB_INT_RET_NAK状态 */ /* USB打印机正忙,正常情况下应该稍后重试 */ /* s=get_port_status( ); 如果有必要,可以检查是什么原因导致打印机忙 */ } 改为 else if ( s==USB_INT_RET_NAK ) { /* USB打印机正忙,如果未执行SET_RETRY命令则CH375自动重试,所以不会返回USB_INT_RET_NAK状态 */ /* USB打印机正忙,正常情况下应该稍后重试 */ s=get_port_status( ); // 如果有必要,可以检查是什么原因导致打印机忙 */ } 看下是什么问题导致打印机忙,你在将"s"输出来看下是什么数据??


以上的试过,返回的数据有时为0xff,有时为0xf7;是不是要设这里的: CH375_WR_CMD_PORT( CMD_SET_RETRY ); /* 设置USB事务操作的重试次数 */ CH375_WR_DAT_PORT( 0x25 ); CH375_WR_DAT_PORT( 0x09 ); /* 位7为1则收到NAK时无限重试, 位3~位0为超时后的重试次数 */ 也设了,是什么原因呢?


不需要设置这个,因为这个设置的是出错(STALL)时候的重试次数,而不是NAK的重试次数,NAK的重试次数在RETRY中的位7为1,位6为0时为无限次重试,你想停止的话可以用ABORT命令停止重试


老大是什么原因呀?我快要放弃用国产的CH375了,


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