关于 CH374

我用374读写U盘 CH374LibInit( );成功执行后,多次调用CH374DiskConnect(),返回值交替为ERR_SUCCESS和ERR_DISK_DISCON。但是同此时读取374寄存器发现寄存器内值是一样的: C9 40 80 F3 00 A0 C0 00 00 D0 00(从04-0E号寄存器)

寄存器REG_INTER_FLAG的值一直保持A0--1 0 1 0 0 0 0 0 位 7 6 5 4 3 2 1 0 位5 BIT_IF_DEV_ATTACH(USB 设备的当前连接状态) 0=尚未连接/断开/拔出;1=已经连接/插入 综上,寄存器可知U盘一直连接的,但是函数CH374DiskConnect返回值却不同,这是为什么?? 麻烦解释下,不胜感激

寄存器能知道U盘连接,函数CH374DiskConnect()应该是返回成功的.

你是用中断方式还是用查询方式检测U盘连接的 要是中断方式你给定义中断引脚去掉,采用查询寄存器方式试下可不可以.


还有就是你的库可能没链接进去


如果库没有链接进去,我的CH374DiskConnect(),及CH374DiskReady()怎么还能使用并会返回值呢?


是用例子程序还是自己写的程序,CH374DiskConnect()函数是自己写的吗?可加了延时?U盘插上时,有时会产生抖动,要加延时


可以不可以将程序帖出来看下??????


#include #include #include

/* 以下定义的详细说明请看CH374HF6.H文件 */ #define LIB_CFG_INT_EN 0 /* CH374的INT#引脚连接方式,0为"查询方式",1为"中断方式" */

#define CH374_IDX_PORT_ADDR 0xDFFF /* CH374索引端口的I/O地址 */ #define CH374_DAT_PORT_ADDR 0x9FFF /* CH374数据端口的I/O地址 */ /* 62256提供的32KB的RAM分为两部分: 0000H-01FFH为磁盘读写缓冲区, 0200H-7FFFH为文件数据缓冲区 */ #define DISK_BASE_BUF_ADDR 0x0000 /* 外部RAM的磁盘数据缓冲区的起始地址,从该单元开始的缓冲区长度为SECTOR_SIZE */

#define CH374_INT_WIRE INT0 /* P3.2, INT0, CH374的中断线INT#引脚,连接CH374的INT#引脚,用于查询中断状态 */ /* 如果未连接CH374的中断引脚,那么应该去掉上述定义,自动使用寄存器查询方式 */

#define DISK_BASE_BUF_LEN 2048 /* 默认的磁盘数据缓冲区大小为512字节,建议选择为2048甚至4096以支持某些大扇区的U盘,为0则禁止在.H文件中定义缓冲区并由应用程序在pDISK_BASE_BUF中指定 */ /* 如果需要复用磁盘数据缓冲区以节约RAM,那么可将DISK_BASE_BUF_LEN定义为0以禁止在.H文件中定义缓冲区,而由应用程序在调用CH375Init之前将与其它程序合用的缓冲区起始地址置入pDISK_BASE_BUF变量 */

#define NO_DEFAULT_CH374_F_ENUM 1 /* 未调用CH374FileEnumer程序故禁止以节约代码 */ #define NO_DEFAULT_CH374_F_QUERY 1 /* 未调用CH374FileQuery程序故禁止以节约代码 */ #define NO_DEFAULT_CH374_RESET 1 /* 未调用CH374Reset程序故禁止以节约代码 */

#include "CH374HF6.H"

unsigned char R_buffer[2]; //用户指令缓存区1,大小暂时定为8 unsigned char R_count; //按字节输入指令时作计数器用 UINT8X my_buffer[ 0x7000 ]; /* 外部RAM的文件数据缓冲区 */ unsigned char FLAG; /* 如果准备使用双缓冲区交替读写,那么可以在参数中指定缓冲区起址 */

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 send_char(unsigned char send_pcdata) {

ES=0; //暂时关中断 SBUF=send_pcdata; while(1) { if(TI==1) //等待输出缓冲区为空;发送完一帧后单片机置TI=1 break; } TI=0; //申请输出缓冲区 ES=1; //开中断,串口传输 }

void send_string(unsigned char code *send_pcdata)//关键字code起了很大的作用,而没有使用code定义的*string,说明指针是一般类型,可以指向代码空间,内部ram 空间或外部ram空间。 //使用code定义的说明仅指向代码空间 { while(*send_pcdata!=0) { send_char(*send_pcdata); send_pcdata++; } }

/* 检查操作状态,如果错误则显示错误代码并停机 */ void mStopIfError( UINT8 iError ) { if ( iError == ERR_SUCCESS ) return; /* 操作成功 */ send_string( "Error: ");send_char((UINT16)iError+48); send_string("\n"); /* 显示错误 */ /* 遇到错误后,应该分析错误码以及CH374DiskStatus状态,例如调用CH374DiskConnect查询当前U盘是否连接,如果U盘已断开那么就重新等待U盘插上再操作, 建议出错后的处理步骤: 1、调用一次CH374DiskReady,成功则继续操作,例如Open,Read/Write等,在CH374DiskReady中会自动调用CH374DiskConnect,不必另外调用 2、如果CH374DiskReady不成功,那么强行将CH374DiskStatus置为DISK_CONNECT状态,然后从头开始操作(等待U盘连接CH374DiskConnect,CH374DiskReady等) */ while ( 1 ) { send_string("error\n"); mDelaymS( 100 ); mDelaymS( 100 ); } }

void uart(void) interrupt 4 using 3//串行口中断 { if(RI==1) //pc通过串口发送过来数据 // 输入缓冲区可以使用 { RI = 0; //申请输入缓冲区 R_buffer[R_count]=SBUF;//读入一个字节用户指令 R_count++; //下一个字节用户指令 if(R_buffer[0]!= 0xff) //不以"ff"开头即为无效指令,若发生,重新读取 { R_count=0; } if((R_count==2)&&(R_buffer[0]==0xff)) //读满四个有效字节,完成一次指令读取,释放输入缓冲,置读有效标志位 { R_count=0; FLAG=1; } } else//TI=1;单片机请求发送 { TI = 0; //没读完时申请输出缓冲区发送 } }

/* 为printf和getkey输入输出初始化串口 */ void mInitSTDIO( ) { SCON = 0x50; PCON = 0x80; TMOD = 0x20; TH1 = 244; /* 22.1184MHz晶振, 9600bps */ TR1 = 1; TI = 1; EA=1; }

void initram()//初始化外部ram0x0000--0x7000 { int i,j,k,l; for(i=0;i<7;i++) { for(j=0;j<15;j++) { for(k=0;k<15;k++) { for(l=0;l<15;l++) my_buffer[l+16*k+j*16*16+i*16*16*16]=l%2; } } } }

void read_RE() { UINT8 mAddr,i,j; i=0; for(mAddr=0x04;mAddr<0x0F;mAddr++) { send_char(0xFF); send_char(mAddr); j=CH374_READ_REGISTER( mAddr ); send_char(j); } }

main( ) { UINT8 i,j, SecCount=10,UnknownUsbDevice=0; UINT16 NewSize;// count; /* 因为演示板的RAM容量只有32KB,所以NewSize限制为16位,实际上如果文件大于32256字节,应该分几次读写并且将NewSize改为UINT32以便累计 */ // UINT8 code *pCodeStr; FLAG=0; R_count=0;

for(i=0;i<2;i++) R_buffer[i]=0; mDelaymS( 100 ); /* 延时100毫秒 */ initram();

mInitSTDIO(); /* 为了让计算机通过串口监控演示过程 */ send_char( 0x00 );send_char( 0x00 );send_char(0x0A); #if DISK_BASE_BUF_LEN == 0 pDISK_BASE_BUF = &my_buffer[0]; /* 不在.H文件中定义CH374的专用缓冲区,而是用缓冲区指针指向其它应用程序的缓冲区便于合用以节约RAM */ #endif i = CH374LibInit( ); /* 初始化CH374程序库和CH374芯片,操作成功返回0 */ send_char(0x00); mStopIfError( i ); mDelaymS( 50 );

CH374Init( ); mDelaymS( 200 ); while ( 1 ) { while ( CH374DiskStatus < DISK_CONNECT ) { /* 查询CH374中断并更新中断状态,等待U盘插入 */ i=CH374DiskConnect( ); /* 查询U 盘是否连接,返回ERR_SUCCESS 则说明当前已连接 */ mDelaymS(100 ); /* 没必要频繁查询 */ } send_char(0xAA);send_char(0xAA); for ( i = 0; i < 100; i ++ ) { /* 最长等待时间,100*50mS */ mDelaymS(100 ); j=CH374DiskReady( ); send_char(0xBB); send_char(j); send_char(0xaa); if ( j == ERR_SUCCESS ) break; /* 查询磁盘是否准备好 */ if ( CH374DiskStatus < DISK_CONNECT ) break; /* 检测到断开,重新检测并计时 */ if ( CH374DiskStatus >= DISK_MOUNTED && i > 5 ) break; /* 有的U盘总是返回未准备好,不过可以忽略,只要其建立连接MOUNTED且尝试5*50mS */ } send_char(0xaa); send_char(CH374DiskStatus); send_char(0xaa); #ifdef EN_DISK_WRITE /* 子程序库支持写操作 */ /* 产生新文件 */ send_string( "Create\n" ); strcpy( mCmdParam.Create.mPathName, "\\NEWFILE.TXT" ); /* 新文件名,在根目录下 */ i = CH374FileCreate( ); /* 新建文件并打开,如果文件已经存在则先删除后再新建 */ mStopIfError( i ); send_string( "Write\n" ); mCmdParam.WriteX.mSectorCount = 1; /* 写入所有扇区的数据 */ mCmdParam.WriteX.mDataBuffer = &my_buffer[0]; /* 指向文件数据缓冲区的起始地址 */ i = CH374FileWriteX( ); /* 向文件写入数据 */ mStopIfError( i ); /* 默认情况下,如果扇区数mCmdParam.WriteX.mSectorCount不为0那么CH374FileWriteX只负责写入数据而不修改文件长度, 如果长时间不写入数据则应该更新文件长度,防止突然断电后前面写入的数据与文件长度不相符, 如果需要写完数据后立即修改/更新文件长度,那么可以置扇区数mCmdParam.WriteX.mSectorCount为0后调用CH374FileWriteX强行更新文件长度, 如果确定不会突然断电或者后面很快有数据不断写入则不必更新文件长度,可以提高速度并减少U盘损耗(U盘内部的内存寿命有限,不宜频繁改写) */ send_string( "Close\n" ); mCmdParam.Close.mUpdateLen = 0; /* 不要自动计算文件长度,如果自动计算,那么该长度总是CH374vSectorSize的倍数 */ i = CH374FileClose( ); mStopIfError( i ); #endif

while(1) if(FLAG==1) { send_char(0x11); read_RE(); FLAG=0; break; }

} }


我是用查询方式检测U盘是否连接的


for(i=0;i<2;i++) R_buffer=0; 应改为:for(i=0;i<2;i++) R_buffer=0; 软件没问题,可以操作的,你查下你的硬件,索引端口,数据端口地址是否正确?U盘插上时UD+,UD-的电压是多少?


应改为:for(i=0;i<2;i++) R_buffer[i]=0;


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