📄 ch375hmp.asm
字号:
RET
mStopIfError_LED: ;LED闪烁
CLR A
MOV C,LED_OUT
MOV ACC.0,C
XRL A,#01H
MOV C,ACC.0
MOV LED_OUT,C
LCALL mDelay100mS
SJMP mStopIfError_LED
;
; 主程序
MAIN: CLR A
MOV PSW,A
MOV IE,A
MOV SP,#60H
MOV A,#0FFH
MOV P0,A
MOV P1,A
MOV P2,A
MOV P3,A
CLR LED_OUT ;开机后LED亮一下以示工作
LCALL mDelay100mS ;延时100毫秒,CH375模块上电后需要100毫秒左右的复位时间
LCALL mDelay100mS
SETB LED_OUT
;其它电路初始化
;初始化完成
NOP
MAIN_LOOP: ;主循环
;可以在打算读写U盘时再查询,没有必要一直连续不停地查询,可以让单片机做其它事,没事可做就延时等待一会再查询
MOV R5,#00H ;没有命令参数
MOV R7,#CMD_QueryStatus ;使用查询方式看U盘是否连接
LCALL ExecCommand ;查询当前模块的状态
LCALL mStopIfError ;错误则停机
MOV A,mCmdParam+1 ;Status.mDiskStatus
XRL A,#DISK_CONNECT
JZ MAIN_CONNECT ;U盘已经连接
LCALL mDelay100mS ;可以让单片机做其它事,没事可做就延时等待一会再查询
LCALL mDelay100mS
SJMP MAIN_LOOP
MAIN_CONNECT: LCALL mDelay100mS ;U盘已经连接,延时,可选操作,有的USB存储器需要几十毫秒的延时
LCALL mDelay100mS
CLR LED_OUT ;LED亮说明U盘连接
; 检查U盘是否准备好,大多数U盘不需要这一步,但是某些U盘必须要执行这一步才能工作
WAIT_READY: LCALL mDelay100mS
MOV R5,#00H
MOV R7,#CMD_DiskReady
LCALL ExecCommand ;查询磁盘是否准备好
MOV A,R7
JNZ WAIT_READY ;U盘尚未准备好
;读取原文件
MOV DPTR,#STR_FILE_NAME1
MOV R0,#mCmdParam ;Open.mPathName
LCALL CopyString ;复制文件名
MOV A,R7
MOV R5,A ;参数长度为文件名长度
MOV R7,#CMD_FileOpen ;打开文件
LCALL ExecCommand ;执行打开文件操作
CJNE R7,#ERR_MISS_DIR,MAIN_OPEN_J1
SJMP MAIN_OPEN_MISS ;ERR_MISS_DIR说明没有找到C51子目录
MAIN_OPEN_J1: CJNE R7,#ERR_MISS_FILE,MAIN_OPEN_J2
MAIN_OPEN_MISS: ;ERR_MISS_FILE说明没有找到文件
;没有原文件则自行产生数据
MOV DPTR,#DATA_BUF ;因为没有找到源文件,所以自行产生数据写入新文件
MOV R5,#00H
MAIN_COPY_STR: PUSH DPH
PUSH DPL
MOV DPTR,#STR_FILE_DATA
MOV A,R5
INC R5
MOVC A,@A+DPTR ;从程序空间复制字符串作为新文件的内容
POP DPL
POP DPH
MOVX @DPTR,A
INC DPTR
JNZ MAIN_COPY_STR ;未到字符串结束符00H
MAIN_FILL_STR: MOV A,#24H ;'$'
MOVX @DPTR,A
INC DPTR
MOV A,DPH
CJNE A,#HIGH (DATA_BUF) + 2,MAIN_FILL_STR ;填充满512字节(一个扇区)
MOV NEW_SIZE_HIGH,#02H
MOV NEW_SIZE_LOW,#00H ;新文件的长度,512字节
MOV SECTOR_COUNT,#01H ;新文件的长度只有一个扇区,计算文件的扇区数,因为读写是以扇区为单位的
LJMP MAIN_CREATE_NEW ;创建新文件
MAIN_OPEN_J2: LCALL mStopIfError ;源文件成功打开
;查询当前文件的信息并计算长度
MOV R5,#00H
MOV R7,#CMD_FileQuery ;查询当前文件的信息,没有输入参数
LCALL ExecCommand
LCALL mStopIfError
MOV NEW_SIZE_HIGH,#10H
MOV NEW_SIZE_LOW,#00H ;新文件的长度不超过4096,实际上模块本身不限制长度
MOV R0,#mCmdParam
MOV A,@R0 ;Modify.mFileSize.31-24,高字节在前
JNZ MAIN_QUERY_J1 ;文件太大
INC R0
MOV A,@R0 ;Modify.mFileSize.23-16
JNZ MAIN_QUERY_J1 ;文件太大
INC R0
MOV A,@R0 ;Modify.mFileSize.15-8
CLR C
SUBB A,#10H ;本示例程序将文件长度限制在4096
JNC MAIN_QUERY_J1 ;文件长度超过4096
MOV A,@R0 ;Modify.mFileSize.15-8
MOV NEW_SIZE_HIGH,A
INC R0
MOV A,@R0 ;Modify.mFileSize.7-0
MOV NEW_SIZE_LOW,A ;新文件的长度
MAIN_QUERY_J1: MOV A,NEW_SIZE_LOW
ADD A,#0FFH
MOV A,NEW_SIZE_HIGH
ADDC A,#01H
CLR C
RRC A ;每个扇区是512字节,所以高8位除以2
MOV SECTOR_COUNT,A ;计算文件的扇区数,因为读写是以扇区为单位的
JNZ MAIN_QUERY_J3
INC SECTOR_COUNT ;至少一个扇区
MAIN_QUERY_J3:
;读取原文件
MOV A,SECTOR_COUNT
MOV mCmdParam+0,A ;Read.mSectorCount
MOV R5,#01H ;只有一个输入参数
MOV R7,#CMD_FileRead ;从文件读取数据
MOV DPTR,#DATA_BUF ;对于读写文件数据的操作,指定外部RAM缓冲区,存放数据的缓冲区的起始地址
LCALL ExecCommand ;从文件读取数据,如果文件比较大,一次读不完,可以再用命令CMD_FileRead继续读取,文件指针自动向后移动
LCALL mStopIfError
MOV A,#00H
MOV mCmdParam+0,A ;Close.mUpdateLen
MOV R5,#01H ;只有一个输入参数
MOV R7,#CMD_FileClose ;关闭文件
LCALL ExecCommand ;关闭文件
LCALL mStopIfError
;将源文件中的小写字符转换为大写,准备写入新文件
MOV DPTR,#DATA_BUF
MOV R7,NEW_SIZE_HIGH
MOV R6,NEW_SIZE_LOW
MAIN_CHAR_CASE: CJNE R6,#00H,MAIN_CHAR_CNT1
CJNE R7,#00H,MAIN_CHAR_CNT2
SJMP MAIN_CHAR_END
MAIN_CHAR_CNT2: DEC R7
MAIN_CHAR_CNT1: DEC R6 ;计数
MOVX A,@DPTR
MOV R5,A
CLR C
SUBB A,#61H ;'a'
JC MAIN_CHAR_SKIP ;不是小写字母
MOV A,R5
CLR C
SUBB A,#7BH ;'z'+1
JNC MAIN_CHAR_SKIP ;不是小写字母
MOV A,R5
ANL A,#0DFH ;小写转大写字母
MOVX @DPTR,A
MAIN_CHAR_SKIP: INC DPTR
SJMP MAIN_CHAR_CASE
MAIN_CHAR_END: NOP ;已经将小写字母转大写
;产生新文件
MAIN_CREATE_NEW:
MOV DPTR,#STR_FILE_NAME2
MOV R0,#mCmdParam ;Create.mPathName
LCALL CopyString ;复制文件名
MOV A,R7
MOV R5,A ;参数长度为文件名长度
MOV R7,#CMD_FileCreate
LCALL ExecCommand ;新建文件并打开,如果文件已经存在则先删除后再新建
LCALL mStopIfError
MOV A,SECTOR_COUNT
MOV mCmdParam+0,A ;Write.mSectorCount
MOV R5,#01H ;只有一个输入参数
MOV R7,#CMD_FileWrite ;向文件写入数据
MOV DPTR,#DATA_BUF ;对于读写文件数据的操作,指定外部RAM缓冲区,存放数据的缓冲区的起始地址
LCALL ExecCommand ;向文件写入数据,如果文件比较大,一次写不完,可以再用命令CMD_FileWrite继续写入,文件指针自动向后移动
LCALL mStopIfError
MOV A,#01H ;自动计算文件长度,长度总是512的倍数
MOV mCmdParam+0,A ;Close.mUpdateLen
MOV R5,#01H ;只有一个输入参数
MOV R7,#CMD_FileClose ;关闭文件
LCALL ExecCommand ;关闭文件
LCALL mStopIfError
;等待U盘断开,仅作演示,实际应用中不必考虑U盘是否断开
MAIN_TAKE_OUT: MOV R5,#00H ;没有命令参数
MOV R7,#CMD_QueryStatus ;使用查询方式看U盘是否断开
LCALL ExecCommand ;查询当前模块的状态
LCALL mStopIfError ;错误则停机
MOV A,mCmdParam+1 ;Status.mDiskStatus
XRL A,#DISK_DISCONNECT
JZ MAIN_DISCONNECT ;U盘已经断开
LCALL mDelay100mS ;延时等待一会再查询
LCALL mDelay100mS
SJMP MAIN_TAKE_OUT
MAIN_DISCONNECT: SETB LED_OUT ;LED灭
LJMP MAIN_LOOP ;等待下一个U盘连接
; END main
;
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -