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

📄 ch375hmp.asm

📁 南京沁恒电子的U盘文件读写模块的实例程序
💻 ASM
📖 第 1 页 / 共 2 页
字号:
; /* 2004.06.05
; ****************************************
; **  Copyright  (C)  W.ch  1999-2007   **
; **  Web:  http://www.winchiphead.com  **
; ****************************************
; **  USB Host File Module      @CH375  **
; ****************************************
; */
; /* U盘文件读写模块, 连接方式: 并口+查询 */
; /* MCS-51单片机ASM语言示例程序, 仅适用于V3.0A及以上版本的模块 */
; /* 因为使用U盘文件读写模块而不是使用U盘文件级子程序库,所以占用较少的单片机资源,可以使用89C51单片机测试 */
; 
;$include	(REG51.INC)
$include	(..\CH375HM.INC)

;   电路连接方式
;   单片机    模块
;    P0    =  D0-D7
;    RD    =  RD#
;    WR    =  WR#
;    ?     =  CS#   如果没有外部RAM,那么CS#=P26,如果有超过16KB的外部RAM,那么CS#=P27 & ! P26 & ...,所以CS#的片选地址为BXXXH
;    P20   =  A0
;    INT0  =  INT#  虽然连接到INT0,但是本程序只是查询模块的INT#的状态,所以可以用P1口等普通I/O引脚代替INT0

CH375HM_INDEX	XDATA	0BCF0H			;CH375模块的索引端口的I/O地址
CH375HM_DATA	XDATA	0BDF1H			;CH375模块的数据端口的I/O地址

CH375HM_INT		BIT		INT0			;假定CH375模块的INT#引脚连接到单片机的INT0引脚

LED_OUT			BIT		P1.4			;P1.4 低电平驱动LED显示,用于监控演示程序的进度

; 假定文件数据缓冲区: ExtRAM: 0000H-7FFFH
DATA_BUF		XDATA	00000H			;外部RAM的文件数据缓冲区,从该单元开始的缓冲区长度不小于一次读写的数据长度,最少为512字节

; 命令参数结构, 长度为20到60字节
mCmdParam		DATA	20H				;默认情况下该结构将占用64字节的RAM,可以修改MAX_PATH_LEN常量,当修改为32时,只占用32字节的RAM
SECTOR_COUNT	DATA	1DH				;文件占用扇区数
NEW_SIZE_HIGH	DATA	1EH				;文件长度的高字节
NEW_SIZE_LOW	DATA	1FH				;文件长度的低字节

				ORG		0000H
				LJMP	MAIN
;
; 程序数据起始地址
				ORG		0100H
STR_FILE_NAME1:	DB		'\C51\CH375HFT.C',00H	;文件名,该文件在C51子目录下
STR_FILE_DATA:	DB		'Note: ',0DH,0AH
				DB      '原本是打算将/C51/CH375HFT.C文件中的小写字母转成大写后写入新的文件,但是找不到这个文件',0DH,0AH,00H
STR_FILE_NAME2:	DB		'\双击我吧.TXT',00H		;新文件名,在根目录下

; 从程序空间复制字符串到内部RAM缓冲区,源字符串必须以00H作为结束标志,长度不能超过255
; 入口:   DPTR 指向源字符串的起始地址, R0 目标缓冲区的起始地址
; 出口:   R7 返回字符串的长度(含字符串结束符00H)
; 使用:   DPTR, R0, R7
CopyString:		MOV		R7,#00H
CopyStringChar:	MOV		A,R7
				INC		R7
				MOVC	A,@A+DPTR
				MOV		@R0,A
				INC		R0
				JNZ		CopyStringChar		;不是字符串结束符00H,继续复制
				RET
;
; 延时100毫秒,不精确
; 使用:   R6, R7
mDelay100mS:	MOV  	R7,#0C8H
mDelay100mS_1:	MOV  	R6,#0C8H
mDelay100mS_2:	NOP
				NOP
				NOP
				DJNZ 	R6,mDelay100mS_2
				DJNZ 	R7,mDelay100mS_1
				RET  	

; 执行命令
; 输入命令码和输入参数长度,返回操作状态码,输入参数和返回参数都在CMD_PARAM结构中
; 入口:   R7 命令码, R5 参数长度, 对于读写文件数据命令, DPTR 为外部RAM缓冲区起始地址
; 出口:   R7 状态码, 对于读写文件数据命令, DPTR 为数据终止地址
; 使用:   R0, R4, R5, R6, R7
ExecCommand:	MOV     R6,DPH				;对于读写文件数据命令,保存外部RAM缓冲区起始地址
				MOV     R4,DPL
				MOV  	DPTR,#CH375HM_INDEX
				MOV     A,#PARA_COMMAND_ADDR
				MOVX 	@DPTR,A				;索引地址为PARA_COMMAND_ADDR
				MOV  	DPTR,#CH375HM_DATA
				MOV  	A,R7
				MOVX 	@DPTR,A				;向索引地址PARA_COMMAND_ADDR写入命令码
				MOV  	A,R5
				MOV     R7,A				;后续参数的长度
				JZ      ExecCommand_W0		;没有参数
				MOV  	DPTR,#CH375HM_INDEX
				MOV     A,#PARA_BUFFER_ADDR
				MOVX 	@DPTR,A				;指向缓冲区
				MOV     R0,#mCmdParam		;指向输入参数的起始地址
				MOV  	DPTR,#CH375HM_DATA
ExecCommand_WP:	MOV		A,@R0
				MOVX	@DPTR,A				;从索引地址PARA_BUFFER_ADDR开始,写入参数
				INC     R0
				DJNZ    R7,ExecCommand_WP
ExecCommand_W0:	MOV  	DPTR,#CH375HM_INDEX
				MOV     A,#PARA_CMD_LEN_ADDR
				MOVX    @DPTR,A				;索引地址PARA_CMD_LEN_ADDR
				MOV  	DPTR,#CH375HM_DATA
				MOV     A,R5
				ORL     A,#PARA_CMD_BIT_ACT	;最高位通知模块,说明命令包已经写入,请求开始执行命令
				MOVX    @DPTR,A				;向索引地址PARA_CMD_LEN_ADDR写入后续参数的长度
ExecCommand_Wait:

$IF 1
				JB		CH375HM_INT,$		;等待模块完成操作产生低电平中断,并返回操作状态
$ELSE
				MOV  	DPTR,#CH375HM_INDEX	;如果不需要扇区方式读写,那么可以查询模块的命令码单元代替查询模块INT#引脚
				MOV     A,#PARA_COMMAND_ADDR
				MOVX    @DPTR,A
				MOV  	DPTR,#CH375HM_DATA
				MOVX    A,@DPTR				;模块操作完成时该值会清0,仅适用于非扇区方式读写
				JNZ     ExecCommand_Wait	;等待中断
$ENDIF

;最佳检测方式是对模块的INT#信号进行下降沿边沿检测
				MOV  	DPTR,#CH375HM_INDEX
				MOV  	A,#PARA_STATUS_ADDR
				MOVX 	@DPTR,A				;写入索引地址PARA_STATUS_ADDR
				MOV  	DPTR,#CH375HM_DATA
				MOVX 	A,@DPTR				;从索引地址PARA_STATUS_ADDR读取中断状态
				MOV		R7,A				;操作状态码
				MOV  	DPTR,#CH375HM_INDEX
				MOV     A,#PARA_CMD_LEN_ADDR
				MOVX    @DPTR,A				;启动操作的单元地址
				MOV  	DPTR,#CH375HM_DATA
				MOV     A,#PARA_CMD_BIT_INACT
				MOVX    @DPTR,A				;中断应答,取消来自模块的中断请求
;因为模块在收到中断应答后3uS之内才撤消中断请求,所以,如果是查询INT#信号的低电平,那么在发出中断应答后3uS之内不应该再查询INT#信号的状态
;但是由于51单片机较慢,下面的处理时间已经超过3uS,所以不必另加延时等待模块撤消中断请求
				CJNE    R7,#ERR_SUCCESS,ExecCommand_J0	;不是操作成功的状态码
				MOV  	DPTR,#CH375HM_INDEX	;操作成功
				MOV		A,#PARA_STS_LEN_ADDR
				MOVX 	@DPTR,A
				MOV  	DPTR,#CH375HM_DATA
				MOVX 	A,@DPTR				;从索引地址PARA_STS_LEN_ADDR读取返回结果数据的长度
				MOV  	R7,A
				JZ      ExecCommand_R0		;没有结果数据
				MOV  	DPTR,#CH375HM_INDEX
				MOV     A,#PARA_BUFFER_ADDR
				MOVX 	@DPTR,A				;指向缓冲区
				MOV     R0,#mCmdParam		;指向输出参数的起始地址
				MOV  	DPTR,#CH375HM_DATA	;从索引地址PARA_BUFFER_ADDR开始,读取结果
ExecCommand_RP:	MOVX	A,@DPTR
				MOV		@R0,A
				INC		R0
				DJNZ 	R7,ExecCommand_RP
ExecCommand_R0:	LJMP	ExecCommand_Ret
ExecCommand_J0:	CJNE    R7,#USB_INT_DISK_READ,ExecCommand_J1
				MOV  	DPTR,#CH375HM_INDEX	;正在从U盘读数据块,请求数据读出
				MOV		A,#PARA_BUFFER_ADDR
				MOVX 	@DPTR,A				;指向缓冲区
				MOV  	R7,#040H			;一次读取64个字节
RD_SEC_BYTE:	MOV     DPTR,#CH375HM_DATA
				MOVX	A,@DPTR				;依次输入64字节的数据
				MOV     DPH,R6
				MOV     DPL,R4				;缓冲区地址
				MOVX    @DPTR,A				;读取的数据保存到外部缓冲区
				INC     DPTR
				MOV     R6,DPH
				MOV     R4,DPL
				DJNZ    R7,RD_SEC_BYTE		;从索引地址0到63依次读出64字节的数据
				MOV  	DPTR,#CH375HM_INDEX
				MOV     A,#PARA_CMD_LEN_ADDR
				MOVX    @DPTR,A				;启动操作的单元地址
				MOV  	DPTR,#CH375HM_DATA
				MOV     A,#PARA_CMD_BIT_ACT
				MOVX    @DPTR,A				;通知模块继续,说明64字节数据已经读取完成
				LJMP    ExecCommand_Wait
ExecCommand_J1:	CJNE    R7,#USB_INT_DISK_WRITE,ExecCommand_J2
				MOV  	DPTR,#CH375HM_INDEX	;正在向U盘写数据块,请求数据写入
				MOV		A,#PARA_BUFFER_ADDR
				MOVX 	@DPTR,A				;指向缓冲区
				MOV  	R7,#040H			;一次写入64个字节
WR_SEC_BYTE:	MOV     DPH,R6
				MOV     DPL,R4				;缓冲区地址
				MOVX    A,@DPTR				;写入的数据来自外部缓冲区
				INC     DPTR
				MOV     R6,DPH
				MOV     R4,DPL
				MOV     DPTR,#CH375HM_DATA
				MOVX    @DPTR,A				;依次输出64字节的数据
				DJNZ    R7,WR_SEC_BYTE		;向索引地址0到63依次写入64字节的数据
				MOV  	DPTR,#CH375HM_INDEX
				MOV     A,#PARA_CMD_LEN_ADDR
				MOVX    @DPTR,A				;启动操作的单元地址
				MOV  	DPTR,#CH375HM_DATA
				MOV     A,#PARA_CMD_BIT_ACT
				MOVX    @DPTR,A				;通知模块继续,说明64字节数据已经写入完成
				LJMP	ExecCommand_Wait
ExecCommand_J2:	CJNE    R7,#USB_INT_DISK_RETRY,ExecCommand_J3
				MOV  	DPTR,#CH375HM_INDEX	;读写数据块失败重试,应该向回修改缓冲区指针
				MOV		A,#PARA_BUFFER_ADDR
				MOVX 	@DPTR,A				;指向缓冲区
				MOV		DPTR,#CH375HM_DATA
				MOVX	A,@DPTR				;大端模式下为回改指针字节数的高8位,如果是小端模式那么接收到的是回改指针字节数的低8位
				MOV		R7,A
				MOVX	A,@DPTR				;大端模式下为回改指针字节数的低8位,如果是小端模式那么接收到的是回改指针字节数的高8位
				CLR		C
				XCH		A,R4
				SUBB	A,R4
				MOV		R4,A				;这是大端模式下的回改指针
				MOV		A,R6
				SUBB	A,R7
				MOV		R6,A
				MOV  	DPTR,#CH375HM_INDEX
				MOV     A,#PARA_CMD_LEN_ADDR
				MOVX    @DPTR,A				;启动操作的单元地址
				MOV  	DPTR,#CH375HM_DATA
				MOV     A,#PARA_CMD_BIT_ACT
				MOVX    @DPTR,A				;通知模块继续,说明重试状态码已经处理完成
				LJMP	ExecCommand_Wait
ExecCommand_J3:								;R7为操作完成状态,操作出现错误
				CJNE    R7,#ERR_DISK_DISCON,ExecCommand_J4	;检查U盘断开事件
				SJMP    ExecCommandEv

⌨️ 快捷键说明

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