[求助]CH372成了无法设备的USB设备

CH372EVT里面的程序是可以用的,你只要修改3个读写子函数以及中断引脚就可以实现和计算机的通信


我的程序: #pragma NOAREGS #include #include #include "CH375INC.H" /* 头文件,在网上下载的CH372或者CH375评估板资料中有 */

sbit CH375_A0 = P3^7; sbit CH375_RD = P3^5; sbit CH375_WR = P3^4;

#define CH375_D0_D7 P1 volatile unsigned char rd_dat;

void delay2us( ) { unsigned char i; for ( i = 2; i != 0; i -- ); /* 根据单片机的时钟选择初值 */ }

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

CH375_D0_D7 = cmd; CH375_A0 = 1; /*选择CH375的命令口*/ // CH375_D0_D7_DIR = output; /*对于标准双向I/O,请在此设置为输出方向*/ CH375_RD = 1; /*如果I/O默认电平是高电平,那么这是可选操作*/

CH375_WR = 0;

CH375_WR = 1;

CH375_A0 = 0; // CH375_D0_D7_DIR = input; /*对于标准双向I/O,请在此设置为输入方向*/ CH375_D0_D7 = 0xFF; /*对于准双向I/O,请在此设置输出全高电平*/ //******************** delay2us(); }

void CH375_WR_DAT_PORT( unsigned char dat ) { /* 向CH375的数据端口写入数据,周期不小于1.5uS,如果单片机较快则延时 */

CH375_D0_D7 = dat; // CH375_D0_D7_DIR = output; /*对于标准双向I/O,请在此设置为输出方向*/

CH375_WR = 0;

CH375_WR = 1;

// CH375_D0_D7_DIR = input; /*对于标准双向I/O,请在此设置为输入方向*/ CH375_D0_D7 = 0xFF; /*对于准双向I/O,请在此设置输出全高电平*/ //********************

}

unsigned char CH375_RD_DAT_PORT( void ) { /* 从CH375的数据端口读出数据,周期不小于1.5uS,如果单片机较快则延时 */ // delay1us(); /* 因为MCS51单片机较慢所以实际上无需延时 */ // ******************** 注释中是用普通I/O引脚模拟8位并口的时序

// CH375_D0_D7_DIR = input; /*对于标准双向I/O,请在此设置为输入方向*/ CH375_D0_D7 = 0xFF; /*对于准双向I/O,请在此设置输出全高电平,便于输入*/

CH375_RD = 0;

// unsigned char dat; rd_dat = CH375_D0_D7; CH375_RD = 1;

CH375_D0_D7 = 0xFF; /*对于准双向I/O,请在此设置输出全高电平*/ return( rd_dat ); //********************

}

void Delay50ms( ) { unsigned char i, j; for ( i=200; i!=0; i-- ) for ( j=250; j!=0; j-- ); }

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 */ }

CH375_WR_CMD_PORT( CMD_SET_USB_MODE ); CH375_WR_DAT_PORT( 2 ); /* 设置为使用内置固件的USB设备方式 */ // for ( i=100; i!=0; i-- ) { /* 等待操作成功,通常需要等待10uS-20uS */ for ( ;; ) { if ( CH375_RD_DAT_PORT( ) == CMD_RET_SUCCESS ) break; } /* if ( i==0 ) { CH372/CH375存在硬件错误 }; */ /* 下述启用中断,假定CH375连接在INT0 */ IT0 = 0; /* 置外部信号为低电平触发 */ IE0 = 0; /* 清中断标志 */ EX0 = 1; /* 允许CH375中断 */ }

void mCh375Interrupt( ) interrupt 2 using 1 /* 2 外部中断1; INT1 */ { unsigned char InterruptStatus; unsigned char i, length; unsigned char data buffer[ 64 ]; CH375_WR_CMD_PORT( CMD_GET_STATUS ); /* 获取中断状态并取消中断请求 */ InterruptStatus = CH375_RD_DAT_PORT( ); /* 获取中断状态 */ switch ( InterruptStatus ) { /* 分析中断状态处理 */ case USB_INT_EP2_OUT: { /* 批量端点下传成功 */ CH375_WR_CMD_PORT( CMD_RD_USB_DATA ); /* 从当前USB中断的端点缓冲区读取数据块,并释放缓冲区 */ length = CH375_RD_DAT_PORT( ); /* 首先读取后续数据长度 */ for ( i = 0; i < length; i ++ ) buffer[ i ] = CH375_RD_DAT_PORT( ); /* 接收数据包 */ /* 测试数据正确性,将接收到的命令包数据取反后返回给PC机 */ CH375_WR_CMD_PORT( CMD_WR_USB_DATA7 ); /* 向USB端点2的发送缓冲区写入数据块 */ CH375_WR_DAT_PORT( length ); /* 首先写入后续数据长度,回传刚接收到的数据长度 */ for ( i = 0; i < length; i ++ ) CH375_WR_DAT_PORT( ~ buffer[ i ] ); /* 数据取反后返回,由计算机应用程序测试数据是否正确 */ break; } case USB_INT_EP2_IN: { /* 批量数据发送成功 */ CH375_WR_CMD_PORT( CMD_UNLOCK_USB ); /* 释放当前USB缓冲区 */ break; } default: { /* 其它中断,未用到,解锁后退出即可 */ CH375_WR_CMD_PORT( CMD_UNLOCK_USB ); /* 释放当前USB缓冲区 */ break; } } }

main( ) { Delay50ms( ); /* 延时等待CH375初始化完成,如果单片机由CH375提供复位信号则不必延时 */ CH375_Init( ); /* 初始化CH375 */ EA = 1; /* 允许中断 */ while ( 1 ); /* 以下指令开始工作循环,等待PC机命令进行操作 */ }

问题: 1,CH375_D0_D7_DIR = input; /*对于标准双向I/O,请在此设置为输入方向*/ 这个DIR在这里需要用吗?我把这个都屏蔽了的。有错吗?

2,/* 测试CH375是否正常工作,可选操作,通常不需要 */

CH375_WR_CMD_PORT( CMD_CHECK_EXIST ); /* 测试CH375是否正常工作 */ 这个子程序,我怎么也通不过,不需要操作吗??如何继续下面的设置模式啊???

3,我的读,写时序都是很符合单片机的要求的,为何测试还是通不过呢?我应该从哪个方面着手检查?

期待答复,谢谢


原理图不知道怎么抓拍上来,就简单说一下吧,采用的是ds1给的非总线扩展的那个图,除了引脚稍微有所调整,其他的都是一样的。我还要从哪里检查比较合适?麻烦给点意见,谢谢


1、CH375_D0_D7_DIR = input;这个是对于可以设置I/O方向的单片机来说的,你采用89c2051就不需要了; 2、测试命令 CMD_CHECK_EXIST返回的是什么值? 测试命令通不过的话,说明你的硬件上还存在问题,先检查晶振是不是正常起振了,再检查一下连线。测试命令如果过不了的话,下面的设置模式是不会成功的。


我今天调试,CMD_CHECK_EXIST返回值 /* 返回数据应该是测试数据取反 */这个已经可以做到了

设置模式2成功与否,我应该从哪里得知呢?但是依旧无法识别外部设备。

void set_usb_mode( unsigned char mode ) { unsigned char i; unsigned char RD_Data; CH375_WR_CMD_PORT( CMD_SET_USB_MODE ); CH375_WR_DAT_PORT( mode ); for( i=100; i!=0; i-- ) /* 等待设置模式操作完成,不超过30uS */ { RD_Data=CH375_RD_DAT_PORT(); if( RD_Data == CMD_RET_SUCCESS ) return; /* 成功 */ } } 观察窗口RD_Data显示的是2,这样代表成功了吗?但是为何还是无法识别外部硬件呢?我还需要怎么弄呢?请指教,谢谢!!!

PS:我下载了DRV.EXE和 DRV.ZIP,将DRV.EXE放到了解压的DRV的DLL动态链接库同一目录下,已经预安装完成了。


观察窗口RD_Data显示的是2,这样代表成功了吗?但是为何还是无法识别外部硬件呢?我还需要怎么弄呢?请指教,谢谢!!! ---------- 修正一下:刚刚看了datasheet,if( RD_Data == CMD_RET_SUCCESS ),我调试可以看到RD_Data=51H,代表操作是成功的,这个和设置模块有关系吗?我现在关键的问题就是外部设备依旧无法识别!!!


如果RD_Data返回51H的话说明设置模式成功了。前面测试命令过了的话,设置模式一般都能成功的。按你所说你的设置模式应该是成功的,出现提示未知设备可能有几个原因: 1、CH375的GND以及单片机的GND必须与USB的GND可靠地连接; 2、USB的D+和D-信号线接反了,导致通信失败; 3、D+和D-不需要串电阻,如果一定要串也不能大于5欧姆; 4、USB信号线必须用标准的USB线;


感谢楼上的luoye268268,我按照这四个依次检查了,我终于发现,原来当初我在接线的时候曾经接反了D+ D-,甚至电源和地也接反了,于是烧坏过CH372,虽然后来割了电路板修正,但是片子烧坏我一直没有注意了,以为不会烧坏,现在换了一个进行仿真,终于成功的安装了驱动,非常感谢了 同时也感谢hcn的指导。 接下来估计还有更多问题要麻烦你们


楼上的luoye268268,驱动安装成功,为什么拔出来之后再插上去,还是无法识别呢?


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