📄 ch375hft.asm
字号:
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 + -