我用的STC单片机,型号为89LE58RD+(支持到80Mhz),外部RAM32k,选用的是3.3V供电的CH375V。单片机24Mhz晶振,在往U盘写数据时不稳定(扇区方式,文件方式),成功时速度能达到75k字节/秒。出错的情况有以下几种(1)很多时候写到一定时候就不动了,好像在writeX函数里出不来;(2)有时候能写完,但是文件打不开,(3)有时候文件名都是错误的,而且删不掉!我的程序如下:请帮忙解决!!是否3.3V的没有5V的稳定??
#include #include #include #include #include
//#define EN_DISK_WRITE #define LIB_CFG_DISK_IO 3 /* 磁盘读写的数据的复制方式,1为"单DPTR复制",2为"双DPTR复制",3为"单DPTR和P2+R0复制" */ #define LIB_CFG_FILE_IO 3 /* 文件读写的数据的复制方式,0为"外部子程序",1为"单DPTR复制",2为"双DPTR复制",3为"单DPTR和P2+R0复制" */ #define LIB_CFG_INT_EN 0 /* CH375的INT#引脚连接方式,0为"查询方式",1为"中断方式" */
#define CH375_CMD_PORT_ADDR 0x8041 /* CH375命令端口的I/O地址 */
#define CH375_DAT_PORT_ADDR 0x8040 /* CH375数据端口的I/O地址 */
#define DISK_BASE_BUF_ADDR 0x0000 /* 外部RAM的磁盘数据缓冲区的起始地址,从该单元开始的缓冲区长度为SECTOR_SIZE */ #define FILE_DATA_BUF_ADDR 0x0300 /* 外部RAM的文件数据缓冲区的起始地址,缓冲区长度不小于一次读写的数据长度 */
#define FILE_DATA_BUF_LEN 0x7800//0x7800 /* 外部RAM的文件数据缓冲区,缓冲区长度不小于一次读写的数据长度 */
#define CH375_INT_WIRE INT1 /* P3.2, INT0, CH375的中断线INT#引脚,连接CH375的INT#引脚,用于查询中断状态 */ //#define CH375_INT_NO 1// 0 /* CH375中断号, CH375的中断线INT#引脚连接单片机的INT0引脚 */ //#define CH375_INT_FLAG IE0 /* 外部中断0请求标志,IE0,CH375中断标志 */ //#define CH375_INT_EN EX0 /* 开外部中断0,EX0,CH375中断允许 */
#define NO_DEFAULT_CH375_F_ENUM 1 /* 未调用CH375FileEnumer程序故禁止以节约代码 */ #define NO_DEFAULT_CH375_F_QUERY 1 /* 未调用CH375FileQuery程序故禁止以节约代码 */ //#define NO_DEFAULT_CH375_INT
#include "..\CH375HF6.H" /* 如果不需要支持FAT32,那么请选用CH375HF4.H */
void mDelay100mS( )/* 延时100毫秒,不精确 */ { UINT8 i, j, c; for ( i = 200; i != 0; i -- ) for ( j = 200; j != 0; j -- ) c+=3; }
/* 将程序空间的字符串复制到内部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; /* 操作成功 */ printf( "Error: %02X\n", (UINT16)iError ); /* 显示错误 并且P1_4闪烁*/ while ( 1 ) { mDelay100mS( ); mDelay100mS( ); } }
/* 为printf和getkey输入输出初始化串口 */ void serialinit( ) { SCON = 0x50; PCON = 0x80; TMOD = 0x20; TH1 = 0xe6; //0xf3; // /* 0xf3 24MHz晶振, 9600bps */ TR1 = 1; TI = 1; }
//unsigned char xdata FILE_DATA_BUF[ FILE_DATA_BUF_LEN ] _at_ FILE_DATA_BUF_ADDR; //在SRAM中指定位置定义一个数组
main( ) {
UINT8 i;//,jj,s,d;
UINT16 cishu,ij;//flag=0, /* 因为演示板的RAM容量只有32KB,所以NewSize限制为16位,实际上如果文件大于32256字节,应该分几次读写并且将NewSize改为UINT32以便累计 */
AUXR = 0x02;//禁止访问内部扩展RAM
mDelay100mS( );// mDelay100mS( ); /* 延时100毫秒 */ serialinit( ); /*串口初始化, */
//for(ij=0;ij // {FILE_DATA_BUF[ ij ] = 0x80;}
printf( "Start\n" ); mDelay100mS( );// mDelay100mS( );// mDelay100mS( ); i = CH375LibInit( ); /* 初始化CH375程序库和CH375芯片,操作成功返回0 */ mStopIfError( i );
// IE1 = 0;//IE0 = 0;// /* 清中断请求标志 */ // IT1 = 0; // EX1 = 1;//EX0 = 1;// /* 允许CH375中断 */ // EA = 1; /* 初始化完成,开中断 */
mDelay100mS( );// while ( 1 ) { mDelay100mS( ); printf( "Wait Udisk\n" ); // while ( CH375DiskStatus != DISK_CONNECT ) xQueryInterrupt( ); /* 等待U盘插入中断,查询CH375中断并更新中断状态,等待U盘插入 */ while ( CH375DiskStatus < DISK_CONNECT ) { /* 查询CH375中断并更新中断状态,等待U盘插入 */ if ( CH375DiskConnect( ) == ERR_SUCCESS ) break; /* 有设备连接则返回成功,CH375DiskConnect同时会更新全局变量CH375DiskStatus */ mDelay100mS( );
} mDelay100mS( ); /* 延时,可选操作,有的USB存储器需要几十毫秒的延时 */ mDelay100mS( ); /* 检查U盘是否准备好*/ for ( i = 0; i < 5; i ++ ) { mDelay100mS( ); printf( "Ready ?\n" ); if ( CH375DiskReady( ) == ERR_SUCCESS ) break; /* 查询磁盘是否准备好 */ }
#ifdef EN_DISK_WRITE /* 产生新文件 */
printf( "Create\n" ); mDelay100mS( ); mCopyCodeStringToIRAM( mCmdParam.Create.mPathName, "/FDATA.TXT" );
mDelay100mS( ); i = CH375FileCreate( ); mStopIfError( i ); printf( "Write\n" );
mDelay100mS( ); mDelay100mS( ); mDelay100mS( ); mDelay100mS( ); mDelay100mS( );
//mCmdParam.Write.mSectorCount = SecCount; /* 写入所有扇区的数据 */ for(cishu=0;cishu<300;cishu++) {
mCmdParam.Locate.mSectorOffset = (cishu)*60+60; //1,写60个扇区(30k),移到文件的尾部,以扇区为单位 _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); i = CH375FileLocate(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); mCmdParam.WriteX.mSectorCount = 60; /******************************************************************/
_nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_();
mCmdParam.WriteX.mDataBuffer = 0x0300;
/******************************************************************/ _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_();
// CH375FileWrite(); //在原文件的后面添加数据 // mDelay100mS( ); // mDelay100mS( );
CH375FileWriteX(); //在原文件的后面添加数据
_nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_();
mCmdParam.Modify.mFileAttr = 0xff; /* 输入参数: 新的文件属性,为0FFH则不修改 */ _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); mCmdParam.Modify.mFileTime = 0xffff; /* 输入参数: 新的文件时间,为0FFFFH则不修改,使用新建文件产生的默认时间 */ _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); // mCmdParam.Modify.mFileDate = MAKE_FILE_DATE( 2007, 8, 10 ); /* 输入参数: 新的文件日期: 2004.05.18 */ mCmdParam.Modify.mFileDate = 0xffff; _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_();
mCmdParam.Modify.mFileSize = CH375vFileSize; _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); // mCmdParam.Modify.mFileSize = NewSize; /* 输入参数: 如果原文件较小,那么新的文件长度与原文件一样长,否则被RAM所限,如果文件长度大于64KB,那么NewSize必须为UINT32 */ i = CH375FileModify( ); /* 修改当前文件的信息,修改日期和长度 */ mStopIfError( i ); // printf( "6\n" );
}
mCmdParam.Close.mUpdateLen = 0; /* 不要自动计算文件长度,如果自动计算,那么该长度总是512的倍数 */
_nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); i = CH375FileClose( ); mStopIfError( i );
printf( "Close\n" ); #endif printf( "Take out\n" ); mDelay100mS( ); mDelay100mS( ); // while ( CH375DiskStatus != DISK_DISCONNECT ) xQueryInterrupt( ); /* 等待中断,查询CH375中断并更新中断状态,等待U盘拔出 */ while ( CH375DiskStatus >= DISK_CONNECT ) { /* 查询CH375中断并更新中断状态,等待U盘拔出 */ if ( CH375DiskConnect( ) != ERR_SUCCESS ) break; mDelay100mS( ); } mDelay100mS( ); mDelay100mS( ); mDelay100mS( ); mDelay100mS( ); } }