logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

Błąd w kodzie ASM kalkulatora 8051: niepoprawne wartości w akumulatorze

Chrupeq 09 Kwi 2012 20:05 2458 1
REKLAMA
  • #1 10776007
    Chrupeq
    Poziom 11  
    Posty: 62
    Ocena: 2
    Witam posiadam taki problem związany z kodem asm. Według kodu wszystko powinno działać od razu a jednakże przy symulowaniu programu w ISIS gdy wcisnę liczbę 3 razy a potem kolejna liczbę którą chce dodać 2 razy dopiero otrzymuje poprawny wynik. Zauważyłem że gdy wcisnę na klawiaturze jaką kol wiek liczbę Akumulator jakby inną wartość łapał i dla pierwszej liczby jest to 7 a dla drugiej 3, lecz wyświetla poprawną wartość na LCD.

    
    $Mod52
    START:
    
    EN EQU P3.7
    RS EQU P3.5
    RW EQU P3.6
    DAT EQU P2
    TEMP0 EQU 60H
    TEMP1 EQU 61H
    FLAG EQU R7
    INPUTKEY EQU 32H
    ORG 00H
    LCALL INIT_LCD
    MOV 40h,#00h
    MOV 41h,#00h
    MOV A,#00h
    MOV r0,#00h
    MOV r1,#00h
    MOV r2,#00h
    MOV r3,#00h
    MOV r4,#00h
    MOV r5,#00h
    MOV r6,#00h
    MOV r7,#00h
    MOV 52H,#0H
    MOV 51H,#0H
    MOV 50H,#0H
    
    
    keyup:
    	LCALL Keyboard 
    	CJNE A,#0FFH,keyup
    
    readkey:
    	LCALL Keyboard
    	CJNE A,#0FFH,keypressed
    	SJMP readkey
    keypressed:
    	MOV r5,A
    	LCALL GetKeyNumHEX
    	MOV 40H,A
    	MOV A,r5
    	LCALL GetKeyNum
    	CJNE A,#'C', ON
    CLEAR:	
    	LCALL CLEAR_LCD
    	LJMP START
    ON:	
    	CJNE R3,#02H,PLUS
    	LJMP SIG
    PLUS:	
    	INC R3
    	CJNE A,#'+',MINUS
    	LJMP SIG
    MINUS:
    	CJNE A,#'-',MULTIPLY
    	LJMP SIG
    MULTIPLY:
    	CJNE A,#'x',SUBSTRACT
    	LJMP SIG
    SUBSTRACT:
    	CJNE A,#'/',NOOPERATOR
    	LJMP SIG
    NOOPERATOR:
    	LCALL WRITE_TEXT
    	LJMP KEYUP
    SIG:
    	LCALL Keyboard
    	CJNE A,#0FFH,SIGN
    	SJMP SIG
    SIGN:
    	MOV INPUTKEY,A
    	LCALL GetKeyNum
    	CJNE A,#'C',SIGNN
    	SJMP CLEAR
    SIGNN:
    	CJNE A,#'+',NOTADD
    	LCALL WRITE_TEXT
    	MOV FLAG,#01H
    	LCALL SECNUM
    NOTADD:
    	CJNE A,#'-',NOTMIN
    	LCALL WRITE_TEXT
    	MOV FLAG,#02H
    	;LCALL MINUS
    NOTMIN:
    	SJMP SIG
    SECNUM:
    	LCALL Keyboard
    	CJNE A,#0FFH,SECNUM
    SECNUMM:
    	LCALL Keyboard
    	CJNE A,#0FFH,SECNUMMM
    	SJMP SECNUMM
    SECNUMMM:
    	MOV R6,A
    	LCALL GetKeyNumHEX
    	MOV 41H,A
    	MOV A,R6
    	LCALL GetKeyNum
    	INC R4
    	CJNE A,#'C',SECNUMMMM
    	SJMP CLEAR
    SECNUMMMM:
    	CJNE A,#'=',ONEDIGI
    	SJMP EQUALLLL
    ONEDIGI:
    	LCALL WRITE_TEXT
    	CJNE A,#'C',NEXT
    	SJMP CLEAR
    NEXT:
    	CJNE R4,#02H,SECNUM
    EQUAL:
    	LCALL Keyboard
    	CJNE A,#0FFH,EQUAL
    EQUALL:
    	LCALL Keyboard
    	CJNE A,#0FFH,EQUALLL
    	SJMP EQUALL
    EQUALLL:	
    	LCALL GetKeyNum
    	CJNE A,#'=',EQUAL
    EQUALLLL:
    	LCALL WRITE_TEXT
    	
    	LCALL ADITION
    	LCALL HEXTOASCII
    	mov a, 52h
    	lcall write_text
    	mov a, 51h
    	lcall write_text
    	mov a, 50h
    	lcall write_text
    FINISH:	
    	LCALL Keyboard
    	CJNE A,#0FFH,FINISH
    FINCLR:	
    	LCALL Keyboard
    	CJNE A,#0FFH,CLRFIN
    	SJMP FINCLR
    CLRFIN:	
    	LCALL GetKeyNum
    	CJNE A,#'C',FINISH
    	LJMP CLEAR
    ;SUBRUTINES
    ADITION:
    
    
    MOV A,40H
    ADD A,41H
    RET
    
    hextoascii:
    	
    	mov 50h,#30h
    	mov 51h,#30h
    	mov 52h,#30h	
    	cjne a,#00h,c1_hextobcd 	;//check if number is 0 if not then continue
    	ret 	
    c1_hextobcd:
    	
    
    	clr c
    	mov b,#100	;//divide by 100
    	div ab
    	orl a,52h
    	;LCALL WRITE_TEXT
    	mov 52h,a	;//save 100th place in R0
    	clr c
    	mov a,b
    	mov b,#10	;//Divide by 10
    	div ab
    	orl a,51h
    	;LCALL WRITE_TEXT
    	mov 51h,a	;//Save 10th place in R1
    	mov a,b
    	orl a,50h
    	;LCALL WRITE_TEXT
    	mov 50h,a	;//Save  units place in R2
    	ret
    
    INIT_LCD:
    	CLR RS
    	MOV DAT,#38h
    	SETB EN
    	CLR EN
    	LCALL WAIT_LCD
    	CLR RS
    	MOV DAT,#0Eh
    	SETB EN
    	CLR EN
    	LCALL WAIT_LCD
    	CLR RS
    	MOV DAT,#06h
    	SETB EN
    	CLR EN
    	LCALL WAIT_LCD
    	RET
    
    WAIT_LCD:
    	MOV DAT, #0FFh
    	CLR EN
    
    	CLR RS
    	SETB RW
    	SETB EN
    	NOP
    
    	MOV A, DAT
    	CLR EN
    	CLR RW
    
    	JB ACC.7, WAIT_LCD
    	RET
    
    CLEAR_LCD:
    	CLR RW
    	CLR RS
    	MOV DAT,#01h
    	SETB EN
    	CLR EN
    	LCALL WAIT_LCD
    	RET
    	
    WRITE_TEXT:
    	SETB RS
    	MOV DAT,A
    	SETB EN
    	CLR EN
    	LCALL WAIT_LCD
    	RET
    
    
    Keyboard:
    	MOV P1,#0F0H
    	LCALL ShortDelay
    	MOV A,P1
    	CJNE A,#0F0H,scanrows
    	MOV A,#0FFH
    	SJMP ret_keyboard
    scanrows:
    	MOV R0,#4
    	MOV R1,#11101111B; p2.4 is first row so we should start [scan] from first.
    nextrow:
    	MOV A,R1
    	RR A
    	MOV R1,A
    	MOV P1,A
    	LCALL ShortDelay
    	MOV A,P1
    	ANL A,#0F0H
    	CJNE A,#0F0H,findcol
    	DJNZ R0,nextrow
    	MOV A,#0FFH
    	SJMP ret_keyboard
    findcol:
    	MOV R2,#0
    nextcol:
    	CLR C
    	RLC A
    	JNC calculate
    	INC R2
    	SJMP nextcol
    calculate:
    	CLR C
    	MOV A,#4
    	SUBB A,R0
    	MOV B,#4
    	MUL AB
    	ADD A,R2 ; r=4(row)+(col)
    ret_keyboard:
    	RET
    
    GetKeyNumHEX:
    	MOV DPTR,#HEK
    	MOVC A,@A+DPTR
    	RET
    HEK:	DB 7d,4d,1d,1d,8d,5d,2d,2d,9d,6d,3d,3d,4d,5d,6d,7d
    
    GetKeyNum:
    	MOV DPTR,#key
    	MOVC A,@A+DPTR
    	RET
    key:	DB '7','4','1','C','8','5','2','0','9','6','3','=','/','x','-','+'
    
    
    
    ShortDelay:
    	MOV TEMP0,#20
    shortloop:
    	MOV TEMP1,#20
    	DJNZ TEMP1,$
    	DJNZ TEMP0,shortloop
    	RET
    ENDD:
            LCALL CLEAR_LCD
    	END
    


    Lukasz
    Dzieki za pomoc
  • REKLAMA
  • #2 17131796
    jacki123456789
    Poziom 9  
    Posty: 37
    Ocena: 2
    Na razie dam wskazówkę, bo chwilowo nie mam czasu analizować programu ani nie mam sprzętu żeby go sprawdzić, ale pamiętaj że wszystkie procedury, wypisywanie na LCD itp zmieniają wartość w akumulatorze więc po wczytaniu danych wywalaj je do jakiegoś wolnego rejestru, a wczytuj bezpośrednio przed wykonaniem działania.
REKLAMA