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

📄 calc.asm

📁 PROTEUS仿真PIC16F877的例子
💻 ASM
字号:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;	CALC.ASM	MPB	Ver 1.0		28-8-05
;
;	Simple calculator 
;	Single digit input, two digit results
;	Integer handling only  
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

	PROCESSOR 16F877
;	Clock = XT 4MHz, standard fuse settings
	__CONFIG 0x3731

;	LABEL EQUATES	;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

	INCLUDE "P16F877A.INC"	


Char	EQU	30	; Display character code
Num1	EQU	31	; First number input
Num2	EQU	32	; Second number input
Result	EQU	33	; Calculated result
Oper	EQU	34	; Operation code store 
Temp	EQU	35	; Temporary register for subtract
Kcount	EQU	36	; Count of keys hit
Kcode	EQU	37	; ASCII code for key
Msd	EQU	38	; Most significant digit of result
Lsd	EQU	39	; Least significant digit of result
Kval	EQU	40	; Key numerical value

RS	EQU	1	; Register select output bit
E	EQU	2	; Display data strobe

; Program begins ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

	ORG	0		; Default start address 
	NOP			; required for ICD mode

	BANKSEL	TRISC		; Select bank 1
	MOVLW	B'11110000'	; Keypad direction code
	MOVWF	TRISC		;  
	CLRF	TRISD		; Display port is output

	BANKSEL PORTC		; Select bank 0
	MOVLW	0FF		; 
	MOVWF	PORTC		; Set keypad outputs high
	CLRF	PORTD		; Clear display outputs
	GOTO	start		; Jump to main program


; MAIN LOOP ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

start	CALL	inid		; Initialise the display
	MOVLW	0x80		; position to home cursor
	BCF	Select,RS	; Select command mode
	CALL	send		; and send code

	CLRW	Char		; ASCII = 0
	CLRW	Kval		; Key value = 0
	CLRW	DFlag		; Digit flags = 0

scan	CALL	keyin		; Scan keypad
	MOVF	Char,1		; test character code
	BTFSS	STATUS,Z	; key pressed?
	GOTO	keyon		; yes - wait for release
	GOTO	scan		; no - scan again

keyon	MOVF	Char,W		; Copy.. 
	MOVWF	Kcode		; ..ASCIIcode
	MOVLW	D'50'		; delay for..
	CALL	xms		; ..50ms debounce

wait	CALL	keyin		; scan keypad again
	MOVF	Char,1		; test character code
	BTFSS	STATUS,Z	; key pressed?
	GOTO	wait		; no - rescan
	CALL	disout		; yes - show symbol

	INCF	Kcount		; inc count..
	MOVF	Kcount,W	; ..of keys pressed
	ADDWF	PCL		; jump into table	
	NOP
	GOTO	first		; process first key
	GOTO	scan		; get operation key
	GOTO	second		; process second symbol
	GOTO	calc		; calculate result
	GOTO	clear		; clear display

first	MOVF	Kval,W		; store..
	MOVWF	Num1		; first num
	GOTO	scan		; and get op key

second	MOVF	Kval,W		; store..
	MOVWF	Num2		; second number 
	GOTO	scan		; and get equals key


; SUBROUTINES ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; Include LCD driver routine
	
	INCLUDE	"LCDIS.INC"


; Scan keypad .............................................

keyin	MOVLW	00F		; deselect..
	MOVWF	PORTC		; ..all rows
	BCF	PORTC,0		; select row A
	CALL	onems		; wait output stable

	BTFSC	PORTC,4		; button 7?
	GOTO	b8		; no
	MOVLW	'7'		; yes
	MOVWF	Char		; load key code
	MOVLW	07		; and
	MOVWF	Kval		; key value
	RETURN

b8	BTFSC	PORTC,5		; button 8?
	GOTO	b9		; no
	MOVLW	'8'		; yes	
	MOVWF	Char
	MOVLW	08
	MOVWF	Kval
	RETURN
	
b9	BTFSC	PORTC,6		; button 9?
	GOTO	bd		; no
	MOVLW	'9'		; yes
	MOVWF	Char
	MOVLW	09
	MOVWF	Kval
	RETURN
	
bd	BTFSC	PORTC,7		; button /?
	GOTO	rowb		; no
	MOVLW	'/'		; yes
	MOVWF	Char		; store key code
	MOVWF	Oper		; store operator symbol
	RETURN

rowb	BSF	PORTC,0		; select row B
	BCF	PORTC,1
	CALL	onems

	BTFSC	PORTC,4		; button 4?
	GOTO	b5		; no
	MOVLW	'4'		; yes
	MOVWF	Char
	MOVLW	04
	MOVWF	Kval
	RETURN
	
b5	BTFSC	PORTC,5		; button 5?
	GOTO	b6		; no
	MOVLW	'5'		; yes
	MOVWF	Char
	MOVLW	05
	MOVWF	Kval
	RETURN
	
b6	BTFSC	PORTC,6		; button 6?
	GOTO	bm		; no
	MOVLW	'6'		; yes
	MOVWF	Char
	MOVLW	06
	MOVWF	Kval
	RETURN
	
bm	BTFSC	PORTC,7		; button x?
	GOTO	rowc		; no
	MOVLW	'x'		; yes
	MOVWF	Char
	MOVWF	Oper
	RETURN

rowc	BSF	PORTC,1		; select row C
	BCF	PORTC,2
	CALL	onems

	BTFSC	PORTC,4		; button 1?
	GOTO	b2		; no
	MOVLW	'1'		; yes
	MOVWF	Char
	MOVLW	01
	MOVWF	Kval
	RETURN
		
b2	BTFSC	PORTC,5		; button 2?
	GOTO	b3		; no
	MOVLW	'2'		; yes
	MOVWF	Char
	MOVLW	02
	MOVWF	Kval
	RETURN
	
b3	BTFSC	PORTC,6		; button 3?
	GOTO	bs		; no
	MOVLW	'3'		; yes
	MOVWF	Char
	MOVLW	03
	MOVWF	Kval
	RETURN

bs	BTFSC	PORTC,7		; button -?
	GOTO	rowd		; no
	MOVLW	'-'		; yes
	MOVWF	Char
	MOVWF	Oper
	RETURN

rowd	BSF	PORTC,2		; select row D
	BCF	PORTC,3
	CALL	onems

	BTFSC	PORTC,4		; button C?
	GOTO	b0		; no	
	MOVLW	'c'		; yes
	MOVWF	Char
	MOVWF	Oper
	RETURN
		
b0	BTFSC	PORTC,5		; button 0?
	GOTO	be		; no
	MOVLW	'0'		; yes
	MOVWF	Char
	MOVLW	00
	MOVWF	Kval
	RETURN
	
be	BTFSC	PORTC,6		; button =?
	GOTO	bp		; no
	MOVLW	'='		; yes
	MOVWF	Char
	RETURN

bp	BTFSC	PORTC,7		; button +?
	GOTO	done		; no
	MOVLW	'+'		; yes
	MOVWF	Char
	MOVWF	Oper
	RETURN

done	BSF	PORTC,3		; clear last row
	CLRF	Char		; character code = 0
	RETURN


; Write display ...........................................

disout	MOVF	Kcode,W		; Load the code
	BSF	Select,RS	; Select data mode
	CALL	send		; and send code
	RETURN

; Process operations ......................................

calc	MOVF	Oper,W		; check for add
	MOVWF	Temp		; load input op code
	MOVLW	'+'		; load plus code
	SUBWF	Temp		; compare
	BTFSC	STATUS,Z	; and check if same
	GOTO	add		; yes, jump to op

	MOVF	Oper,W		; check for subtract 
	MOVWF	Temp
	MOVLW	'-'
	SUBWF	Temp
	BTFSC	STATUS,Z
	GOTO	sub

	MOVF	Oper,W		; check for multiply 
	MOVWF	Temp
	MOVLW	'x'
	SUBWF	Temp
	BTFSC	STATUS,Z
	GOTO	mul
	
	MOVF	Oper,W		; check for divide
	MOVWF	Temp
	MOVLW	'/'
	SUBWF	Temp
	BTFSC	STATUS,Z
	GOTO	div
	GOTO	scan		; rescan if key invalid


; Calclate results from 2 input numbers ...................
 
add	MOVF	Num1,W		; get first number
	ADDWF	Num2,W		; add second
	MOVWF	Result		; and store result
	GOTO	outres		; display result


sub	BSF	STATUS,C	; Negative detect flag
	MOVF	Num2,W		; get first number
	SUBWF	Num1,W		; subtract second
	MOVWF	Result		; and store result
	
	BTFSS	STATUS,C	; answer negative?
	GOTO	minus		; yes, minus result
	GOTO	outres		; display result

minus	MOVLW	'-'		; load minus sign	
	BSF	Select,RS	; Select data mode
	CALL	send		; and send symbol

	COMF	Result		; invert all bits
	INCF	Result		; add 1
	GOTO	outres		; display result


mul	MOVF	Num1,W		; get first number
	CLRF	Result		; total to Z
add1	ADDWF	Result		; add to total
	DECFSZ	Num2		; num2 times and
	GOTO	add1		; repeat if not done
	GOTO	outres		; done, display result


div	CLRF	Result		; total to Z
	MOVF	Num2,W		; get divisor
	BCF	STATUS,C	; set C flag
sub1	INCF	Result		; count loop start
	SUBWF	Num1		; subtract 
	BTFSS	STATUS,Z	; exact answer?
	GOTO	neg		; no
	GOTO	outres		; yes, display answer
neg	BTFSC	STATUS,C	; gone negative?
	GOTO	sub1		; no - repeat
	DECF	Result		; correct the result
	MOVF	Num2,W		; get divisor
	ADDWF	Num1		; calc remainder

	MOVF	Result,W	; load result
	ADDLW	030		; convert to ASCII
	BSF	Select,RS	; Select data mode
	CALL	send		; and send result

	MOVLW	'r'		; indicate remainder
	CALL	send
	MOVF	Num1,W
	ADDLW	030		; convert to ASCII	
	CALL	send
	GOTO	scan


; Convert binary to BCD ...................................

outres	MOVF	Result,W	; load result
	MOVWF	Lsd		; into low digit store
	CLRF	Msd		; high digit = 0
	BSF	STATUS,C	; set C flag
	MOVLW	D'10'		; load 10

again	SUBWF	Lsd		; sub 10 from result
	INCF	Msd		; inc high digit
	BTFSC	STATUS,C	; check if negative
	GOTO	again		; no, keep going
	ADDWF	Lsd		; yes, add 10 back 
	DECF	Msd		; inc high digit


; display 2 digit BCD result ..............................

	MOVF	Msd,W		; load high digit result
	BTFSC	STATUS,Z	; check if Z
	GOTO	lowd		; yes, dont display Msd

	ADDLW	030		; convert to ASCII
	BSF	Select,RS	; Select data mode
	CALL	send		; and send Msd

lowd	MOVF	Lsd,W		; load low digit result
	ADDLW	030		; convert to ASCII
	BSF	Select,RS	; Select data mode
	CALL	send		; and send Msd

	GOTO	scan		; scan for clear key
	

; Restart ................................................

clear	MOVLW	01		; code to clear display
	BCF	Select,RS	; Select data mode
	CALL	send		; and send code	
	CLRF	Kcount		; reset count of keys
	GOTO	scan		; and rescan keypad


	END	;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

⌨️ 快捷键说明

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