关于CH375A接收数据问题

各位高手大家好:

本人刚刚接触CH375A,按网上的程序,现在枚举是好使的,并且用USB测试工具往单片机送数据时,单片机也能接收到正确的中断,但是,此后接收数据长度和数据时就总是:数据为两个2,长度也为2了,不知道为什么,请指教,还有就是如果只是测试简单的USB通讯,你们都用什么测试软件呢?谢谢!!

用CH372DBG.EXE来调试,到我们网站在线下载里去下载.然后在测试一下看看结果.


应该还是你程序上的问题 上位机软件:CH372DBG.ZIP 下位机软件:CH372EVTZ.IP,参考\CH372EVT\PUB\XFIRM 另,\CH372EVT\PUB\这个目录下其他例程的上下位机是配对的


我用从贵公司网站上下载的C程序和调试程序试验了一下,结果和我的程序是一样的,进入中断后,从USB口读出的仍然都是2,我的程序是用模拟并口的方式做的,电路中RD脚接单片机的RD脚,WR脚接单片机的WR脚,CS脚接P27,A0脚接P26,INT脚接P32,D+,D-直接接USB接口的D+,D-,板上的电源用USB口过来的+5V电源,V3用了滤波电容后接地,TXD,RXD直接接地了,请问这么接可以吗?谢谢!!


把下位机程序贴出来看看.


这个程序是我在USBEX.C的基础上改的,请只看管脚定义和发送命令,读写命令就可以,太感谢了!

#pragma NOAREGS #include #include "CH375INC.H"

sbit CH375_A0=P2^6; sbit CH375_CS=P2^7; sbit CH375_WR=P3^6; sbit CH375_RD=P3^7;

typedef union _REQUEST_PACK{ unsigned char buffer[8]; struct{ unsigned char bmReuestType; //标准请求字 unsigned char bRequest; //请求代码 unsigned int wValue; //特性选择高 unsigned int wIndx; //索引 unsigned int wLength; //数据长度 }r; } mREQUEST_PACKET, *mpREQUEST_PACKET;

//设备描述符 unsigned char code DevDes[]={ 0x12 //描述符大小 , 0x01 //常数DEVICE , 0x10 //USB规范版本信息 , 0x01 , 0xFF //类别码, , 0x80 //子类别码 , 0x37 //协议码 , 0x08 //端点0的最大信息包大小 , 0x48 //厂商ID , 0x43 , 0x37 //产品ID , 0x55 , 0x00 //设备版本信息 , 0x01 , 0x00 //索引值 , 0x00 , 0x00 , 0x01 //可能配置的数目 , 00 //无意义 , 00 , 00 , 00 , 00 , 00 }; //配置描述符 unsigned char code ConDes[]={ //配置描述符 0x09 //描述符大小 , 0x02 //常数CONFIG , 0x27 //此配置传回所有数据大小 , 0x00 // , 0x01 //接口数 , 0x01 //配置值 , 0x00 //索引 , 0x80 //电源设置 , 0x40 //需要总线电源 //接口描述符 , 0x09 //描述符大小 , 0x04 //常数INTERFACE , 0x00 //识别码 , 0x00 //代替数值 , 0x03 //支持的端点数 , 0xFF //类别码 , 0x80 //子类别码 , 0x37 //协议码 , 0x00 //索引 //端点描述符 , 0x07 //述符大小 , 0x05 //常数ENDPOINT , 0x82 //端点数目及方向 , 0x02 //支持的传输类型 , 0x40 //支持的最大信息包大小 , 0x00 , 0x00 // , 0x07 , 0x05 , 0x02 , 0x02 , 0x40 , 0x00 , 0x00 , 0x07 , 0x05 , 0x81 , 0x03 , 0x08 , 0x00 , 0x01

, 0x07 , 0x05 , 0x01 , 0x02 , 0x08 , 0x00 , 0x00 }; //配置描述符 unsigned char code LangDes[]={0x04,0x03,0x09,0x04}; //语言描述符 unsigned char code SerDes[]={0x12,0x03,'C',0,'H',0,'3',0,'7',0,'5',0,'U',0,'S',0,'B',0}; //字符串描述符

unsigned char mVarSetupRequest; // ;USB请求码 unsigned char mVarSetupLength; // ;后续数据长度 unsigned char code * VarSetupDescr; // ;描述符偏移地址

unsigned char VarUsbAddress ; //

bit CH375FLAGERR; //错误清0 bit CH375CONFLAG; //配置标志

unsigned char volatile xdata CH375_CMD_PORT _at_ 0xBDF1; /* CH375命令端口的I/O地址 */ unsigned char volatile xdata CH375_DAT_PORT _at_ 0xBCF0; /* CH375数据端口的I/O地址 */

mREQUEST_PACKET request; sbit CH375ACT = P1^4;

/* 延时2微秒,不精确 */ void Delay1us(){ ; }

void Delay2us( ) { unsigned char i; #define DELAY_START_VALUE 1 /* 根据单片机的时钟选择初值,20MHz以下为0,30MHz以上为2 */ for ( i=DELAY_START_VALUE; i!=0; i-- ); }

/* 延时50毫秒,不精确 */ void Delay50ms( ) { unsigned char i, j; for ( i=200; i!=0; i-- ) for ( j=250; j!=0; j-- ); }

/* 将PC机的低字节在前的16位字数据转换为C51的高字节在前的数据 */ //unsigned int BIG_ENDIAN( unsigned int value ) //{ // unsigned int in, out; // in = value; // ((unsigned char *)&out)[1] = ((unsigned char *)&in)[0]; // ((unsigned char *)&out)[0] = ((unsigned char *)&in)[1]; // return( out ); //}

void CH375_WR_CMD_PORT( unsigned char cmd ) { /* 向CH375的命令端口写入命令,周期不小于4uS,如果单片机较快则延时 */ delay2us(); ////CH375_CMD_PORT=cmd; /******************** 注释中是用普通I/O引脚模拟8位并口的时序,CH375_CS引脚是可选的,可以一直接GND强制片选*/ /// CH375_D0_D7 = cmd; P0=cmd; CH375_A0 = 1; /// 选择CH375的命令口 // CH375_D0_D7_DIR = output; 对于标准双向I/O,请在此设置为输出方向 CH375_RD = 1; //如果I/O默认电平是高电平,那么这是可选操作 CH375_CS = 0; CH375_WR = 0; CH375_CS = 0; // 对于高速单片机,该指令用于延时,以便向CH375_WR产生宽度至少为80nS的低电平脉冲 CH375_WR = 1; CH375_CS = 1; CH375_A0 = 0; P0=0xff;

// 对于准双向I/O,请在此设置输出全高电平 ///******************** delay2us(); }

void CH375_WR_DAT_PORT( unsigned char dat ) { /* 向CH375的数据端口写入数据,周期不小于1.5uS,如果单片机较快则延时 */ /*CH375_DAT_PORT=dat; ******************** 注释中是用普通I/O引脚模拟8位并口的时序*/ // CH375_D0_D7 = dat; ///// delay2us( ); P0=dat; // CH375_D0_D7_DIR = output; 对于标准双向I/O,请在此设置为输出方向 CH375_CS = 0; CH375_WR = 0; CH375_CS = 0; // 对于高速单片机,该指令用于延时,以便向CH375_WR产生宽度至少为80nS的低电平脉冲 CH375_WR = 1; CH375_CS = 1; // CH375_D0_D7_DIR = input; 对于标准双向I/O,请在此设置为输入方向 // CH375_D0_D7 = 0xFF; // 对于准双向I/O,请在此设置输出全高电平 P0=0xff;

//******************** */ delay2us(); /* 因为MCS51单片机较慢所以实际上无需延时 */ }

unsigned char CH375_RD_DAT_PORT( void ) { /* 从CH375的数据端口读出数据,周期不小于1.5uS,如果单片机较快则延时 */ // delay1us(); /* 因为MCS51单片机较慢所以实际上无需延时 */ /* ******************** 注释中是用普通I/O引脚模拟8位并口的时序 // CH375_D0_D7_DIR = input; 对于标准双向I/O,请在此设置为输入方向 */ unsigned char dat=0; //CH375_D0_D7 = 0xFF; // 对于准双向I/O,请在此设置输出全高电平,便于输入 delay2us( ); P0=0xff; CH375_A0 = 0;//////////// CH375_CS = 0; //// P0=0xff;///////// CH375_RD = 0; CH375_CS = 0; //对于高速单片机,该指令用于延时,以便向CH375_RD产生宽度至少为80nS的低电平脉冲 ///unsigned char dat = CH375_D0_D7; /// delay2us( );///// dat=P0; CH375_RD = 1; CH375_CS = 1; //CH375_D0_D7 = 0xFF; // 对于准双向I/O,请在此设置输出全高电平 //dat=CH375_D0_D7;

/// P0=0xff; return( dat );

}

void CH375_Init( ) { unsigned char i; /* 测试CH375是否正常工作,可选操作,通常不需要 */ CH375_WR_CMD_PORT( CMD_CHECK_EXIST ); /* 测试CH375是否正常工作 */ CH375_WR_DAT_PORT( 0x55 ); /* 写入测试数据 */ i = ~ 0x55; /* 返回数据应该是测试数据取反 */ if ( CH375_RD_DAT_PORT( ) != i ) { /* CH375不正常 */ for ( i=80; i!=0; i-- ) { CH375_WR_CMD_PORT( CMD_RESET_ALL ); /* 多次重复发命令,执行硬件复位 */ CH375_RD_DAT_PORT( ); } CH375_WR_CMD_PORT( 0 ); Delay50ms( ); /* 延时50ms */ } /* 设置USB工作模式, 必要操作 */ CH375_WR_CMD_PORT( CMD_SET_USB_MODE ); CH375_WR_DAT_PORT( 2 ); /* 设置为使用内置固件的USB设备方式 */ for ( i=100; i!=0; i-- ) { /* 等待操作成功,通常需要等待10uS-20uS */ if ( CH375_RD_DAT_PORT( ) == CMD_RET_SUCCESS ) { //// IT0 = 0; break; } } /* if ( i==0 ) { CH372/CH375存在硬件错误 }; */ /* 下述启用中断,假定CH375连接在INT0 */ IT0 = 0; /* 置外部信号为低电平触发 */ IE0 = 0; /* 清中断标志 */ EX0 = 1; /* 允许CH375中断 */ }

//********************************************************* //端点0数据上传 void mCh375Ep0Up(){ unsigned char i,len; if(mVarSetupLength){ //长度不为0传输具体长度的数据 if(mVarSetupLength<=8){ len=mVarSetupLength; mVarSetupLength=0; } //长度小于8则长输要求的长度 else{ len=8; mVarSetupLength-=8; } //长度大于8则传输8个,切总长度减8 CH375_WR_CMD_PORT(CMD_WR_USB_DATA3); //发出写端点0的命令 CH375_WR_DAT_PORT(len); //写入长度 for(i=0;i!=len;i++) CH375_WR_DAT_PORT(request.buffer[i]); //循环写入数据 } else{ CH375_WR_CMD_PORT(CMD_WR_USB_DATA3); //发出写端点0的命令 CH375_WR_DAT_PORT(0); //上传0长度数据,这是一个状态阶段 } }

//*********************************************************

//复制描述符以便上传 void mCh375DesUp(){ unsigned c


还有个问题,调试程序时还用加.lib文件嘛,我只是加了CH375INC.H


还有一个情况我忘说了,就是初始化USB时,发送CHECK_EXIST命令,并不会返回取反的数据,但是好象因为送了工作模式字(2)是对的,所以枚举是成功的,并且此后读出返回的状态也是对的0x51。

不知道有没有影响,是不是说明有什么问题,谢谢!!


程序写这么复杂,你参考TEST.C就可以了,只需要修改两个参数 unsigned char volatile xdata CH375_CMD_PORT _at_ 0xBDF1; /* CH375命令端口的I/O地址 */ unsigned char volatile xdata CH375_DAT_PORT _at_ 0xBCF0; /* CH375数据端口的I/O地址 */ 改为: unsigned char volatile xdata CH375_CMD_PORT _at_ 0x7BF1; /* CH375命令端口的I/O地址 */ unsigned char volatile xdata CH375_DAT_PORT _at_ 0x3CF0; /* CH375数据端口的I/O地址 */ 其他不要做任何修改就可以了. 用CH372DBG调试的时候,下发数据(长度小于64个)不要加空格,比如下发数据AA55,然后点击上传,将会收到55AA 另外你把测试结果详细的说明以下


那你取到的数据是什么?要保证测试命令一定要正常通过,而且尽量测试两次把每个IO都要测试,比如,发送CHECK_EXIST命令,发送0X55数据,得到0XAA,发送CHECK_EXIST命令,在发0XAA数据,得到0X55,这样才说明你的读写子函数是正确的.


谢谢您的回复,我想问一下:

1、我的硬件连接可以吗?

2、您说的让我把命令口与数据口改为那两个地址是怎么得到的呢?其实例子中的地址我也不知道怎么得到的,我觉得命令口与数据口的地址就只差一个A0位,而不是差两位呀?

非常感谢!


硬件连接没有问题,ch375中断引脚怎么接的? 设置模式的时候,如果设置模式成内置固件模式(模式2),则不需要上面的描述符. 上面的两个地址是采用总线方式操作ch375,只要区分A0位就可以了.


我的电路连接:(没用什么74HC373)电路中RD脚接单片机的RD脚,WR脚接单片机的WR脚,CS脚接P27,A0脚接P26,INT脚接P32,D+,D-直接接USB接口的D+,D-,板上的电源用USB口过来的+5V电源,V3用了滤波电容后接地,TXD,RXD直接接地了,

CH375_WR_CMD_PORT( CMD_CHECK_EXIST ); /* 测试CH375是否正常工作 */ CH375_WR_DAT_PORT( 0x55 ); /* 写入测试数据 */ i = ~ 0x55; /* 返回数据应该是测试数据取反 */ if ( CH375_RD_DAT_PORT( ) != i ) { /* CH375不正常 */ for ( i=80; i!=0; i-- ) { CH375_WR_CMD_PORT( CMD_RESET_ALL ); /* 多次重复发命令,执行硬件复位 */ CH375_RD_DAT_PORT( ); } CH375_WR_CMD_PORT( 0 ); Delay50ms( ); /* 延时50ms */ } 上面语句结束后,读出的数据为0XFF,

CH375_WR_CMD_PORT( CMD_SET_USB_MODE ); CH375_WR_DAT_PORT( 2 ); /* 设置为使用内置固件的USB设备方式 */ for ( i=100; i!=0; i-- ) { /* 等待操作成功,通常需要等待10uS-20uS */ if ( CH375_RD_DAT_PORT( ) == CMD_RET_SUCCESS ) break; } 这里读出的数据就是对的:CMD_RET_SUCCESS ,同样的子程序, 我感觉还是硬件有问吧,请指教!!谢谢


补充一下: 因为手头没有0.47uf的电容,所以CH375的复位脚用的680P电容替代的,不知道行不行?我也试着把RST脚直接接到I/O口,用程序控制复位,但是还是不行!

我发现发送完EXIT命令后,数据为0x55有时会返回0x1F,我把RD,WR脚换成P2^5,P2^6脚时,返回的数据与前面又有所不同,不知道为什么?请指教,谢谢了!


我上面所说的地址是按照你的硬件连接确定的: sbit CH375_A0=P2^6; sbit CH375_CS=P2^7; sbit CH375_WR=P3^6; sbit CH375_RD=P3^7;

如果你不把WR,RD接在总线上的WR,RD,那么肯定要用模拟IO方式.这样做个测试,你循环的发送数据,看一下各IO波形是否正常,比如循环发送数据0X55,WR,CS都为0的时候CH375采样.


我用你定义的地址,其它都不改的话,枚举是不成功的,但是我改成模拟并口后,枚举是成功的,但始终EXIST命令的返回不对,还有就是按我的程序,后续接收到的数据长度和内容都是2(不管我发送什么),并且发送一回后,不停进入中断。

请指教,谢谢


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