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

📄 ch375hft.asm

📁 MCS-51单片机ASM语言的U盘文件读写示例程序, 适用于89C52或者更大程序空间的单片机
💻 ASM
📖 第 1 页 / 共 2 页
字号:
					INC     DPTR
					JZ      COPY_INFO_END
					INC     R7
					CJNE    R7,#0FFH,COPY_INFO_CHAR	; 文件字符计数
COPY_INFO_END:		MOV  	NewSize,#00H
					MOV  	NewSize+01H,R7		; 新文件的长度
					MOV  	SecCount,#01H		; 新文件只占用1个扇区, (NewSize+511)/512
					LJMP 	CREATE_NEW_FILE
; 找到原文件
FOUND_SOURCE_FILE:	;LCALL	CH375FileQuery		; 查询其信息,包括长度,日期时间,属性等
					;LCALL	_mStopIfError
					MOV     A,CH375vFileSize	; 原文件的长度
					JNZ     SOURCE_FILE_LONG	; 由于演示板用的62256只有32K字节,其中CH375子程序用512字节,所以只读取不超过63个扇区
					MOV     A,CH375vFileSize+01H
					JNZ     SOURCE_FILE_LONG	; 由于RAM缓冲区有限,所以限制一次读写操作的长度不超过32256字节
					MOV     A,CH375vFileSize+02H
					CLR     C
					SUBB    A,#HIGH (FILE_DATA_BUF_LEN)
					JC      SOURCE_FILE_SHORT	; 小于RAM缓冲区的长度
					JNZ     SOURCE_FILE_LONG	; 大于RAM缓冲区的长度
					MOV     A,CH375vFileSize+03H
					CLR     C
					SUBB    A,#LOW (FILE_DATA_BUF_LEN)
					JC      SOURCE_FILE_SHORT	; 一次读写操作的长度未操作RAM缓冲区的长度
SOURCE_FILE_LONG:	MOV  	SecCount,#(FILE_DATA_BUF_LEN/512)	; 限制为RAM文件读写缓冲区的长度
					MOV  	NewSize,#HIGH (FILE_DATA_BUF_LEN)
					MOV  	NewSize+01H,#LOW (FILE_DATA_BUF_LEN)
					SJMP 	READ_SOURCE_FILE
SOURCE_FILE_SHORT:	MOV  	A,CH375vFileSize+03H	; 如果原文件较小,那么使用原长度
					MOV     NewSize+01H,A		; NewSize=CH375vFileSize
					ADD  	A,#0FFH
					MOV  	A,CH375vFileSize+02H
					MOV     NewSize,A			; SecCount = (NewSize+511)/512
					ADDC 	A,#01H
					MOV  	R6,A
					CLR  	A
					ADDC 	A,CH375vFileSize+01H
					RRC     A
					MOV     A,R6
					RRC     A
					MOV  	SecCount,A			; 计算新文件的长度对应的扇区数,因为读写是以扇区为单位的
; 从原文件中读取数据到FILE_DATA_BUF中,以扇区为单位进行读写,所以速度较快,适用于数据量较大的情况
READ_SOURCE_FILE:	MOV  	R0,#LOW (mCmdParam)	; 读操作要指定读出数据的长度,以扇区为单位,mCmdParam.Read.mSectorCount
					MOV  	@R0,SecCount		; 指定读取扇区数, 本例子中是读取全部数据,如果超过63个扇区则只读取63个扇区
					PUSH	CH375vFileSize+03H
					PUSH	CH375vFileSize+02H
					PUSH	CH375vFileSize+01H
					PUSH	CH375vFileSize
					MOV		A,CH375vFileSize+03H	;默认情况下,以扇区方式读取数据时,无法读出文件尾部不足1个扇区的部分,所以必须临时加大文件长度以读取尾部零头
					ADD		A,#0FFH				;CH375vFileSize+511
					MOV		CH375vFileSize+03H,A
					MOV		A,CH375vFileSize+02H
					ADDC	A,#01H
					MOV		CH375vFileSize+02H,A
					MOV		A,CH375vFileSize+01H
					ADDC	A,#00H
					MOV		CH375vFileSize+01H,A
					MOV		A,CH375vFileSize
					ADDC	A,#00H
					MOV		CH375vFileSize,A
					LCALL	CH375FileRead		; 从文件读取数据
					LCALL	_mStopIfError		; 如果文件数据的复制方式为"外部子程序",那么由_xWriteToExtBuf子程序读出数据,否则自动读到FILE_DATA_BUF中
					POP		CH375vFileSize		; 恢复原文件长度
					POP		CH375vFileSize+01H
					POP		CH375vFileSize+02H
					POP		CH375vFileSize+03H
					MOV  	R0,#LOW (mCmdParam)	; mCmdParam.Close.mUpdateLen
					MOV     @R0,#00H
					LCALL	CH375FileClose		; 关闭文件, 用完后需要关闭文件
					LCALL	_mStopIfError
; 将FILE_DATA_BUF中的原文件字符转换为大写
					MOV     DPTR,#FILE_DATA_BUF
					MOV     R6,#00H
					MOV     R7,#00H				; 计数
CONVERT_CHAR_NEXT:	CLR     C
					MOV  	A,R7
					SUBB 	A,NewSize+01H
					MOV  	A,R6
					SUBB 	A,NewSize
					JNC  	CONVERT_CHAR_END	; 原文件字符已经处理完毕
					MOVX 	A,@DPTR
					MOV  	R5,A
					CLR  	C
					SUBB 	A,#061H
					JC   	CONVERT_CHAR_SKIP	; 不是小写字符
					MOV  	A,R5
					SETB 	C
					SUBB 	A,#07AH
					JNC  	CONVERT_CHAR_SKIP	; 不是小写字符
					MOV  	A,R5
					ANL  	A,#0DFH
					MOVX 	@DPTR,A				; 将原小写字符转换为大写后写回FILE_DATA_BUF中
CONVERT_CHAR_SKIP:	INC     DPTR				; 指向缓冲区中的下一个字符
					INC  	R7
					CJNE 	R7,#00H,CONVERT_CHAR_NEXT	; 计数
					INC  	R6
					SJMP 	CONVERT_CHAR_NEXT
CONVERT_CHAR_END:

; 在根目录下创建新文件NEWFILE.TXT,以扇区为单位进行读写,所以速度较快,适用于数据量较大的情况
CREATE_NEW_FILE:	CLR     LED_WR				; 写操作
					MOV  	R0,#LOW (mCmdParam)	; 命令参数,mCmdParam.Create.mPathName
					MOV  	DPTR,#NEW_NAME		; 指向新文件名
					LCALL	_mCopyStringToIRAM	; 复制文件名作为调用子程序的参数
					LCALL	CH375FileCreate		; 新建文件并打开,如果文件已经存在则先删除后再新建
					LCALL	_mStopIfError
					MOV  	R0,#LOW (mCmdParam)	; 写操作要指定写入数据的长度,以扇区为单位,mCmdParam.Write.mSectorCount
					MOV  	@R0,SecCount		; 写入所有扇区的数据
					LCALL	CH375FileWrite		; 向文件写入数据
					LCALL	_mStopIfError		; 如果文件数据的复制方式为"外部子程序",那么由_xReadFromExtBuf子程序写入数据,否则自动将FILE_DATA_BUF中的数据写入
					MOV     A,#0FFH
					MOV  	R0,#LOW (mCmdParam+08H)	; 输入参数mCmdParam.Modify.mFileAttr: 新的文件属性,为0FFH则不修改
					MOV  	@R0,A
					MOV  	R0,#LOW (mCmdParam+06H)	; 输入参数mCmdParam.Modify.mFileTime: 新的文件时间,为0FFFFH则不修改,使用新建文件产生的默认时间
					MOV  	@R0,A
					INC  	R0
					MOV  	@R0,A
					MOV  	R0,#LOW (mCmdParam+04H)	; 输入参数mCmdParam.Modify.mFileDate: 新的文件日期: 2004.05.18 */
					MOV  	@R0,#030H			; 日期产生方法是 Date = ((Year-1980)<<9) + (Month<<5) + Day
					INC  	R0
					MOV  	@R0,#0B2H
					MOV  	R0,#LOW (mCmdParam)	; 输入参数mCmdParam.Modify.mFileSize: 如果原文件较小,那么新的文件长度与原文件一样长,否则被RAM所限
					MOV     @R0,#00H
					INC     R0
					MOV     @R0,#00H			; 如果文件长度大于64KB,那么该单元应该写入文件长度的高23-16位
					INC     R0
					MOV  	@R0,NewSize
					INC     R0
					MOV  	@R0,NewSize+01H		; 指定新的文件长度
					LCALL	CH375FileModify		; 修改当前文件的信息,修改日期和长度
					LCALL	_mStopIfError
					MOV  	R0,#LOW (mCmdParam)	; 命令参数, mCmdParam.Close.mUpdateLen
					MOV  	@R0,#00H			; 不要自动计算文件长度,如果自动计算,那么该长度总是512的倍数
					LCALL	CH375FileClose		; 关闭文件
					LCALL	_mStopIfError

; 在根目录下创建第二个新文件MY_FILE2.TXT,以字节为单位进行读写,所以速度较慢,适用于RAM较少、数据量较小的情况
					MOV  	R0,#LOW (mCmdParam)	; 命令参数,mCmdParam.Create.mPathName
					MOV  	DPTR,#NEW_NAME_2	; 指向新文件名
					LCALL	_mCopyStringToIRAM	; 复制文件名作为调用子程序的参数
					LCALL	CH375FileCreate		; 新建文件并打开,如果文件已经存在则先删除后再新建
					LCALL	_mStopIfError
; 以字节为单位写入几十个字节的数据
					MOV  	R0,#LOW (mCmdParam+01H)	; 命令参数,mCmdParam.ByteWrite.mByteBuffer
					MOV  	DPTR,#DATA_FOR_FILE2	; 指向准备写入新文件中的数据
					LCALL	_mCopyStringToIRAM	; 将准备写入新文件中的数据复制到参数结构中
					MOV  	R0,#LOW (mCmdParam)	; 写操作要指定写入数据的长度,以扇区为单位,mCmdParam.ByteWrite.mByteCount
					MOV  	@R0,#18H			; 本次写入的字节数24,不能大于MAX_BYTE_IO
					LCALL	CH375ByteWrite		; 向文件写入数据,如果还有数据需要继续写入,那么可以再调用CH375ByteWrite,接着刚才的写入
					LCALL	_mStopIfError		; 以字节为单位写文件不需要使用FILE_DATA_BUF缓冲区,所以与复制方式无关
					MOV  	R0,#LOW (mCmdParam)	; 命令参数, mCmdParam.Close.mUpdateLen
					MOV  	@R0,#01H			; 以字节为单位写入文件后,应该自动计算文件长度
					LCALL	CH375FileClose		; 关闭文件
					LCALL	_mStopIfError

					SETB    LED_WR
; 演示处理完毕, 等待U盘拔出
					SETB 	LED_RUN
WAIT_DISK_OUT:		MOV  	A,CH375DiskStatus	; 查询CH375中断并更新中断状态,等待U盘拔出
					XRL  	A,#01H
					JZ   	DISK_OUT_NOW
					LCALL	xQueryInterrupt
					SJMP 	WAIT_DISK_OUT
DISK_OUT_NOW:		SETB 	LED_OUT				; LED灭
					LCALL	mDelay100mS
					LCALL	mDelay100mS
					LJMP 	WAIT_DISK_IN		; 主循环
;
END

⌨️ 快捷键说明

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