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

📄 compulater.txt

📁 1. 计算器实现的功能 (1)整数的加、减、乘、除运算; (2)小数的加、减运算
💻 TXT
📖 第 1 页 / 共 3 页
字号:
LIST   P=16F877
INCLUDE "P16F877.INC"
A1      EQU     21H
A2	EQU	22H
A3	EQU	23H	;扫描后的键的地址值 
A4	EQU	24H
G1	EQU	25H	
G2	EQU	26H
AA	EQU	27H
BUFF	EQU 	28H
BIT	EQU	29H
OUT1	EQU	30H
COUNT	EQU	31H	;取数时的四位限制
ADDER0	EQU	32H	;ADDER0-3作为显示缓存区
ADDER1	EQU	33H	;存放将要显示的数字的
ADDER2	EQU	34H	;非压缩BCD码
ADDER3	EQU	35H
ADDER4	EQU	36H	;ADDER4存放键盘输入数字的个数

KEY_ANS	EQU	37H	;键的地址翻译后的数值
TEST1	EQU	38H	;和A3内容相同,翻译键址后的数值时用到

DATA0	EQU	39H	;DATA0-3存放 被加数、减数、小数的整数部分
DATA1	EQU	40H
DATA2	EQU	41H
DATA3	EQU	42H
DATB0	EQU	43H	;DATB0-3存放 加数、被减数、小数的整数部分
DATB1	EQU	44H
DATB2	EQU	45H
DATB3	EQU	46H

ANSER0	EQU	47H	;加、减运算结果缓存区
ANSER1	EQU	48H
ANSER2	EQU	49H
ANSER3	EQU	50H

FLAGA	EQU	51H	;标志位,加进位,减借位时FLAGA=1

DATC0	EQU	52H	;DATC0-3存乘数、被除数、余数
DATC1	EQU	53H
DATC2	EQU	54H
DATC3	EQU	55H
DATD0	EQU	56H	;DATD0-3存被乘数、除数
DATD1	EQU	57H
DATD2	EQU	58H
DATD3	EQU	59H
DATE0	EQU	60H	;DATE0-3存乘法结果、除数的商
DATE1	EQU	61H
DATE2	EQU	62H
DATE3	EQU	63H
DATF0	EQU	66H	;DATF0-3中间数据暂存区
DATF1	EQU	67H
DATF2	EQU	68H
DATF3	EQU	69H

FLAGB	EQU	64H	;如果DATD中的数据为零,则FLAGB=1
FLAGC	EQU	65H	;报错标志位,执行ERROR-FUN后,FLAGC=1
FG_DOT	EQU	6AH	;小数点标志位,有小数点按下,则FG_DOT=1

DATG0	EQU	6BH	;;DATF0-3中间数据暂存区
DATG1	EQU	6CH
DATG2	EQU	6DH
DATG3	EQU	6EH
;********************MAIN FUNTION*****************************
    ORG    000H
MAIN
     	NOP
	CALL	LEDD			;初始化LED
AAA	CALL	INI_ADDER		;显示空字符
	CALL	PLAY
	CALL	GET_NUM			;获取键入的数字

DD2	BTFSC	FLAGC,0			;检测,出错则重新开始
	GOTO	AAA
	CALL	NEXT_MATH		;翻译符号,进行相关运算处理
;------------------------------	
	BTFSS	FLAGA,0			;运算出错则重新开始
	GOTO	BBB
	CALL	ERROR_FUN
	GOTO	CCC
BBB	
	CALL	PLAY			;显示结果
	
CCC	CALL	EQU_Y_N			;‘=’号按下后,重新开始
	GOTO	AAA
	GOTO	ENDD
;  01-funtion************keyboard number**********************
KEYNUM  NOP
	
STA	BCF	 STATUS,RP1
	BSF      STATUS,RP0             ;设置为体1
        MOVLW 	 0F0H
        MOVWF 	 TRISD			;设置RD口低四位为输出,高四位为输入
        BCF      STATUS,RP0		;设置为体0
;-------------just if the key is-on-------
IFON	MOVLW	 00H
	MOVWF	 PORTD			;将低四位全部输出0
	MOVF	 PORTD,W		;将高四位输入给W
	IORLW    0FH			;屏蔽低四位

	MOVWF	 A4
	COMF	 A4,1			;判断高四位输入中是否有键按下
	

	BTFSC    STATUS,Z		;若Z=1,表明无键按下,跳回IFON继续
	GOTO	 IFON			;扫描直至有键按下
 	CALL	 DELAY			;否则延时后再次扫描

IFON2	MOVLW	 00H
	MOVWF	 PORTD
	MOVF	 PORTD,W
	IORLW    0FH
	MOVWF	 A4
	COMF	 A4,1
	BTFSS    STATUS,Z		;再次扫描后,仍有键按下,则跳到KEYSCAN
	GOTO	 KEYSCAN		;没有的话则延时后继续扫描
	CALL	 DELAY
	GOTO	 IFON

;------------KEYNUMBER-----------------------    
KEYSCAN  
        MOVLW	 0EH 			;RD1-3口输出高电平,RD0口输出低电平,判段该行
        MOVWF	 A1			;是否有键按下
        MOVWF 	 PORTD
        MOVF	 PORTD,W		
	ANDLW	 0F0H			;屏蔽掉高四位
	MOVWF	 A2			;输出A2
	XORLW	 0F0H			;屏蔽掉低四位
        BTFSS	 STATUS,Z		;有键按下时,Z=0,则跳转到KEYON
        GOTO	 KEYON			;无键按下时,Z=1,继续扫描下一行

        MOVLW	 0DH			;RD0、2、3口输出高电平,RD1口输出低电平
        MOVWF	 A1
        MOVWF 	 PORTD
        MOVF	 PORTD,W
        ANDLW	 0F0H
	MOVWF	 A2
	XORLW	 0F0H
        BTFSS	 STATUS,Z
        GOTO	 KEYON

        MOVLW	 0BH			;RD0、1、3口输出高电平,RD2口输出低电平
        MOVWF	 A1
        MOVWF 	 PORTD
        MOVF	 PORTD,W
        ANDLW	 0F0H
	MOVWF	 A2
	XORLW	 0F0H
        BTFSS	 STATUS,Z
        GOTO	 KEYON

        MOVLW	 07H			;RD0、1、2口输出高电平,RD3口输出低电平
        MOVWF	 A1
        MOVWF 	 PORTD
        MOVF	 PORTD,W
        ANDLW	 0F0H
	MOVWF	 A2
	XORLW	 0F0H
        BTFSS	 STATUS,Z
        GOTO	 KEYON
        GOTO	 STA

KEYON   MOVF    A1,0
        ADDWF    A2,W
        MOVWF    A3			;把扫描到的键值存入A3
	
;---------------wait for keyboard off----------
IFOFF	MOVLW	 00H			;判断按下的键是否已经起来,并通过延时来防抖
	MOVWF	 PORTD
	MOVF	 PORTD,W
	IORLW    0FH
	MOVWF	 A4
	COMF	 A4,1
	BTFSS    STATUS,Z		;键已起来则Z=1,延时后再扫描
	GOTO	 IFOFF
	CALL     DELAY
	CALL	 DELAY
IFOFF2	MOVLW	 00H
	MOVWF	 PORTD
	MOVF	 PORTD,W
	IORLW    0FH
	MOVWF	 A4
	COMF	 A4,1
	BTFSS    STATUS,Z		;再次扫描仍键已起来则RETURN
	GOTO     IFOFF
	RETURN
;  02-funtion************  将扫描得到的键地址翻译成数字
TRANSK	NOP
	MOVF	A3,0
	MOVWF	TEST1
	
	BTFSS	TEST1,3		;如果是符号
	RETURN
	BTFSS	TEST1,2		;键的低四位的地址是 _BH
	GOTO	NEXT2
	BTFSS	TEST1,1		;键的低四位的地址是 _DH
	GOTO	NEXT1
	BTFSS	TEST1,0		;键的低四位的地址是 _EH
	GOTO	NEXT0
	GOTO	NEXT_END
NEXT2				;test 7-4, _BH
	BTFSC	TEST1,5
	GOTO	NEXT25
	CLRF	KEY_ANS		;DBH <=> 00
NEXT25	BTFSC	TEST1,4
	GOTO	NEXT_END	
	MOVLW	09H
	MOVWF	KEY_ANS		;EBH <=> 09
	GOTO	NEXT_END

NEXT1	BTFSC	TEST1,7		;test 7-4, _DH
	GOTO	NEXT16
	MOVLW	08H
	MOVWF	KEY_ANS		; 7DH <=> 08
	GOTO	NEXT_END
NEXT16	BTFSC	TEST1,6		
	GOTO	NEXT15
	MOVLW	07H
	MOVWF	KEY_ANS		; BDH <=> 07
	GOTO	NEXT_END
NEXT15	BTFSC	TEST1,5		
	GOTO	NEXT14
	MOVLW	06H
	MOVWF	KEY_ANS		; DDH <=> 06
	GOTO	NEXT_END
NEXT14	BTFSC	TEST1,4		
	GOTO	ERROR_1
	MOVLW	05H
	MOVWF	KEY_ANS		; EDH <=> 05
	GOTO	NEXT_END

NEXT0	BTFSC	TEST1,7		;test 7-4, _EH
	GOTO	NEXT06
	MOVLW	04H
	MOVWF	KEY_ANS		;  7EH <=> 04
	GOTO	NEXT_END
NEXT06	BTFSC	TEST1,6		
	GOTO	NEXT05
	MOVLW	03H
	MOVWF	KEY_ANS		;  BEH <=> 03
	GOTO	NEXT_END
NEXT05	BTFSC	TEST1,5		
	GOTO	NEXT04
	MOVLW	02H
	MOVWF	KEY_ANS		;  DEH <=> 02
	GOTO	NEXT_END
NEXT04	BTFSC	TEST1,4		
	GOTO	ERROR_1
	MOVLW	01H
	MOVWF	KEY_ANS		;  EEH <=> 01
	GOTO	NEXT_END
NEXT_END
	NOP
	RETURN
;  03-funtion******************************************************
GET_NUM	CLRF	FLAGC
	CLRF	FG_DOT
LL2	CALL	INI_ADDER
	CALL	PLAY
	MOVLW	05H		;5给计数器COUNT,限制只能取四位数
	MOVWF	COUNT
LL1	CALL	KEYNUM		;调用取键值子程序
;-------IF the num we get is not the signal__go on----------
	MOVF	A3,0
	MOVWF	TEST1
	BTFSS	TEST1,3		;检测有运算符号按下时跳到END1
	GOTO	END_1

	BTFSC	TEST1,2
	GOTO	NNEXT
	BTFSS	TEST1,7		
	GOTO	END_1		;检测有等号按下时跳到END1
	BTFSC	TEST1,6
	GOTO	NNEXT
	CALL	DOT_FUN		;检测到小数点时,执行相应程序并显示
	CALL	PLAY
	GOTO	LL1
;----------------------------------------
NNEXT	CALL	TRANSK		;调用翻译键值子程序
	CALL	ANS_ADDER
	CALL	PLAY		;将结果显示
	DECFSZ	COUNT,1		;计数器减一
	GOTO	LL1		;不为0则继续取下一位
	GOTO	LL2		;为0则说明已超过四位,重新开始取值
END_1	NOP
	MOVF	ADDER4,0	;检测第一次按下运算符号或等号时报错
	IORLW	00H		;不是第一次按下则返回,即检测到符号时表明输入数结束
	BTFSS	STATUS,Z
	GOTO	END_2
	CALL	ERROR_FUN
	BSF	FLAGC,0
END_2	RETURN

;  04-funtion********Calculation funtion***********翻译运算符号
NEXT_MATH
	BTFSC	FG_DOT,0	;如果有小数点,则执行小数的相应程序
	GOTO	M_DOT
	BTFSS	TEST1,3		;检测 ,是运算符号,则执行相应跳转
	GOTO	MATH7
	GOTO	FUN_RET		;不是运算符号,则返回
MATH7	BTFSC	TEST1,7		;如果‘除’号
	GOTO	MATH6
	CALL	DIVI_FUN	;执行‘除’法程序
	GOTO	FUN_RET
MATH6	BTFSC	TEST1,6		;如果‘乘’号
	GOTO	MATH5
	CALL	MULT_FUN	;执行‘乘’法程序
	GOTO	FUN_RET
MATH5	BTFSC	TEST1,5		;如果‘减’号
	GOTO	MATH4
	CALL	SUB_FUN		;执行‘减’法程序
	GOTO	FUN_RET
MATH4	BTFSC	TEST1,4		;如果‘加’号
	GOTO	FUN_RET
	CALL	ADD_FUN		;执行‘加’法程序
	GOTO 	FUN_RET

M_DOT	BTFSC	TEST1,7		;小数‘除’法
	GOTO	MAT_6
	BSF	FLAGA,0		;强行报错,返回
	GOTO	FUN_RET
MAT_6	BTFSC	TEST1,6		;小数‘乘’法
	GOTO	MAT_5
	BSF	FLAGA,0		;强行报错,返回
	GOTO	FUN_RET
MAT_5	BTFSC	TEST1,5		;如果‘减’号
	GOTO	MAT_4
	CALL	SUB_DOTT	;小数‘减’法
	GOTO	FUN_RET
MAT_4	BTFSC	TEST1,4		;如果‘加’号
	GOTO	FUN_RET
	CALL	ADD_DOTT	;小数‘加’法
FUN_RET	NOP
	RETURN
;************ addition funtion ************************************************
;  05-funtion*****************ADD_PREPARE****************
ADD_FUN	NOP			;加法准备函数
	CLRF	DATA0
	CLRF	DATA1
	CLRF	DATA2
	CLRF	DATA3		;DATA清零
	CLRF	DATB0
	CLRF	DATB1
	CLRF	DATB2
	CLRF	DATB3		;DATB清零

	CALL	ADDER_A		;把显示缓存区的内容‘被加数’给DATA
	CALL	GET_NUM		;取‘加数’
	CALL	ADDER_B		;把显示缓存区的内容‘加数’给DATB
	CALL	INI_ADDER	;清屏
	CALL	ADD_A_B		;计算DATA+DATB=ANSER
	CALL	RES_ADDER	;把结果ANSER给显示缓存区
	RETURN
;  06-funtion********************** ADDTION ****************
ADD_A_B	NOP			;计算DATA+DATB
	MOVLW	06H
	ADDWF	DATA0,0
	ADDWF	DATB0,0		;计算个位数相加
	MOVWF	ANSER0		;ANSER0=DATA0+DATB0+6
	BTFSS	STATUS,DC	
	GOTO	A_DD2		;DC=0,没有进位则减六
	MOVLW	01H		;有进位则FLAGA=1
	MOVWF	FLAGA		
	MOVF	ANSER0,W	;保证ANSER0中存放的是非压缩BCD码
	ANDLW	0FH
	MOVWF	ANSER0
	GOTO	JIA_1		;继续进行十位数的相加
A_DD2	MOVLW	06H
	SUBWF	ANSER0,1	;没有进位则ANSER0=ANSER0-6
	MOVLW	00H
	MOVWF	FLAGA		;没有进位则FLAGA=0
JIA_1	MOVLW	06H		;十位数相加(原理同个位数)
	ADDWF	DATA1,0
	MOVWF	ANSER1
	MOVF	FLAGA,0
	ADDWF	DATB1,0
	ADDWF	ANSER1,1	
	BTFSS	STATUS,DC
	GOTO	A_DD3	;DC=0
	MOVLW	01H
	MOVWF	FLAGA
	MOVF	ANSER1,W
	ANDLW	0FH
	MOVWF	ANSER1
	GOTO	JIA_2	
A_DD3	MOVLW	06H
	SUBWF	ANSER1,1
	MOVLW	00H
	MOVWF	FLAGA
JIA_2	MOVLW	06H		;百位数相加(原理同个位数)
	ADDWF	DATA2,0
	MOVWF	ANSER2
	MOVF	FLAGA,0
	ADDWF	DATB2,0
	ADDWF	ANSER2,1
	BTFSS	STATUS,DC
	GOTO	A_DD4	;DC=0	
	MOVLW	01H
	MOVWF	FLAGA
	MOVF	ANSER2,W
	ANDLW	0FH
	MOVWF	ANSER2
	GOTO	JIA_3	
A_DD4	MOVLW	06H
	SUBWF	ANSER2,1
	MOVLW	00H
	MOVWF	FLAGA
JIA_3	MOVLW	06H		;千位数相加(原理同个位数)
	ADDWF	DATA3,0
	MOVWF	ANSER3
	MOVF	FLAGA,0
	ADDWF	DATB3,0
	ADDWF	ANSER3,1
	BTFSS	STATUS,DC
	GOTO	A_DD5	;DC=0	
	MOVLW	01H
	MOVWF	FLAGA
	MOVF	ANSER3,W
	ANDLW	0FH
	MOVWF	ANSER3
	GOTO	JIA_4	
A_DD5	MOVLW	06H
	SUBWF	ANSER3,1
	MOVLW	00H
	MOVWF	FLAGA
JIA_4	RETURN

⌨️ 快捷键说明

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