[求助]XP提示无法识别USB设备,和单片机晶振有关吗?

大家好,我想用51系列单片机和CH372实现与电脑的数据通讯,购买了沁恒的372实验模块,连接如下图:

20103614445385.gif

单片机里的代码用的是沁恒网站上下的(由于没有译码电路,读写数据、写命令这三个函数改了一下)

现在这套设备自己在面包板上焊好,上电后XP提示无法识别的USB设备,由于此面包板上次做串口调试用,晶振用的不是12MHZ,但是手边暂时没有12MHZ的,不知道是不是单片机晶振的原因呢?

非常感谢!

1、CH372的晶振必须为12M,单片机没要求 2、USB线是否为屏蔽线;USB口外壳需要接地;整个板子的共地性要好,面包板更要注意这一点 3、程序中一开始需要做测试命令,验证接口程序和硬件连接是否正常


你好,首先谢谢你的回复

372的晶振是模块上自带的,为12M USB外壳接地后故障依旧,

然后我看了下代码,好像给372的第一条命令就没有执行成功,我的代码如下: ================================= /* 设置USB工作模式, 必要操作 */ CH375_WR_CMD_PORT( CMD_SET_USB_MODE ); CH375_WR_DAT_PORT( 2 ); /* 设置为使用内置固件的USB设备方式 */ for ( i=100; i!=0; i-- ) if ( CH375_RD_DAT_PORT( ) == CMD_RET_SUCCESS ) break; /* 等待操作成功,通常需要等待10uS-20uS */ if ( i == 0 ){P1=P0;} /*{ CH372/CH375芯片内部或者物理连接存在硬件错误 }; */ ---------------------------------

我现在P0口接了一排LED,这样得到芯片的反馈数据是0xFD,不知道是什么意思。 另外,我查了下手册,USB模式有内置和外置两种,不知道怎么区分?谢谢了。

其中,我说的WR_CMD和WR_DAT函数作了以下修改: ================================= sbit mCS=P3^4;//定义按键位置 sbit mA0=P3^7; sbit mRD=P3^6; sbit mWD=P3^5;

/* 与CH372/CH375有关的基本I/O操作 */

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

mCS=1; //off #CS mA0=1; //CMD mode mRD=1; //off Read mWD=0; //on Write mCS=0; //on #CD P0=cmd; //send cmd mCS=1; //off #CS Delay2us(); }

void CH375_WR_DAT_PORT( UINT8 dat ) { /* 向CH375的数据端口写入数据,周期不小于1.5uS,如果单片机较快则延时 */ //CH375_DAT_PORT=dat; mCS=1; //off #CS mA0=0; //data mode mRD=1; //off Read mWD=0; //on Write mCS=0; //on #CD P0=dat; //send data mCS=1; //off #CS Delay1us(); /* 如果是MCS51单片机,因其较慢,所以实际上无需延时 */ }

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

mCS=1; //off #CS mA0=0; //data mode mRD=0; //on Read mWD=1; //off Write mCS=0; //on #CD return(P0); //read data mCS=1; //off #CS }

---------------------------------


刚刚右在设置USB模式前加了一段测试代码,但是看来测试没有通过: ================== /*initial test*/ CH375_WR_CMD_PORT(CMD_CHECK_EXIST); //testing CH375_WR_DAT_PORT(0x13); Delay2us(); //P0=CH375_RD_DAT_PORT( ); if(CH375_RD_DAT_PORT()!=~0x13) {goto EOF1;} //testing not passed, exit function delay(100);

/* 设置USB工作模式, 必要操作 */ . . . . . EOF1: P1=0xDD; goto EOF; EOF2: P1=0xDC; goto EOF; EOF: Delay1us();

------------------

最终LED显示的是0xDD。 请问一般测试没有通过的话,会是些什么原因呢?谢谢


把PO口的LED都去掉,另外读写时序修改一下,先做测试命令,确定硬件连接以及时序没有问题

void CH375_WR_CMD_PORT( UINT8 cmd ) { /* 向CH375的命令端口写入命令,周期不小于4uS,如果单片机较快则延时 */ Delay2us(); //CH375_CMD_PORT=cmd; P0=cmd; //send cmd mA0=1; //CMD mode mCS=0; //on #CD mRD=1; //off Read mWD=0; //on Write mWD=1; //off Write mCS=1; //off #CS mA0=0; //CMD mode

Delay2us(); }

void CH375_WR_DAT_PORT( UINT8 dat ) { /* 向CH375的数据端口写入数据,周期不小于1.5uS,如果单片机较快则延时 */ //CH375_DAT_PORT=dat; P0=dat; //send data mA0=0; //data mode mRD=1; //off Read mCS=0; //on #CD mWD=0; //on Write mWD=1; //off Write mCS=1; //off #CS Delay1us(); /* 如果是MCS51单片机,因其较慢,所以实际上无需延时 */ }

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

mA0=0; //data mode mRD=0; //on Read mWD=1; //off Write mCS=0; //on #CD i = P0; //read data mRD=1; //on Read mCS=1; //off #CS }


另,MCS51的P0口做为普通I/O口使用时,需要外接上拉电阻


用了study的代码,依旧是测试代码没有通过(LED显示0xDD)

另外,不好意思前面说错了,LED是接在P1口上的,并且已经接了上拉电阻

to study:请教一下,读写函数里这些步骤你这么改是出于什么考虑呢?谢谢 另外LED接在P1口上,还需要去除吗?这样就完全不知道内部程序的状态了(现在至少还能知道测试代码没通过,呵呵)


你的时序有明显的错误。正常情况下RD,WR,CS一定要为1,A0可以为0,也可以为1 void CH375_WR_DAT_PORT( UINT8 dat ) { /* 向CH375的数据端口写入数据,周期不小于1.5uS,如果单片机较快则延时 */ //CH375_DAT_PORT=dat;

mCS=1; //off #CS mA0=0; //data mode mRD=1; //off Read mWD=0; //on Write mCS=0; //on #CD P0=dat; //send data mCS=1; //off #CS

Delay1us(); /* 如果是MCS51单片机,因其较慢,所以实际上无需延时 */ }

mWD=0; //on Write执行完这句后,就再也没有为1了。

在调试的时候,建议您用串口方式,通过串口把数据送到PC上,就可以看到您读到的数据到底是什么数据了。LED指示不够明确。


程序上面上电之后先延时50ms在操作,因为CH372的上电复位时间要在50ms左右,一般在默认的情况下RD,WR,CS都是高电平,数据端口为输入状态,A0为低电平。这样可以防止在通讯过程中数据出错。

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

mA0=0; //data mode mRD=0; //on Read mWD=1; //off Write mCS=0; //on #CD i = P0; //read data mRD=1; //on Read mCS=1; //off #CS return i; }


再次感谢两位的回复,由于家里条件暂时有限,还没接串口,所以暂时还是想用P1口的led来debug,想请教一下为什么看led不太恰当,有没有电路上面的什么原因呢?谢谢

另外,本着“没用的时候置高电平”的思想,我又改了一下三个函数如下:

/* 与CH372/CH375有关的基本I/O操作 */ void CH375_WR_CMD_PORT( UINT8 cmd ) { /* 向CH375的命令端口写入命令,周期不小于4uS,如果单片机较快则延时 */ Delay2us(); //CH375_CMD_PORT=cmd; mCS=1; P0=cmd; //send cmd mA0=1; //CMD mode mWD=1; mRD=1;

mRD=1; //off Read mWD=0; //on Write

mCS=0; //on #CD P0=cmd; //send cmd mCS=1; //off #CS

mWD=1; //off Write

Delay2us(); }

void CH375_WR_DAT_PORT( UINT8 dat ) { /* 向CH375的数据端口写入数据,周期不小于1.5uS,如果单片机较快则延时 */ //CH375_DAT_PORT=dat; mCS=1; P0=dat; //send data mA0=0; //data mode mRD=1; //off Read mWD=0; //on Write

mCS=0; //on #CD P0=dat; //send data mCS=1; //off #CS

mWD=1; //off Write

Delay1us(); /* 如果是MCS51单片机,因其较慢,所以实际上无需延时 */ }

UINT8 CH375_RD_DAT_PORT( void ) { /* 从CH375的数据端口读出数据,周期不小于1.5uS,如果单片机较快则延时 */ unsigned char i; Delay1us(); /* 如果是MCS51单片机,因其较慢,所以实际上无需延时 */ //return( CH375_DAT_PORT ); mCS=1; mA0=0; //data mode mRD=0; //on Read mWD=1; //off Write

mCS=0; //on #CS i = P0; //read data mCS=1; //off #CS

mRD=1; //off Read

return i;

}

同时,main函数也调整了一下: main( void ) {

//ft P1=0xFE;

delay(200); delay(200); CH375_Init( ); EA = 1;

P1=0xF1;

while ( 1 ); }

上电后就没有头绪了,XP依旧提示无法识别的设备,但是LED一个都不亮 不过在烧写程序的板子上通电时(也就是没接USB模块),led显示0xF1,就是while(1)之前

请问一下可能会是什么原因呢?万分感谢!


1、普通51单片机的P0口做I/O使用时,必须外接上拉电阻,硬件有没有改正呢 2、时序有问题了: void CH375_WR_CMD_PORT( UINT8 cmd ) { P0=cmd; //send cmd mA0=1; //CMD mode mCS=0; //on #CD mWD=0; //on Write mWD=0; /*延时,保证60nS*/ mWD=1; //off Write mCS=1; //off #CS mA0=0; //CMD mode P0 = 0xFF; /* 置方向为输入 */ Delay2us(); /* 延时,保正1.5uS */ }

void CH375_WR_DAT_PORT( UINT8 dat ) { P0=dat; //send data mA0=0; //data mode mCS=0; //on #CD mWD=0; //on Write mWD=0; /*延时,保证60nS*/ mWD=1; //off Write mCS=1; //off #CS P0 = 0xFF; /* 置方向为输入 */ Delay1us(); /* 延时,保证0.6uS */ }

UINT8 CH375_RD_DAT_PORT( void ) { /* 从CH375的数据端口读出数据,周期不小于1.5uS,如果单片机较快则延时 */ unsigned char i; Delay1us(); /* 延时,保证0.6uS */ P0 = 0xFF; /* 置方向为输入 */ mA0=0; //data mode mCS=0; mRD=0; //on Read mRD=0; /*延时,保证60nS*/ i = P0; //read data mRD=1; //on Read mCS=1; //off #CS return( i ); } 程序开始,需要初始化一下:A0 = 0; CS = 1; WR = 1; RD = 1; P0 = 0xFF;上述延时,需要根据单片机主频调整,不要误太大 3、调试的思路,先前已经说过了,先做测试命令,验证硬件连接和接口程序是否正确,再进行后续操作


在此感谢您的耐心解答: 1,LED接了上拉电阻,P0作为数据传输的确没有接,谢谢提醒 2,谢谢代码,我回去试试看。也就是说,正确的时序应该是:

在进入读写函数前,片选、读写模式都保持关闭状态 在片选开启之前,I/O口各位进入需要传输的数据的高低位状态 选择命令/数据模式, 开启片选, 开启读或写模式,并且作适当延时 关闭读或写模式 关闭片选

应该是这样,对吗? 不过您最后一句把I/O口置位0xFF有点不太理解,能解释一下吗?谢谢 另外,延时如果太大的话,会出什么问题吗?我不太熟悉精确延时,所以我想的是宁可延时大一点也不要过小。

3,好的,我晚上回家试试看

再次感谢!


1、I/O一直保持为输出模式,如果与其相连的引脚也是输出,且电平不同的话,会造成短路,置位是切换为输入模式,安全些 2、延时根据你单片机的指令周期去算,这个估算一下就可以了


终于成功了! 特此再次感谢SCM、study、红桃六的耐心解答和帮助


最终是什么原因,说出来大家一起分享一下,给后来者提供一点经验。


昨天回家后做了两件事:1,P0口接了上拉电阻;2,用了你10楼的代码 因为很晚了,所以XP提示成功连接后没怎么研究就睡觉了

我自己估计可能主要是上拉电阻的原因,函数上的时序应该相对来说影响小一些吧?

这两天回家后我会再看看


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