我用的375做主機(jī),用的它的串口方式與單片機(jī)連接,想把從單片機(jī)并口接收的數(shù)據(jù)通過ch375送給USB打印機(jī),可是打印出的數(shù)據(jù)不太對,不知道什么原因。
我再補(bǔ)充一下,我要實(shí)現(xiàn)的功能是:把一個智能儀器的數(shù)據(jù)通過其并口傳給單片機(jī),然后單片機(jī)通過CH375把數(shù)據(jù)轉(zhuǎn)換成USB數(shù)據(jù)送給USB打印機(jī),也就是為該智能儀器擴(kuò)展USB接口,使其能夠連接USB打印機(jī)。 我現(xiàn)在的問題是:智能儀器傳過來的數(shù)據(jù)可能不是64的整數(shù)倍,那么最后一個數(shù)據(jù)包不夠64的時候怎么處理???我在單片機(jī)中開了兩個64字節(jié)的BUFFER,
你可以看下我們這邊的例子程序,也是并口接收打印機(jī)數(shù)據(jù),通過USB口發(fā)送數(shù)據(jù)。實(shí)際上只需要加一個定時器超時就可以了: /* 2004.03.05, 2004.8.18 **************************************** ** Copyright (C) W.ch 1999-2004 ** ** Web: http://www.winchiphead.com ** **************************************** ** USB 1.1 Host Examples for CH375 ** ** KC7.0@MCS-51 ** **************************************** */ //計(jì)算機(jī)通過并口發(fā)送數(shù)據(jù),然后通過375轉(zhuǎn)換成USB打印機(jī) // 程序示例,C語言,CH375中斷為查詢方式,只負(fù)責(zé)數(shù)據(jù)傳輸,不涉及打印格式及打印描述語言
// 以下定義適用于MCS-51單片機(jī),其它單片機(jī)參照修改,為了提供C語言的速度需要對本程序進(jìn)行優(yōu)化 //#pragma src #include #include #include #include "CH375INC.H" unsigned char volatile xdata CH375_CMD_PORT _at_ 0xDEF1; // CH375命令端口的I/O地址 unsigned char volatile xdata CH375_DAT_PORT _at_ 0xDCF0; // CH375數(shù)據(jù)端口的I/O地址 sbit cs_p=P1^3; sbit SIN=P1^4; sbit ACK=P1^6; sbit ERR=P1^7; sbit PE=P3^1; sbit BUSY0=P3^2; sbit STB=P3^0; sbit SLCT=P3^5; sbit CH375_INT_WIRE =P3^3; // P3.2, INT1, 連接CH375的INT#引腳,用于查詢中斷狀態(tài) unsigned char count=0,send=0; unsigned char xdata buffer[64]; // 公用緩沖區(qū) unsigned char xdata data_to_send[64]; unsigned int j=0; typedef unsigned char BOOL1; // typedef bit BOOL1; 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;
// 延時2微秒,不精確 void delay2us( ) { unsigned char i; for ( i = 2; i != 0; i -- ); }
// 延時1微秒,不精確 void delay1us( ) { unsigned char i; for ( i = 1; i != 0; i -- ); }
void delay2ms( ) { unsigned char i,j; for ( i = 20; i != 1; i -- ) {for(j=100;j!=1;j--); } }
// 延時100毫秒,不精確 void delay100ms( ) { unsigned char i, j, c; for ( i = 200; i != 0; i -- ) for ( j = 200; j != 0; j -- ) c+=3; }
// 基本操作
void CH375_WR_CMD_PORT( unsigned char cmd ) { // 向CH375的命令端口寫入命令,周期不小于4uS,如果單片機(jī)較快則延時 delay2us(); CH375_CMD_PORT=cmd; delay2us(); }
void CH375_WR_DAT_PORT( unsigned char dat ) { // 向CH375的數(shù)據(jù)端口寫入數(shù)據(jù),周期不小于1.5uS,如果單片機(jī)較快則延時 CH375_DAT_PORT=dat; delay1us(); // 因?yàn)镸CS51單片機(jī)較慢所以實(shí)際上無需延時 }
unsigned char CH375_RD_DAT_PORT() { // 從CH375的數(shù)據(jù)端口讀出數(shù)據(jù),周期不小于1.5uS,如果單片機(jī)較快則延時 delay1us(); // 因?yàn)镸CS51單片機(jī)較慢所以實(shí)際上無需延時 return( CH375_DAT_PORT ); }
unsigned char wait_interrupt() { // 主機(jī)端等待操作完成, 返回操作狀態(tài) // unsigned int i=0; while( CH375_INT_WIRE ); CH375_WR_CMD_PORT( CMD_GET_STATUS ); // 產(chǎn)生操作完成中斷, 獲取中斷狀態(tài) return( CH375_RD_DAT_PORT() ); }
#define TRUE 1 #define FALSE 0 unsigned char set_usb_mode( unsigned char mode ) { //設(shè)置CH375的工作模式 unsigned char i; CH375_WR_CMD_PORT( CMD_SET_USB_MODE ); CH375_WR_DAT_PORT( mode ); for( i=0; i!=100; i++ ) { // 等待設(shè)置模式操作完成,不超過30uS if ( CH375_RD_DAT_PORT()==CMD_RET_SUCCESS ) {return( TRUE );} // 成功 else {return( FALSE );} // CH375出錯,例如芯片型號錯或者處于串口方式或者不支持 } } // USB的數(shù)據(jù)同步通過切換DATA0和DATA1實(shí)現(xiàn): 在設(shè)備端, USB打印機(jī)可以自動切換; // 在主機(jī)端, 必須由SET_ENDP6和SET_ENDP7命令控制CH375切換DATA0與DATA1. // 主機(jī)端的程 序處理方法是為設(shè)備端的各個端點(diǎn)分別提供一個全局變量, // 初始值均為DATA0, 每執(zhí)行一次成功事務(wù)后取反, 每執(zhí)行一次失敗事務(wù)后將其復(fù)位為DATA1
void toggle_send( BOOL1 tog ) { // 主機(jī)發(fā)送同步控制:0=DATA0,1=DATA1 CH375_WR_CMD_PORT( CMD_SET_ENDP7 ); CH375_WR_DAT_PORT( tog ? 0xC0 : 0x80 ); delay2us(); }
void toggle_recv( BOOL1 tog ) { /* 主機(jī)接收同步控制:0=DATA0,1=DATA1 */ CH375_WR_CMD_PORT( CMD_SET_ENDP6 ); CH375_WR_DAT_PORT( tog ? 0xC0 : 0x80 ); delay2us(); }
//數(shù)據(jù)讀寫, 單片機(jī)讀寫CH375芯片中的數(shù)據(jù)緩沖區(qū)
unsigned char rd_usb_data( unsigned char *buf ) { // 從CH37X讀出數(shù)據(jù)塊 unsigned char i, len; CH375_WR_CMD_PORT( CMD_RD_USB_DATA ); // 從CH375的端點(diǎn)緩沖區(qū)讀取接收到的數(shù)據(jù) len=CH375_RD_DAT_PORT(); // 后續(xù)數(shù)據(jù)長度 for ( i=0; i!=len; i++ ) *buf++=CH375_RD_DAT_PORT(); return( len ); }
void wr_usb_data( unsigned char len, unsigned char *buf ) { /* 向CH37X寫入數(shù)據(jù)塊 */ CH375_WR_CMD_PORT( CMD_WR_USB_DATA7 ); /* 向CH375的端點(diǎn)緩沖區(qū)寫入準(zhǔn)備發(fā)送的數(shù)據(jù) */ CH375_WR_DAT_PORT( len ); /* 后續(xù)數(shù)據(jù)長度, len不能大于64 */ while( len ) {CH375_WR_DAT_PORT( *buf++ );len--;} }
// 主機(jī)操作 unsigned char endp_out_addr; //打印機(jī)數(shù)據(jù)接收端點(diǎn)的端點(diǎn)地址 unsigned char endp_out_size; // 打印機(jī)數(shù)據(jù)接收端點(diǎn)的端點(diǎn)尺寸 BOOL1 tog_send; // 打印機(jī)數(shù)據(jù)接收端點(diǎn)的同步標(biāo)志 unsigned char endp_in_addr; // 打印機(jī)狀態(tài)發(fā)送端點(diǎn)的端點(diǎn)地址,為0則只支持單向接口 BOOL1 tog_recv; // 打印機(jī)狀態(tài)發(fā)送端點(diǎn)的同步標(biāo)志
unsigned char issue_token( unsigned char endp_and_pid ) { // 執(zhí)行USB事務(wù) // 執(zhí)行完成后, 將產(chǎn)生中斷通知單片機(jī), 如果是USB_INT_SUCCESS就說明操作成功 CH375_WR_CMD_PORT( CMD_ISSUE_TOKEN ); CH375_WR_DAT_PORT( endp_and_pid ); // 高4位目的端點(diǎn)號, 低4位令牌PID return( wait_interrupt() ); // 等待CH375操作完成 }
#define USB_INT_RET_NAK 0x2A // 00101010B,返回NAK unsigned char get_port_status( ) { //查詢打印機(jī)端口狀態(tài),返回狀態(tài)碼,如果為0FFH則說明操作失敗 //返回狀態(tài)碼中: 位5(Paper Empty)為1說明無紙, 位4(Select)為1說明打印機(jī)聯(lián)機(jī), 位3(Not Error)為0說明打印機(jī)出錯 toggle_send( 0 ); // SETUP階段為DATA0 buffer[0]=0xA1; buffer[1]=1; buffer[2]=buffer[3]=buffer[4]=buffer[5]=0; buffer[6]=1; buffer[7]=0; // SETUP數(shù)據(jù),GET_PORT_STATUS wr_usb_data( 8, buffer ); // SETUP數(shù)據(jù)總是8字節(jié) if ( issue_token( ( 0 << 4 ) | DEF_USB_PID_OUT )==USB_INT_SUCCESS ) { // SETUP階段操作成功 toggle_recv( 1 ); // DATA階段,準(zhǔn)備接收DATA1 if ( issue_token( ( 0 << 4 ) | DEF_USB_PID_IN )==USB_INT_SUCCESS ) { // DATA階段操作成功 rd_usb_data( buffer ); // 讀出接收到的數(shù)據(jù),通常只有1個字節(jié) toggle_send( 1 ); // STATUS階段為DATA1 wr_usb_data( 0, buffer ); // 發(fā)送0長度的數(shù)據(jù)說明控制傳輸成功 if ( issue_token( ( 0 << 4 ) | DEF_USB_PID_OUT )==USB_INT_SUCCESS ) return( buffer[0] ); // 返回狀態(tài)碼 } } return( 0xFF ); // 返回操作失敗 }
void send_data( unsigned short len, unsigned char *buf ) { /* 主機(jī)發(fā)送數(shù)據(jù)塊,一次最多64KB */ unsigned cha