⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ch375hf1.c

📁 u盘读写模块.C51单片机与USB接口芯片对U盘进行文件读写,支持FAT8,FAT16和FAT32磁盘格式.
💻 C
📖 第 1 页 / 共 5 页
字号:
											status = CH375ByteWrite( );  /* 刷新文件长度 */
										}
										if ( status != ERR_SUCCESS ) {  /* 操作失败 */
											RetLen = SER_STREAM_ERROR;  /* 提示错误 */
											goto StreamExitSend;
										}
									}
								}
							}
							TR0 = 0;  /* 关闭定时器 */
						}
						RI = 0;
						RetLen = SBUF;
						while ( TI == 0 );
						if ( RetLen == SER_STREAM_END || RetLen == SER_STREAM_FLUSH ) {  /* 要求退出,要求刷新 */
							status = CH375ByteWrite( );  /* 将缓冲区中的数据写入文件 */
							if ( status == ERR_SUCCESS ) {  /* 操作成功 */
								mCmdParam.ByteWrite.mByteCount = 0;
								status = CH375ByteWrite( );  /* 刷新文件长度 */
							}
							if ( status == ERR_SUCCESS && RetLen == SER_STREAM_FLUSH ) {  /* 刷新文件长度成功 */
								TI = 0;
								SBUF = SER_STREAM_ACK;  /* 应答 */
								continue;
							}
							RetLen = status == ERR_SUCCESS ? SER_STREAM_ACK : SER_STREAM_ERROR;  /* 提示 */
							break;
						}
						mCmdParam.ByteWrite.mByteBuffer[ mCmdParam.ByteWrite.mByteCount ] = RetLen;
						mCmdParam.ByteWrite.mByteCount ++;
						if ( mCmdParam.ByteWrite.mByteCount == MAX_BYTE_IO ) {  /* 缓冲区已满 */
							status = CH375ByteWrite( );  /* 将缓冲区中的数据写入文件 */
							mCmdParam.ByteWrite.mByteCount = 0;
							if ( status == ERR_SUCCESS && ( (UINT16)CH375vFileSize & 0x01FF ) - 1 < MAX_BYTE_IO ) {  /* 操作成功,数据已经写到新扇区中 */
								status = CH375ByteWrite( );  /* 刷新文件长度 */
							}
							if ( status != ERR_SUCCESS ) {  /* 操作失败 */
								RetLen = SER_STREAM_ERROR;  /* 提示错误 */
								break;
							}
						}
						TI = 0;
						SBUF = SER_STREAM_ACK;  /* 应答 */
					}
					goto StreamExitSend;
					break;
				case CMD_BulkOnlyCmd:  /* 执行基于BulkOnly协议的命令 */
					status = CH375BulkOnlyCmd( );
					if ( status == ERR_SUCCESS ) RetLen = sizeof( mCmdParam.BOC.mCSW );  /* 操作成功则返回结果 */
					break;
				case CMD_DiskReady:  /* 查询磁盘是否准备好 */
					status = CH375DiskReady( );
					break;
				case CMD_DiskSize:  /* 查询磁盘容量 */
					status = CH375DiskSize( );
					if ( status == ERR_SUCCESS ) RetLen = sizeof( mCmdParam.DiskSize );  /* 操作成功则返回结果 */
					break;
				case CMD_DirCreate:  /* 新建目录并打开,如果目录已经存在则直接打开 */
					DirNameStart = 0xFF;
					for ( RetLen = 0; RetLen != MAX_PATH_LEN; RetLen ++ ) {
						c = mCmdParam.DirCreate.mPathName[ RetLen ];
						if ( c == 0 ) break;
						if ( c == PATH_SEPAR_CHAR1 || c == PATH_SEPAR_CHAR2 ) DirNameStart = RetLen;
					}
					if ( DirNameStart == 0 || DirNameStart == 2 && mCmdParam.DirCreate.mPathName[1] == ':' ) UpDirCluster = 0;
					else {
						if ( DirNameStart != 0xFF ) {
							mCmdParam.DirCreate.mPathName[ DirNameStart ] = 0;
							RetLen = DirNameStart;
							status = CH375FileOpen( );
							if ( status == ERR_SUCCESS ) status = ERR_MISS_DIR;
							else if ( status == ERR_OPEN_DIR ) status = ERR_SUCCESS;
							mCmdParam.DirCreate.mPathName[ RetLen ] = PATH_SEPAR_CHAR1;
						}
						UpDirCluster = CH375vStartCluster;
					}
					if ( status == ERR_SUCCESS ) {
						status = CH375FileOpen( );
						if ( status == ERR_SUCCESS ) status = ERR_FOUND_NAME;
						else if ( status == ERR_OPEN_DIR ) status = ERR_SUCCESS;
						else if ( status == ERR_MISS_FILE ) {
							status = CH375FileCreate( );
							if ( status == ERR_SUCCESS ) {
								CH375DirtyBuffer( );  /* 清除磁盘缓冲区 */
								mClrDiskBaseBuf( );  /* 磁盘缓冲区清零 */
								DirXramBuf = &DISK_BASE_BUF[0];
								DirConstData = ".          \x10\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x21\x30\x0\x0\x0\x0\x0\x0..         \x10\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x0\x21\x30\x0\x0\x0\x0\x0\x0";
								for ( RetLen = 0x40; RetLen != 0; RetLen -- ) {
									*DirXramBuf = *DirConstData;
									DirXramBuf ++;
									DirConstData ++;
								}
								DISK_BASE_BUF[0x1A] = ( (PUINT8I)&CH375vStartCluster )[3];
								DISK_BASE_BUF[0x1B] = ( (PUINT8I)&CH375vStartCluster )[2];
								DISK_BASE_BUF[0x14] = ( (PUINT8I)&CH375vStartCluster )[1];
								DISK_BASE_BUF[0x15] = ( (PUINT8I)&CH375vStartCluster )[0];
								DISK_BASE_BUF[0x20+0x1A] = ( (PUINT8I)&UpDirCluster )[3];
								DISK_BASE_BUF[0x20+0x1B] = ( (PUINT8I)&UpDirCluster )[2];
								DISK_BASE_BUF[0x20+0x14] = ( (PUINT8I)&UpDirCluster )[1];
								DISK_BASE_BUF[0x20+0x15] = ( (PUINT8I)&UpDirCluster )[0];
								CH375LibConfig |= 0x08;  /* 文件数据复制方式切换为"双DPTR复制" */
								mCmdParam.Write.mSectorCount = 1;
								mCmdParam.WriteX.mDataBuffer = &DISK_BASE_BUF[0];
								status = CH375FileWriteX( );
								if ( status == ERR_SUCCESS ) {
									mClrDiskBaseBuf( );  /* 磁盘缓冲区清零 */
									for ( RetLen = 1; RetLen != CH375vSecPerClus; RetLen ++ ) {
										CH375DirtyBuffer( );  /* 清除磁盘缓冲区 */
										mCmdParam.Write.mSectorCount = 1;
										mCmdParam.WriteX.mDataBuffer = &DISK_BASE_BUF[0];
										status = CH375FileWriteX( );
										if ( status != ERR_SUCCESS ) break;
									}
									if ( RetLen == CH375vSecPerClus ) {
										mCmdParam.Modify.mFileSize = 0;
										mCmdParam.Modify.mFileDate = 0xFFFF;
										mCmdParam.Modify.mFileTime = 0xFFFF;
										mCmdParam.Modify.mFileAttr = 0x10;
										status = CH375FileModify( );
									}
								}
								CH375LibConfig &= 0xF7;  /* 恢复原文件数据复制方式 */
							}
						}
					}
					RetLen = 0;
					break;
				case CMD_FileDirInfo:  /* 存取当前已打开文件的目录信息 */
					if ( mCmdParam.FileDirInfo.mAccessMode == 0 ) {  /* 读取文件目录信息 */
						status = CH375FileQuery( );  /* 查询文件属性,以便将相关数据调到内存中再修改 */
						if ( status == ERR_SUCCESS ) {
							DirInfoBufI1 = (PUINT8I)(&mCmdParam.FileDirInfo.mDir);
							DirInfoBufX1 = (PUINT8X)(&DISK_BASE_BUF[0]) + CH375vFdtOffset;  /* 在内存中,当前FDT的起始地址 */
							for ( RetLen = sizeof( mCmdParam.FileDirInfo.mDir ); RetLen != 0; RetLen -- ) {
								*DirInfoBufI1 = *DirInfoBufX1;
								DirInfoBufI1 ++;
								DirInfoBufX1 ++;
							}
							RetLen = sizeof( mCmdParam.FileDirInfo );
						}
						mCmdParam.FileDirInfo.mAccessMode = mCmdParam.FileDirInfo.mReserved[0] = mCmdParam.FileDirInfo.mReserved[1] = mCmdParam.FileDirInfo.mReserved[2] = 0;
					}
					else if ( mCmdParam.FileDirInfo.mAccessMode == 0xF0 ) {  /* 写入/更新文件目录信息 */
						DirInfoBufI2 = (PUINT8I)(&mCmdParam.FileDirInfo.mDir);
						DirInfoBufX2 = (PUINT8X)(&DISK_BASE_BUF[0]) + CH375vFdtOffset;  /* 在内存中,当前FDT的起始地址 */
						for ( RetLen = sizeof( mCmdParam.FileDirInfo.mDir ); RetLen != 0; RetLen -- ) {
							*DirInfoBufX2 = *DirInfoBufI2;
							DirInfoBufX2 ++;
							DirInfoBufI2 ++;
						}
						mCmdParam.Modify.mFileAttr = ( (P_FAT_DIR_INFO)( (PUINT8X)(&DISK_BASE_BUF[0]) + CH375vFdtOffset ) ) -> DIR_Attr;  /* 准备假修改文件属性,实际保持原值 */
						mCmdParam.Modify.mFileDate = mCmdParam.Modify.mFileTime = 0xFFFF;  /* 不修改文件日期和时间 */
						mCmdParam.Modify.mFileSize = 0xFFFFFFFF;  /* 不修改文件长度 */
						status = CH375FileModify( );  /* 实际是将内存中刚刚修改过的内容真正刷新到U盘中 */
					}
					else {  /* 其它值无效 */
						status = ERR_DISK_FULL;
					}
					break;
				case CMD_FileReadLast:  /* 从当前文件的尾部读取不足一个扇区长度的零碎数据 */
					mCmdParam.Locate.mSectorOffset = 0xffffffff;
					status = CH375FileLocate( );  /* 以扇区为单位移到文件尾部,如果文件尾部有不足一个扇区的零头数据则被忽略 */
					if ( status == ERR_SUCCESS ) {
						CH375vFileSize += 511;  /* 人为地将文件长度增加一个扇区减1,以便读出最后一个扇区中的零头数据 */
						mCmdParam.Read.mSectorCount = 1;  /* 读取文件尾部的零头数据 */
						mCmdParam.ReadX.mDataBuffer = 0;
						status = CH375FileReadX( );  /* 从文件读取尾部零头数据,如果原尾部没有零头数据,那么什么也读不到,返回时mCmdParam.Read.mSectorCount为实际读出扇区数 */
						CH375vFileSize -= 511;  /* 恢复原文件长度 */
						RetLen = mCmdParam.Read.mSectorCount;
						if ( status == ERR_SUCCESS ) {
							mCmdParam.Locate.mSectorOffset = 0xffffffff;  /* 移到文件的尾部,以扇区为单位,所以会忽略文件尾部的零头数据 */
							status = CH375FileLocate( );  /* 重新回到原文件的尾部 */
						}
					}
					mCmdParam.Read.mSectorCount = RetLen;
					RetLen = sizeof( mCmdParam.Read );
					break;
				case CMD_SetFileSize:  /* 修改系统子程序库的文件长度变量 */
					CH375vFileSize = mCmdParam.SetFileSize.mFileSize;  /* 新的文件长度 */
					break;
				case CMD_GetVer:  /* 获取当前模块的版本号 */
					mCmdParam.GetVer.mFileLibVer = CH375GetVer( );  /* 子程序库的版本 */
					mCmdParam.GetVer.mModuleVer = FILE_MODULE_VER;  /* 模块版本 */
					if ( CH375Version2 ) {  /* CH375A */
						mWriteCmdCH375( CMD_GET_IC_VER );
						mCmdParam.GetVer.mUsbIcVer = CH375_DAT_PORT;  /* USB芯片CH375A版本号 */
					}
					else mCmdParam.GetVer.mUsbIcVer = 0x10;  /* CH375S */
					RetLen = sizeof( mCmdParam.GetVer );
					break;
				case CMD_ResetInit:  /* 复位并重新初始化CH375 */
					mResetCH375( );  /* 复位CH375芯片 */
					status = CH375Init( );  /* 重新初始化CH375 */
					break;
				case CMD_PowerDown:  /* 进入低功耗省电状态 */
					if ( mCmdParam.Other.mBuffer[0] == ~ CMD_PowerDown ) {  /* 命令有效 */
						mQueryCH375( );  /* 清除中断 */
						if ( CH375Version2 ) mWriteCmdCH375( CMD_ENTER_SLEEP );  /* CH375A睡眠 */
						_nop_( );
						PCON = 0x82;  /* 单片机下电 */
						_nop_( );
						_nop_( );
						_nop_( );
						_nop_( );
						_nop_( );
						_nop_( );
						_nop_( );
						_nop_( );
						mWriteCmdCH375( CMD_GET_IC_VER );  /* 唤醒CH375芯片 */
						mDelaymS( 20 );
						mQueryCH375( );  /* 清除中断 */
						if ( mTestCH375( ) || mTestCH375( ) ) {  /* 返回数据应该是测试数据取反,否则CH375出错 */
							mResetCH375( );  /* 复位CH375芯片 */
							status = CH375Init( );  /* 重新初始化CH375 */
						}
					}
					else status = ERR_UNKNOWN_CMD;  /* 不支持的命令 */
					break;
				case CMD_BaudRate:  /* 设置串口通讯波特率 */
					mSetBaudRate = 1;  /* 设置波特率 */
					break;
				case CMD_SetupModule:  /* 设置模块配置 */
					mModeAutoNotice = mCmdParam.Setup.mSetup & 0x01;  /* 空闲时查询U盘连接状态并自动中断通知 */
					mModeUpdateSize = mCmdParam.Setup.mSetup & 0x10;  /* 向文件写入数据后自动更新文件长度 */
					if ( ( mCmdParam.Setup.mSetup & 0xC0 ) == 0x40 ) mModeBigEndian = 0;  /* 数据字节顺序: 小端格式 */
					else if ( ( mCmdParam.Setup.mSetup & 0xC0 ) == 0x80 ) mModeBigEndian = 1;  /* 数据字节顺序: 大端格式 */
					if ( mModeUpdateSize ) CH375LibConfig |= 0x10;  /* 自动更新文件长度 */
					else CH375LibConfig &= 0xEF;  /* 不更新文件长度 */
					break;
				case CMD_DirectWrCmd:  /* 直接传递给CH375,写命令 */
					CH375_CMD_PORT = mCmdParam.Direct.mData;
					break;
				case CMD_DirectRdDat:  /* 直接传递给CH375,读数据 */
					mCmdParam.Direct.mData = CH375_DAT_PORT;
					RetLen = sizeof( mCmdParam.Direct );
					break;
				case CMD_DirectWrDat:  /* 直接传递给CH375,写数据 */
					CH375_DAT_PORT = mCmdParam.Direct.mData;
					break;
				case CMD_DebugAccess:  /* 调试模式存取 */
					switch ( mCmdParam.DebugAccess.mMode & 0x03 ) {  /* 存取模式: 位1-位0: 00存取SFR,01存取内部RAM,10存取外部RAM,11存取程序ROM */
						case 0:  /* SFR */
							switch ( (UINT8)(mCmdParam.DebugAccess.mAddress) ) {  /* 分析SFR地址 */
								case 0x80:
									if ( mCmdParam.DebugAccess.mMode & 0x40 ) P0 = mCmdParam.DebugAccess.mData;  /* 存取模式: 位6为1则写 */
									else mCmdParam.DebugAccess.mData = P0;  /* 存取模式: 位6为0则读 */
									break;
								case 0x87:
									if ( mCmdParam.DebugAccess.mMode & 0x40 ) PCON = mCmdParam.DebugAccess.mData;  /* 存取模式: 位6为1则写 */
									else mCmdParam.DebugAccess.mData = PCON;  /* 存取模式: 位6为0则读 */
									break;
								case 0x88:
									if ( mCmdParam.DebugAccess.mMode & 0x40 ) TCON = mCmdParam.DebugAccess.mData;  /* 存取模式: 位6为1则写 */
									else mCmdParam.DebugAccess.mData = TCON;  /* 存取模式: 位6为0则读 */
									break;
								case 0x89:
									if ( mCmdParam.DebugAccess.mMode & 0x40 ) TMOD = mCmdParam.DebugAccess.mData;  /* 存取模式: 位6为1则写 */
									else mCmdParam.DebugAccess.mData = TMOD;  /* 存取模式: 位6为0则读 */
									break;
								case 0x8A:
									if ( mCmdParam.DebugAccess.mMode & 0x40 ) TL0 = mCmdParam.DebugAccess.mData;  /* 存取模式: 位6为1则写 */
									else mCmdParam.DebugAccess.mData = TL0;  /* 存取模式: 位6为0则读 */
									break;
								case 0x8B:
									if ( mCmdParam.DebugAccess.mMode & 0x40 ) TH0 = mCmdParam.DebugAccess.mData;  /* 存取模式: 位6为1则写 */
									else mCmdParam.DebugAccess.mData = TH0;  /* 存取模式: 位6为0则读 */
									break;
								case 0x8C:
									if ( mCmdParam.DebugAccess.mMode & 0x40 ) TL1 = mCmdParam.DebugAccess.mData;  /* 存取模式: 位6为1则写 */
									else mCmdParam.DebugAccess.mData = TL1;  /* 存取模式: 位6为0则读 */
									break;
								case 0x8D:
									if ( mCmdParam.DebugAccess.mMode & 0x40 ) TH1 = mCmdParam.DebugAccess.mData;  /* 存取模式: 位6为1则写 */
									else mCmdParam.DebugAccess.mData = TH1;  /* 存取模式: 位6为0则读 */
									break;
								case 0x90:
									if ( mCmdParam.DebugAccess.mMode & 0x40 ) P1 = mCmdParam.DebugAccess.mData;  /* 存取模式: 位6为1则写 */
									else mCmdParam.DebugAccess.mData = P1;  /* 存取模式: 位6为0则读 */
									break;
								case 0x98:
									if ( mCmdParam.DebugAccess.mMode & 0x40 ) SCON = mCmdParam.DebugAccess.mData;  /* 存取模式: 位6为1则写 */
									else mCmdParam.DebugAccess.mData = SCON;  /* 存取模式: 位6为0则读 */
									break;
								case 0x99:
									if ( mCmdParam.DebugAccess.mMode & 0x40 ) SBUF = mCmdParam.DebugAccess.mData;  /* 存取模式: 位6为1则写 */
									else mCmdParam.DebugAccess.mData = SBUF;  /* 存取模式: 位6为0则读 */
									break;
								case 0xA0:
									if ( mCmdParam.DebugAccess.mMode & 0x40 ) P2 = mCmdParam.DebugAccess.mData;  /* 存取模式: 位6为1则写 */
									else mCmdParam.DebugAccess.mData = P2;  /* 存取模式: 位6为0则读 */
									break;
								case 0xA8:
									if ( mCmdParam.DebugAccess.mMode & 0x40 ) IE = mCmdParam.DebugAccess.mData;  /* 存取模式: 位6为1则写 */
									else mCmdParam.DebugAccess.mData = IE;  /* 存取模式: 位6为0则读 */
									break;
								case 0xB0:
									if ( mCmdParam.DebugAccess.mMode & 0x40 ) P3 = mCmdParam.DebugAccess.mData;  /* 存取模式: 位6为1则写 */
									else mCmdParam.DebugAccess.mData = P3;  /* 存取模式: 位6为0则读 */
									break;
								case 0xB8:
									if ( mCmdParam.DebugAccess.mMode & 0x40 ) IP = mCmdParam.DebugAccess.mData;  /* 存取模式: 位6为1则写 */
									else mCmdParam.DebugAccess.mData = IP;  /* 存取模式: 位6为0则读 */
									break;
								case 0xC8:
									if ( mCmdParam.DebugAccess.mMode & 0x40 ) T2CON = mCmdParam.DebugAccess.mData;  /* 存取模式: 位6为1则写 */
									else mCmdParam.DebugAccess.mData = T2CON;  /* 存取模式: 位6为0则读 */
									break;
								case 0xCA:
									if ( mCmdParam.DebugAcc

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -