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

📄 mcu.asm

📁 proteus实例集锦
💻 ASM
📖 第 1 页 / 共 5 页
字号:
						;触发外部中断0。
		call	ENABLEINT0		;开启外部中断0。
		mov	a,MENUINDEX		;取得功能序号。
		mov	dptr,#FUNCTABLE		;
		rl	a			;
		rl	a			;
		jmp	@a+dptr			;按功能序号转移至相应功能处。

FUNCTABLE:	ljmp	FUNCTION0		;一定要强制使用ljmp指令,以保证每个
						;小段都是4个字节。
		nop				;
		ljmp	FUNCTION1		;
		nop				;		
		ljmp	FUNCTION2		;
		nop				;
		ljmp	FUNCTION3		;
		nop				;
		ljmp	FUNCTION4		;
		nop				;
		ljmp	FUNCTION5		;
		nop				;
		ljmp	FUNCTION6		;
		nop				;
		ljmp	FUNCTION7		;
		nop				;
		ljmp	FUNCTION8		;
		nop				;
		ljmp	FUNCTION9		;
		nop				;
		ljmp	FUNCTION10		;
		nop				;
		ljmp	FUNCTION11		;
		nop				;
		ljmp	FUNCTION12		;
		nop				;
		ljmp	FUNCTION13		;
		nop				;

;;;;;;;;;;;;;;;;功能选择子程序结束;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;	

;;;;;;;;;;;;;;;;欢迎子程序;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;>>>>>>>>>>>>>>>资源占用报告>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;>>>>>>>>>>>>>>>临时占用a,dptr
;>>>>>>>>>>>>>>>报告完毕>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
FUNCTION0:	mov	dptr,#8000h		;
		mov	a,#81h			;
		movx	@dptr,a			;命令自建元器件进入欢迎状态。
						;再啰嗦几句,如果您要使用自建
						;元器件,那么必须自己改写动态
						;库,作者提供一个简单的动态库
						;开源项目。
		mov	a,#80h			;
		movx	@dptr,a			;命令自建元器件进入待机状态。
		mov	a,#LCD_CLS		;
		call	WRCMD			;清屏。
		mov	dptr,#WELCOME_1		;
		call 	WRSTR			;初始化LCD屏幕,显示第一行。
		mov 	a,#LCD_SETDDADDR+64	;换行。
		call 	WRCMD			;
		inc	dptr			;
		call 	WRSTR			;
FUNCTION0_1:	mov	a,RETURNFLAG		;检查返回标志,决定是否返回。
		jz	FUNCTION0_CON		;如果为零,继续执行。CON=CONTINUE。
		jmp	main			;
FUNCTION0_CON:	jmp	FUNCTION0_1		;
;;;;;;;;;;;;;;;;欢迎子程序结束;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;测量电压功能子程序;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;>>>>>>>>>>>>>>>资源占用报告>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;>>>>>>>>>>>>>>>临时占用a,b,c,dptr,bank0区r0~r7
;>>>>>>>>>>>>>>>报告完毕>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
FUNCTION1:	call	DISABLEINT1		;屏蔽外部中断1。
						;作者没有使用中断的方法处理ADC0804的
						;$INTR$引脚变化,所以必须屏蔽外部中
						;断1。
		mov	a,STATUS		;取得外部电设备状态字。
		orl	a,#01h			;进入测量电压状态。
		anl	a,#0FDh			;
		mov	STATUS,a		;保存外部电设备状态字。
		mov	dptr,#8100h		;
		movx	@dptr,a			;
		nop				;稍微停顿一下。
		nop				;
FUNCTION1_1:	mov	a,RETURNFLAG		;检查返回标志,决定是否返回。
		jz	FUNCTION1_CON		;如果为零,继续执行。
		jmp	main			;
FUNCTION1_CON:	call	ADCIO			;调用ADC0804读写操作子程序。
						;读取的数值放在a和地址ADCOUTCUR中。
		cjne	a,ADCOUTBAK,FUNCTION1_2	;比较当前和上一次ADC0804输出,如果
						;相同,那么表明外部电压没有发生改
						;变,也就没有必要刷新显示,这样视觉
						;效果比较舒服。
		jmp	FUNCTION1		;
FUNCTION1_2:	mov	r3,a			;ADC0804的数值乘以5,除以255就是对应
						;的模拟电压值。现在将这个模拟电压值
						;的单位换算为mV,也就是扩大1000倍,
						;然后取得4位计算结果。当然了,最后
						;那一位没有意义,因为ADC0804只有8
						;bit精度,您可以算算它对应的最小电
						;压分辨率是多少。
		mov	r2,#00h			;
		mov	r7,#88h			;
		mov	r6,#13h			;十六进制1388等于十进制5000。
		call	MULD2			;调用双字节无符号乘法子程序。
		mov	r0,#DIVD4ADDRESS0	;以下准备调用4字节无符号除法子程序,
						;将刚才的乘法结果除以255。下面是一些
						;赋初始值的准备工作。
		mov	r1,#DIVD4ADDRESS4	;
		mov	a,r2			;
		movx	@r1,a			;
		inc	r1			;
		mov	a,r3			;
		mov	@r1,a			;
		inc	r1			;
		mov	a,r4			;
		mov	@r1,a			;
		inc	r1			;
		mov	a,r5			;
		mov	@r1,a			;
		inc	r1			;
		mov	@r1,#00h		;
		inc	r1			;
		mov	@r1,#00h		;
		inc	r1			;
		mov	@r1,#00h		;
		inc	r1			;
		mov	@r1,#0FFh		;准备除以的255。
		call	DIVD4			;调用4字节无符号除法子程序。
						;除法结束之后就应该显示结果了,对吧!
						;可是您别着急,在内存中的数值是二进制
						;的,一个字节对应2个十六进制数字,所
						;以必须先做一些转换工作。有两种方法。
						;第一种:将运算结果连续的进行除以10的操
						;作,依次取得个位、十位、百位等等,就
						;像下面的程序那样,这么做比较浪费处理
						;器的时间,因为您做的是除法。第二种方
						;法:对结果进行BCD调整。这个方法应该简
						;单,留给您自己思考了,我没有编写。
		mov	r1,#DIVD4ADDRESS8	;
		mov	@r1,#00h		;
		inc	r1			;
		mov	@r1,#00h		;
		inc	r1			;
		mov	@r1,#00h		;
		inc	r1			;
		mov	@r1,#0Ah		;准备除以10。
		mov	dptr,#LCD0		;
		call	DIVD4			;
		mov	a,DIVD4ADDRESS3		;DIVD4ADDRESS3单元存放的是除法后的最低位
						;余数,由于是除以10的余数,只能是0123456
						;789之一。
		movc	a,@a+dptr		;要是直接显示这个数字的话,恐怕您什么都
						;看不到。LCD1602不认识啊,它只认识ASCII
						;码,所以还得取得这个数字对应的ASCII码才
						;行。作者已经在前面列出了必要的ASCII码表。
						;也许作者这个处理方法复杂了,要是您有好的
						;方法,不吝赐教哦!作者QQ66410070。
		mov	RESULT5,a		;
		call   DIVD4			;
		mov	a,DIVD4ADDRESS3		;
		movc	a,@a+dptr		;
		mov	RESULT4,a		;
		call   DIVD4			;
		mov	a,DIVD4ADDRESS3		;
		movc	a,@a+dptr		;
		mov	RESULT3,a		;
		call   DIVD4			;
		mov	a,DIVD4ADDRESS3		;
		movc	a,@a+dptr		;
		mov	RESULT1,a		;
		mov	a,#0Dh			;小数点。
		movc	a,@a+dptr		;
		mov	RESULT2,a		;
		mov	a,#0Ch			;
		movc	a,@a+dptr		;
		mov	RESULT6,a		;单位V。
		mov	a,#00h			;
		mov	RESULT7,a		;空终止。后面的程序类似,不再解释。
		mov 	a,#LCD_CLS		;清屏。
		call 	WRCMD			;
		call	WRRESULT		;调用写结果字符串子程序。
		jmp	FUNCTION1_1		;
;;;;;;;;;;;;;;;;测量电压功能子程序结束;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;	

;;;;;;;;;;;;;;;;ADC读写子程序;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;>>>>>>>>>>>>>>>资源占用报告>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;>>>>>>>>>>>>>>>临时占用a,dptr,c,r7
;>>>>>>>>>>>>>>>报告完毕>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
ADCIO:		mov	a,ADCOUTCUR		;
		mov	ADCOUTBAK,a		;前一次结果保存在ADCOUTBAK中。
		mov	dptr,#8200h		;选择ADC0804,一定要保证P2.7处于高
						;电平,禁止ADC的输出。作者把启动
						;ADC0804转换的操作映射为外部内存的
						;空写操作(随便;写任何数值)。但是
						;作者没有将ADC0804的的读取映射为外
						;部内存的读操作。作者曾经试图这么
						;做,但是失败了!也许是Proteus软件
						;在时序方面的问题,也许是ADC0804器
						;件的问题,当然也可能是作者水平有
						;限,没能找到解决方案。如果您有好的
						;设计,千万告知作者,谢谢!
		movx	@dptr,a			;空写ADC0804,启动转换。
		setb	c			;
		mov	p3.3,c			;读取数据必须先写1。
ADCIO_1:	mov	c,P3.3			;等待ADC0804转换完成。
		jc	ADCIO_1			;
		mov	p0,#0FFh		;读取数据必须先写1。
		clr	c			;
		mov	p2.7,c			;开启ADC0804的输出允许。
		nop				;不要马上读取。
		nop				;ADC0804转换结束与输出需要间隔几个
						;时钟周期。
		nop				;具体需要几个时钟周期请参考手册,自
		nop				;行调整。
		nop				;
		nop				;
		nop				;
		nop				;
		mov	a,p0			;读端口,取得转换的数字值。
		mov	ADCOUTCUR,a		;写入ADCOUTCUR。
		setb	c			;
		mov	p2.7,c			;关闭ADC0804的输出允许,以免影响后
						;续对其它器件的操作。一定要关闭啊!
		ret				;
;;;;;;;;;;;;;;;;ADC读写子程序结束;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;测量电阻功能子程序;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;>>>>>>>>>>>>>>>资源占用报告>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;>>>>>>>>>>>>>>>临时占用a,b,c,dptr,bank0区r0~r7
;>>>>>>>>>>>>>>>>>报告完毕>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
FUNCTION2:	call	DISABLEINT1		;屏蔽外部中断1。
		mov	a,STATUS		;取得外部电设备状态字。
		orl	a,#03h			;进入测量电阻状态。
		mov	STATUS,a		;保存外部电设备状态字。
		mov	dptr,#8100h		;
		movx	@dptr,a			;
		nop				;稍微停顿一下。
		nop
FUNCTION2_1:	mov	a,RETURNFLAG		;检查返回标志,决定是否返回。
		jz	FUNCTION2_CON		;
		jmp	main			;
FUNCTION2_CON:	call	ADCIO			;调用ADC0804读写操作子程序。
						;读取的数值放在a和地址ADCOUTCUR中。
		cjne	a,ADCOUTBAK,FUNCTION2_2	;比较当前和上一次ADC0804输出,如果
						;相同,那么表明外部电压没有发生改
						;变,也就没有必要刷新显示,这样视
						;觉效果比较舒服。
		jmp	FUNCTION2		;
FUNCTION2_2:	mov	r3,a			;ADC0804的数值乘以23500,除以3060,
						;再减去910,就是待测电阻值。参考电
						;路图,您可以自己思考为什么是这个算
						;式?以下的程序与测电压大同小异,不
						;再多解释。
		mov	r2,#00h			;
		mov	r7,#0CCh		;
		mov	r6,#5Bh			;十六进制5BCC等于十进制23500。
		call	MULD2			;调用双字节无符号乘法子程序。
		mov	r0,#DIVD4ADDRESS0	;
		mov	r1,#DIVD4ADDRESS4	;
		mov	a,r2			;
		movx	@r1,a			;
		inc	r1			;
		mov	a,r3			;
		mov	@r1,a			;
		inc	r1			;
		mov	a,r4			;
		mov	@r1,a			;
		inc	r1			;
		mov	a,r5			;
		mov	@r1,a			;
		inc	r1			;
		mov	@r1,#00h		;
		inc	r1			;
		mov	@r1,#00h		;
		inc	r1			;
		mov	@r1,#0Bh		;
		inc	r1			;
		mov	@r1,#0F4h		;十六进制0BF4等于十进制3060。
		call	DIVD4			;
		clr	c			;清除c。
		mov	r1,#DIVD4ADDRESS7	;以下减去910,四个字节减法。
		mov	a,@r1			;
		subb	a,#8Eh			;
		mov	@r1,a			;
		dec	r1			;
		mov	a,@r1			;
		subb	a,#03h			;
		mov	@r1,a			;
		dec	r1			;
		mov	a,@r1			;
		subb	a,#00h			;
		mov	@r1,a			;
		dec	r1			;
		mov	a,@r1			;
		subb	a,#00h			;
		mov	@r1,a			;				
		mov	r1,#DIVD4ADDRESS8	;
		mov	@r1,#00h		;
		inc	r1			;
		mov	@r1,#00h		;
		inc	r1			;
		mov	@r1,#00h		;
		inc	r1			;
		mov	@r1,#0Ah		;
		mov	dptr,#LCD0		;
		call	DIVD4			;
		mov	a,DIVD4ADDRESS3		;
		movc	a,@a+dptr		;
		mov	RESULT3,a		;
		call   DIVD4			;
		mov	a,DIVD4ADDRESS3		;
		movc	a,@a+dptr		;
		mov	RESULT2,a		;
		call   DIVD4			;
		mov	a,DIVD4ADDRESS3		;
		movc	a,@a+dptr		;
		mov	RESULT1,a		;
		mov	a,#0Bh			;R的字符。
		movc	a,@a+dptr		;
		mov	RESULT4,a		;
		mov	a,#00h			;
		mov	RESULT5,a		;
		mov	a,RESULT1		;灭零处理。比如待测的电阻是20R,
						;希望显示结果20R,而不是020R,灭
						;掉前导零。
		cjne	a,#30h,FUNCTION2_3	;先取得最高位字符,如果是零(ASCII
						;码30h),那么灭掉,其后的字符依次
						;前移一位。否则不灭零,直接显示。
		mov	a,RESULT2		;
		mov	RESULT1,a		;
		mov	a,RESULT3		;
		mov	RESULT2,a		;
		mov	a,RESULT4		;
		mov	RESULT3,a		;
		mov	a,RESULT5		;
		mov	RESULT4,a		;
		mov	a,RESULT1		;

⌨️ 快捷键说明

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