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

📄 maze.asm

📁 在定时器中断中做LED的PWM输出 AT89C2051实现A/D转换的C51程序 单片机开发系统 指令系统 程序设计 定时与中断 系统扩展 接口技术 串行口
💻 ASM
字号:
;过迷宫的算法。
LIST	EQU	30H	;有效路线记录表的首址。
CONT	DATA	30H	;有效路线中的岔路口计数器。
OK	BIT	00H	;成功标志。
RETURN	BIT	01H	;返回标志。
ERROR	BIT	02H	;出错标志。

	ORG	0000H
	LJMP	TEST
	
	ORG	100H
TEST:	MOV	DPTR,#LINE1;模拟岔路口数据表格首址。
	LCALL	SEARCH	;通过未知迷宫的搜索算法。
	NOP		;算法输出的有效路线记录:
	NOP		;16H(记录长度为22字节)
	NOP		;3EH,26H,3FH,26H,29H,2DH,25H
	NOP		;2DH,2DH,3EH,2DH,25H,2DH,26H,2AH
	NOP		;29H,2EH,2EH,2DH,2AH,25H,80H
	NOP		;
	MOV	DPTR,#LINE2;模拟岔路口数据表格首址。
	LCALL	GO	;通过已知迷宫的算法。	
STOP:	LJMP	STOP


SEARCH:	CLR	OK	;初始化成功标志为零(尚未成功)。
	CLR	RETURN	;初始化返回标志为零(向前搜索)。
	MOV	CONT,#0	;初始化有效路线记录为空表。
	MOV	R0,#LIST;初始化线性表指针。
S0:	LCALL	ON	;接通电机电源,使机器鼠向前运动。
S1:	LCALL	DETECT	;检测当前位置的情况。
	CJNE	A,#10H,S2;是在直巷子里吗?
	SJMP	S1	;是,不关电机,一边前进一边检测。
S2:	LCALL	OFF	;有情况,断开电机电源使机器鼠停下来。
	CJNE	A,#80H,S3;是出口吗?
	INC	R0	;调整指针。
	INC	CONT	;记录长度加一。
	MOV	@R0,A	;保存出口信息。
	SETB	OK	;是出口,设置成功标志。
	RET	;有效路线搜索结束。
S3:	JNZ	S4	;是死胡同尽头吗?
	LCALL	BACK	;是,向后转。
	SETB	RETURN	;设置返回标志。
	SJMP	S0	;从死胡同返回。
S4:	CJNE	A,#14H,S5;是路段内部的左转弯吗?
	LCALL	LEFT	;是,向左转。
	SJMP	S0	;继续前进。
S5:	CJNE	A,#18H,S6;是路段内部的右转弯吗?
	LCALL	RIGHT	;是,向右转。
	SJMP	S0	;继续前进。
S6:	MOV	B,A	;保存检测信息。
	JB	RETURN,S7;是返回状态吗?
	INC	R0	;不是,调整到下一个地址,准备保存新岔路口记录。
	MOV	@R0,B	;保存新岔路口记录。
	INC	@R0	;在新岔路口,按左手“顺墙摸”选择第一岔路。
	INC	CONT	;记录表格长度加一。
	SJMP	S9	;进入新的路段。
S7:	MOV	A,@R0	;是返回状态,取原记录。
	ANL	A,#33H	;分离出岔路总数和当前岔路的编号。
	MOV	R2,A	;暂存。
	SWAP	A	;交换位置。
	XRL	A,R2	;进行比较。
	JZ	S8	;相同否?
	INC	@R0	;不相同,还有未经搜索的岔路,选择下一条岔路。
	CLR	RETURN	;清除返回标志,准备进行新的搜索。
	SJMP	S9	;进入新的路段。
S8:	DEC	CONT	;相同,所有岔路均已搜索过,删除该岔路口。
	DEC	R0	;记录指针后退。
S9:	JNB	B.2,S0	;若左边没有岔路,继续向前走。
	LCALL	LEFT	;若左边有岔路,则向左转(左手“顺墙摸”法则)。
	LJMP	S0	;继续前进。

GO:	MOV	R7,CONT	;取有效路线记录元素总数。
	MOV	R0,#LIST+1;指向第一个记录元素。
	CLR	ERROR	;初始化出错标志。
GO0:	LCALL	ON	;接通电机电源,使机器鼠向前运动。
GO1:	LCALL	DETECT	;检测当前位置的情况。
	CJNE	A,#10H,GO2;是在直巷子里吗?
	SJMP	GO1	;是,不关电机,一边前进一边检测。
GO2:	LCALL	OFF	;有情况,断开电机电源使机器鼠停下来。
	CJNE	A,#80H,GO3;是出口吗?
	RET		;顺利通过迷宫。
GO3:	CJNE	A,#14H,GO4;是路段内部的左转弯吗?
	LCALL	LEFT	;是,向左转。
	SJMP	GO0	;继续前进。
GO4:	CJNE	A,#18H,GO5;是路段内部的右转弯吗?
	LCALL	RIGHT	;是,向右转。
	SJMP	GO0	;继续前进。
GO5:	XRL	A,@R0	;碰到岔路口,和记录信息比较。
	ANL	A,#0FCH	;分离出岔路口类型比较结果。
	JNZ	GOE	;岔路口类型与记录中的类型不同,出错。
	MOV	A,@R0	;读取记录元素。
	MOV	B,A	;暂存。
	ANL	A,#3	;分离出岔路编号。
	CJNE	A,#3,GO7;是选择第三岔路吗?
	LCALL	RIGHT	;向右转弯。
	SJMP	GO9	;继续向前走。
GO7:	CJNE	A,#2,GO8;是选择第二岔路吗?
	JNB	B.3,GO9	;若右边没有岔路,继续向前走。
	LCALL	RIGHT	;若右边有岔路,向右转弯。
	SJMP	GO9	;继续向前走。
GO8:	JNB	B.2,GO9	;选择第一岔路,若左边没有岔路,继续向前走。
	LCALL	LEFT	;若左边有岔路,则向左转。
GO9:	INC	R0	;调整记录指针。
	DJNZ	R7,GO0	;记录元素尚未读完,继续前进。
GOE:	CLR	OK	;记录全部读完或迷宫发生变化,清除成功标志。
	SETB	ERROR	;设立出错标志。
	RET		;失败返回。

ON:	NOP		;电机启动子程序(省略)。
	NOP
	RET

OFF:	NOP		;电机关闭子程序(省略)。
	NOP
	RET

LEFT:	NOP		;向左转弯子程序(省略)。
	NOP
	RET

RIGHT:	NOP		;向右转弯子程序(省略)。
	NOP
	RET

BACK:	NOP		;向后转弯子程序(省略)。
	NOP
	RET

DETECT:	CLR	A	;检测子程序(用读表格来模拟)。
	MOVC	A,@A+DPTR
	INC	DPTR
	RET

LINE1:	DB	3CH,18H,18H,00H,14H,14H,3CH,14H,18H	;图11-1所示迷宫在左手“顺
	DB	24H,14H,00H,18H,2CH,14H,14H,18H,3CH	;墙摸”时沿路检测得到的编码。
	DB	2CH,18H,00H,14H,28H,14H,24H,00H,2CH
	DB	14H,00H,18H,28H,18H,24H,3CH,18H,18H
	DB	00H,14H,14H,3CH,14H,18H,18H,14H,24H
	DB	2CH,18H,18H,14H,14H,00H,18H,18H,14H
	DB	14H,28H,00H,24H,2CH,18H,28H,18H,18H
	DB	2CH,24H,18H,2CH,18H,2CH,3CH,00H,3CH
	DB	2CH,18H,18H,24H,2CH,24H,00H,2CH,14H
	DB	28H,00H,24H,28H,14H,14H,14H,18H,2CH
	DB	14H,18H,18H,00H,14H,14H,18H,28H,2CH
	DB	00H,28H,14H,18H,2CH,14H,18H,28H,18H
	DB	00H,14H,24H,18H,24H,80H

LINE2:	DB	3CH,14H,18H,24H,14H,14H,18H,3CH	;图11-1所示迷宫在有效
	DB	14H,18H,18H,14H,24H,18H,28H,18H	;路线记录的指引下,
	DB	18H,2CH,24H,18H,2CH,18H,2CH,3CH	;沿路检测得到的编码。
	DB	2CH,18H,18H,24H,2CH,24H,14H,28H
	DB	28H,14H,14H,14H,18H,2CH,2CH,14H
	DB	18H,2CH,14H,18H,28H,18H,24H,80H

	END

⌨️ 快捷键说明

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