时钟问题!

我现在用了PHILIPS的P89V51RD2xx单片机,在之前做的板子上做读写U盘实验,文件大小40K左右,晶振为24M,都是正常的,换了新板子,晶振为12M,单片机都为12clock模式,这样,读写U盘就会有个别字节出现乱码的现象,请问:这里面有什么要注意的地方?!

那你把晶振换成24M也会出现乱码的现象吗?这个和晶振没有多大的关系,估计是的程序有问题


晶振换成24M不会出现乱码现象的!


你用的是模拟I/O口的方式来读写U盘的话,如果是模拟I/O口的话,晶振速度太慢会出现出错的问题的


在用12M晶振时,使用的单片机的双时钟模式,应该跟之前的是一样的了,偶尔有个别字节的乱码现象,试了几块板子都是这样,有时候又是好的,感觉是不稳定。用的128M的优盘,FAT32文件系统,这是不是不够最优?说是要优先用FAT16文件系统!


你可以不可以将你的三个读写子程序帖出来看下??


CH375的详细数据手册,你们是不是封装了国外的某个usb接口IC呀?我想自己写一写CH375的驱动


/* CH375 主机文件系统接口 */ /* 支持: FAT12/FAT16/FAT32 */ /* 读取优盘中第n个花样文件 */

#include "CH375.H" #include"Memory.h"

UINT32I tempPos; UINT32I tempAddr;

#ifdef NO_DEFAULT_CH375_INT /* 自行编写中断处理程序,加上了超时处理,并且在等待中断的过程中可以做其它事 */ void xQueryInterrupt( void ) /* 查询CH375中断并更新中断状态,该程序基本框架可以参考CH375HF?.H文件 */ { UINT16 i; for ( i = 65535; i != 0; i -- ) { /* 正常情况下该过程为几毫秒到几十毫秒,偶尔也会达到几百毫秒 */ if ( CH375_INT_WIRE == 0 ) break; /* 如果CH375的中断引脚输出低电平则说明CH375操作完成 */ 在等待CH375中断的过程中,可以做些需要及时处理的事情 } if ( i == 0 ) CH375超时,通常是硬件问题; CH375_CMD_PORT = CMD_GET_STATUS; /* 获取当前中断状态 */ mDelay2uS( ); /* 操作无意义,用于至少延时2uS,可以用多个NOP空操作指令实现 */ CH375IntStatus = CH375_DAT_PORT; /* 获取中断状态 */ if ( CH375IntStatus == USB_INT_DISCONNECT ) CH375DiskStatus = DISK_DISCONNECT; /* 检测到USB设备断开事件 */ else if ( CH375IntStatus == USB_INT_CONNECT ) CH375DiskStatus = DISK_CONNECT; /* 检测到USB设备连接事件 */ } #endif //================================================================================================== /* 以毫秒为单位延时,不精确,适用于24MHz时钟 */ void mDelaymS( UINT8I delay ) { UINT8I i; UINT8I j; UINT8I 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 */ } } //================================================================================================== /* 将程序空间的字符串复制到内部RAM中,返回字符串长度 */ UINT8 mCopyCodeStringToIRAM( UINT8 idata *iDestination, UINT8 code *iSource ) { UINT8 i = 0; while ( *iDestination = *iSource ) { iDestination ++; iSource ++; i ++; } return( i ); } //================================================================================================== /* 检查操作状态,如果错误则显示错误代码并停机 */ void mStopIfError( UINT8 iError ) { if ( iError == ERR_SUCCESS ) return; /* 操作成功 */ while ( 1 ) { mDelaymS( 100 ); mDelaymS( 100 ); } } //================================================================================================== void host( UINT8I n )/*typedef unsigned char idata UINT8I;*/ { UINT8 str[4]; /* 用以存放花样文件名*/ UINT32I i,c,d; /*typedef unsigned long idata UINT32I;*/ UINT32I TotalReadCount,TotalWriteCount;

tempPos = 0x0010000; tempAddr = 0x0010000;

i = CH375LibInit( ); /* 初始化CH375程序库和CH375芯片,操作成功返回0 */ mDelaymS( 100 ); //等待初始化完成 mStopIfError( i ); while ( P1_0 == 0 ) { while ( CH375DiskStatus < DISK_CONNECT ) { /* 等待U盘插入 */ if ( P1_0 == 1 ) { return; } if ( CH375_INT_WIRE == 0 ) xQueryInterrupt( ); /* 如果CH375中断,那么查询CH375中断并更新中断状态,可以改成中断方式 */ mDelaymS( 100 ); /* 没必要频繁查询 */ if ( CH375DiskConnect( ) == ERR_SUCCESS ) break; /* 查询方式: 检查磁盘是否连接,返回成功说明连接 */ } mDelaymS( 250 ); /* 延时,可选操作,有的USB存储器需要几十毫秒的延时 */ //================================================================================================== /* 检查U盘是否准备好,有些U盘不需要这一步,但是某些U盘必须要执行这一步才能工作 */ for ( i = 0; i < 5; i ++ ) { /* 有的U盘总是返回未准备好,不过可以被忽略 */ mDelaymS( 100 ); if ( CH375DiskReady( ) == ERR_SUCCESS ) break; /* 查询磁盘是否准备好 */ } //================================================================================================== /* 读取文件名为CONFID.TXT的花样配置文件,获得需要的第n个花样文件名! */ i = mCopyCodeStringToIRAM( mCmdParam.Open.mPathName, "/CONFIG.TXT"); /* 搜索文件名,*为通配符,适用于所有文件或者子目录*/ i = CH375FileOpen( ); /* 打开文件 */ mStopIfError( i ); if ( i == ERR_MISS_FILE ) break; /* 再也搜索不到匹配的文件,已经没有匹配的文件名 */ if ( i != ERR_SUCCESS ) break; /* 出错 */

mCmdParam.ByteLocate.mByteOffset = (n-1)*4;/* 跳过文件的前(n-1)*4 个字节开始读写*/ CH375ByteLocate( ); mCmdParam.ByteRead.mByteCount = 4; /* 读取4个字节(花样的主文件名长度为4)*/ CH375ByteRead( ); /*直接读取文件的第((n-1)*4+1)个字节到((n-1)*4+4)个字节数据,前(n-1)*4个字节被跳过*/ mStopIfError( i ); for ( i=0; i!=4; i++ ) { str[i]=mCmdParam.ByteRead.mByteBuffer[i]; /* 要读取的花样文件名 */ } i = CH375FileClose( ); /* 关闭文件 */ mStopIfError( i );

/* 读取第n个花样文件! */ mCmdParam.Open.mPathName[0] = '/';

mCmdParam.Open.mPathName[1] = str[0]; /* 要读取的花样文件名 */ mCmdParam.Open.mPathName[2] = str[1]; mCmdParam.Open.mPathName[3] = str[2]; mCmdParam.Open.mPathName[4] = str[3];

mCmdParam.Open.mPathName[5] = '.'; mCmdParam.Open.mPathName[6] = 'T'; mCmdParam.Open.mPathName[7] = 'X'; mCmdParam.Open.mPathName[8] = 'T'; mCmdParam.Open.mPathName[9] = 0x00;

i = CH375FileOpen( ); /* 打开文件 */ mStopIfError( i ); if ( i == ERR_MISS_DIR || i == ERR_MISS_FILE ) break; /* 出错 */ else /* 找到文件 */ { TotalReadCount = CH375vFileSize; /* 准备读取总长度 */ TotalWriteCount = CH375vFileSize; while ( TotalReadCount ) { /* 如果文件比较大,一次读不完,可以再调用CH375ByteRead继续读取,文件指针自动向后移动 */ if ( TotalReadCount > MAX_BYTE_IO ) c = MAX_BYTE_IO; /* 剩余数据较多,限制单次读写的长度不能超过 sizeof( mCmdParam.ByteRead.mByteBuffer ) */ else c = TotalReadCount; /* 最后剩余的字节数 */ mCmdParam.ByteRead.mByteCount = c; /* 请求读出几十字节数据 */ i = CH375ByteRead( ); /* 以字节为单位读取数据块,单次读写的长度不能超过MAX_BYTE_IO,第二次调用时接着刚才的向后读 */ mStopIfError( i ); TotalReadCount -= mCmdParam.ByteRead.mByteCount; /* 计数,减去当前实际已经读出的字符数 */ Setbytes_UDisk( tempPos, c, mCmdParam.ByteRead.mByteBuffer ); tempPos+=mCmdParam.ByteRead.mByteCount;/*修改当前地址*/ } i = CH375FileClose( ); /* 关闭文件 */ mStopIfError( i ); } //================================================================================================== /* 往U盘写文件 */ mCopyCodeStringToIRAM( mCmdParam.Create.mPathName, "/NEWFILE.TXT" ); /* 新文件名,在根目录下,中文文件名 */ i = CH375FileCreate( ); /* 新建文件并打开,如果文件已经存在则先删除后再新建 */ mStopIfError( i ); while( TotalWriteCount ) { if ( TotalWriteCount > MAX_BYTE_IO ) d = MAX_BYTE_IO; /* 剩余数据较多,限制单次读写的长度不能超过 sizeof( mCmdParam.ByteRead.mByteBuffer ) */ else d = TotalWriteCount; /* 最后剩余的字节数 */ Getbytes_UDisk( tempAddr,d,mCmdParam.ByteWrite.mByteBuffer ); tempAddr += d; mCmdParam.ByteWrite.mByteCount = d; TotalWriteCount -= mCmdParam.ByteWrite.mByteCount; i = CH375ByteWrite( ); /* 向文件写入数据 */ mStopIfError( i ); } mCmdParam.Close.mUpdateLen = 1; /* 自动计算文件长度,以字节为单位写文件,建议让程序库关闭文件以便自动更新文件长度 */ i = CH375FileClose( ); mStopIfError( i ); while ( CH375DiskStatus != DISK_DISCONNECT ) xQueryInterrupt( ); /* 查询CH375中断并更新中断状态,等待U盘拔出 */ mDelaymS( 100 ); } }


注解:是将U盘中的文件读到512K的外部RAM中,在从此RAM中读出写到U盘中!


外部晶振用的12M,对内为PHILIPS单片机P89V51RD2xx的6时钟模式! 函数:Setbytes_UDisk()、Getbytes_UDisk()为访问外部RAM的子程序。


另外对“模拟I/O口的方式”的概念不解!


用的是CH375HF6.LIB库!


CH375工作于并口方式!


也就是模拟I/O口方式!


模拟I/O口方式读写优盘,连CH375的晶振一直用的是12M,现在只是将连单片机的晶振由24M换成了12M!


那你有没有测试你的RAM是不是好的呢???还有就是你的程序好象少了很多库里面的定义


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