程序从a.txt中读取一串数据,假如是 Hello,the world!将读的数据存放到DATA_BUF中,再将DATA_BUF中的数据写入创建的文件NEWFILE.txt中,在电脑上打开此文件,看到的却是乱码。我始终弄不明白这是为什么,请各位各位哥哥姐姐们帮帮忙啊!
我的程序如下: #include #include #include #include
#define MAX_PATH_LEN 32 #include "CH375HM.H"
/* 电路连接方式 单片机 模块 P0 = D0-D7 RD = RD# WR = WR# P26 = CS# P20 = A0 P15 = STA# INT0 = INT# */ #define CH375HM_INDEX XBYTE[0xBCF0]/* CH375模块的索引端口的I/O地址 */ #define CH375HM_DATA XBYTE[0xBDF1]/* CH375模块的数据端口的I/O地址 */ #define CH375HM_INT_WIRE INT0 /* CH375模块的INT#引脚连接到单片机的INT0引脚 */ sbit P15 = P1^5; #define CH375HM_STA P15 /* CH375模块的STA#引脚连接到单片机的P15引脚 */
/* 文件数据缓冲区: ExtRAM: 0000H-7FFFH */ unsigned char xdata DATA_BUF[ 512 * 64 ] _at_ 0x0000;
CMD_PARAM mCmdParam; unsigned char mIntStatus; /* CH375模块的中断状态或者操作完成状态 */
sbit LED_OUT0 = P1^0; sbit LED_OUT1 = P1^1;
sbit KEY = P1^3;
#define CH375HM_INDEX_WR( Index ) { CH375HM_INDEX = (Index); } /* 写索引地址 */ #define CH375HM_DATA_WR( Data ) { CH375HM_DATA = (Data); } /* 写数据 */ #define CH375HM_DATA_RD( ) ( CH375HM_DATA ) /* 读数据 */
void mDelaymS( unsigned char delay ) { unsigned char i, j, c; for ( i = delay; i != 0; i -- ) { for ( j = 200; j != 0; j -- ) c += 3; for ( j = 200; j != 0; j -- ) c += 3; } }
void mPressKey() { while ( 1 == KEY ) { LED_OUT0 = 0; LED_OUT1 = 1; mDelaymS(500); LED_OUT0 = 1; LED_OUT1 = 0; mDelaymS(500); } mDelaymS(200); KEY = 1; mDelaymS(200); LED_OUT0 = 0; mDelaymS(200); LED_OUT1 = 1; }
/* 执行命令 */ unsigned char ExecCommandBuf( unsigned char cmd, unsigned char len, unsigned ar xdata *bufstart ) { unsigned char i, status; #define DataCount status unsigned char data *buf; unsigned char xdata *CurrentBuf; CH375HM_INDEX_WR( 0 ); /* 索引地址置0 */ CH375HM_DATA_WR( cmd ); /* 向索引地址0写入命令码 */ CH375HM_DATA_WR( len ); /* 向索引地址1写入后续参数的长度 */ if ( len ) /* 有参数 */ { i = len; buf = (unsigned char *)&mCmdParam; /* 指向输入参数的起始地址 */ do { CH375HM_DATA_WR( *buf ); /* 从索引地址2开始,写入参数 */ buf ++; } while ( -- i ); } CH375HM_STA = 0; /* 产生下降沿通知模块,说明命令包已经写入,请求开始执行命令 */ CurrentBuf = bufstart; while ( 1 ) /* 处理数据传输,直到操作完成才退出 */ { while ( CH375HM_INT_WIRE ); CH375HM_INDEX_WR( 63 ); status = CH375HM_DATA_RD( ); CH375HM_STA = 1; /* 中断应答,取消来自模块的中断请求 */ if ( status == ERR_SUCCESS ) /* 操作成功 */ { CH375HM_INDEX_WR( 1 ); DataCount = CH375HM_DATA_RD( ); /* 从索引地址1读取返回结果数据的长度,计数 */ if ( DataCount ) /* 有结果数据 */ { buf = (unsigned char *)&mCmdParam; /* 指向输出参数的起始地址 */ i = 2; do { CH375HM_INDEX_WR( i ); i ++; *buf = CH375HM_DATA_RD( ); /* 从索引地址2开始,读取结果 */ buf ++; } while ( -- DataCount ); } break; /* 操作成功返回 */ } else if ( status == USB_INT_DISK_READ ) { /* 正在从U盘读数据块,请求数据读出 */ DataCount = 64; /* 计数 */ i = 0; do { CH375HM_INDEX_WR( i ); i ++; *CurrentBuf = CH375HM_DATA_RD( ); /* 从索引地址0到63依次读出64字节的数据 */ CurrentBuf ++; /* 读取的数据保存到外部缓冲区 */ } while ( -- DataCount ); CH375HM_STA = 0; /* 产生下降沿通知模块继续,说明64字节数据已经读取完成 */ } else if ( status == USB_INT_DISK_WRITE ) /* 正在向U盘写数据块,请求数据写入 */ { CH375HM_INDEX_WR( 0 ); i = 64; do { CH375HM_DATA_WR( *CurrentBuf ); /* 向索引地址0到63依次写入64字节的数据 */ CurrentBuf ++; /* 写入的数据来自外部缓冲区 */ } while ( -- i ); CH375HM_STA = 0; /* 产生下降沿通知模块继续,说明64字节数据已经写入完成 */ } else if ( status == USB_INT_DISK_RETRY ) /* 读写数据块失败重试,应该向回修改缓冲区指针 */ { CH375HM_INDEX_WR( 0 ); i = CH375HM_DATA_RD( ); CH375HM_INDEX_WR( 1 ); DataCount = CH375HM_DATA_RD( ); CurrentBuf -= ( (unsigned short)i << 8 ) + DataCount; CH375HM_STA = 0; /* 产生下降沿通知模块继续,说明重试状态码已经处理完成 */ } else { /* 操作失败 */ if ( status == ERR_DISK_DISCON || status == ERR_USB_CONNECT ) mDelaymS( 100 ); /* U盘刚刚连接或者断开,应该延时几十毫秒再操作 */ break; /* 操作失败返回 */ } }
return( status ); }
/* 执行命令 */ unsigned char ExecCommand( unsigned char cmd, unsigned char len ) { return( ExecCommandBuf( cmd, len, 0 ) ); }
void mStopIfError( unsigned char iError ) { unsigned char led; if ( iError == ERR_SUCCESS ) return; /* 操作成功 */ led=0; while ( 1 ) { LED_OUT0 = led&1; /* LED闪烁 */ mDelaymS( 1000 ); led^=1; } }
/* 为printf和getkey输入输出初始化串口 */ void mInitSTDIO( ) { SCON = 0x50; //串口控制寄存器串口模式为1,8位UART,允许接收 PCON = 0x00; //电源控制寄存器 SMOD1=0 波特率为振荡器的/64 TMOD = 0x20; //定时器的模式控制位 使用定时器1定时,采用8位自载定时器, TH1 = 0xFD; TL1 = 0xFD; //11.0529MHz晶振, 9600 bps TR1 = 1; //定时器运行 TI = 1; //发送中断标志位
mDelaymS(200); LED_OUT0 = 1; mDelaymS(200); LED_OUT1 = 1; mDelaymS(200); KEY = 1; mDelaymS(200); }
void main( ) { unsigned char i, c, SecCount; unsigned long OldSize; unsigned short NewSize; LED_OUT0 = 0; /* 开机后LED亮一下以示工作 */ mDelaymS( 1000 ); LED_OUT0 = 1; mInitSTDIO( );
while ( 1 ) /* 主循环 */ { /* 使用查询方式看U盘是否连接 */ while ( 1 ) { i = ExecCommand( CMD_QueryStatus, 0 ); mStopIfError( i ); if ( mCmdParam.Status.mDiskStatus >= DISK_CONNECT ) break; /* U盘已经连接 */ mDelaymS( 1000 ); } mDelaymS( 1000 ); LED_OUT0 = 0; /* LED亮 */ while ( ExecCommand( CMD_DiskReady, 0 ) != ERR_SUCCESS ) { mDelaymS( 1000 ); /* 查询磁盘是否准备好 */ }
mPressKey(); mDelaymS(5000);
/* 读取原文件 */ memcpy( mCmdParam.Open.mPathName, "\\A.TXT", MAX_PATH_LEN ); i = ExecCommand( CMD_FileOpen, MAX_PATH_LEN ); if ( i == ERR_MISS_DIR || i == ERR_MISS_FILE ) { for ( c = 0; c < 255; c ++ ) { /* 最多搜索前255个文件 */ memcpy( mCmdParam.Enumer.mPathName, "\\*", MAX_PATH_LEN ); /* 搜索文件名,*为通配符,适用于所有文件或者子目录 */ for ( i = 0; i < MAX_PATH_LEN - 1; i ++ ) if ( mCmdParam.Enumer.mPathName[ i ] == 0 ) break; /* 指向搜索文件名的结束符 */ mCmdParam.Enumer.mPathName[ i ] = c; /* 将结束符替换为搜索的序号,从0到255 */ i = ExecCommand( CMD_FileEnumer, i+1 ); /* 枚举文件,如果文件名中含有通配符*,则为搜索文件而不打开,输入参数的长度很好计算 */ if ( i == ERR_MISS_FILE ) break; /* 再也搜索不到匹配的文件,已经没有匹配的文件名 */ if ( i == ERR_SUCCESS ) { /* 搜索到与通配符相匹配的文件名,文件名及其完整路径在命令缓冲区中 */ continue; /* 继续搜索下一个匹配的文件名,下次搜索时序号会加1 */ } else { /* 出错 */ mStopIfError( i ); break; } } strcpy( DATA_BUF, "Note: \xd\n没找到文件!\xd\n" ); OldSize = 0; NewSize = strlen( DATA_BUF ); SecCount = ( NewSize + 511 ) >> 9; } else { /* 找到文件或者出错 */ mStopIfError( i ); i = ExecCommand( CMD_FileQuery, 0 ); /* 查询当前文件的信息,没有输入参数 */ mStopIfError( i ); OldSize = mCmdParam.Modify.mFileSize; if ( OldSize > (unsigned long)(64*512) ) { SecCount = 64; NewSize = 64*512; } else { SecCount = ( OldSize + 511 ) >> 9; NewSize = (unsigned short)OldSize; } mCmdParam.Read.mSectorCount = SecCount; /* 读取全部数据 */ i = ExecCo