PIC beter sig totalt ologiskt

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
pucko
Inlägg: 29
Blev medlem: 16 oktober 2006, 18:49:09

PIC beter sig totalt ologiskt

Inlägg av pucko »

Hej jag har en PIC16F84A. I följlande kod/main lop anropar jag subrutinen delay allara först. Då fungerar det som det ska. Men om jag anropar delay sist i lopen strax innan goto main_loop då fungerar det inte som det ska. Det är nämligen så att jag har en timer interrupt i bakgrunden och när det inte fungerar som det ska beter sig programmet som om jag skulle nollställa prescalervärdet. Dvs timern går jättesnabbt.

Finns det någon möjlighet för er att förstå varför baserat på denna info?

Ser liksom inte logiken i varför det skulle bli skillnad om jag placerar call delay allra först eller näst sist. Sekventiellt så är det ju samma sak bortsett från en goto som inte borde inverka ett dugg.


Tack...

Kod: Markera allt

main_loop
		call delay	
		banksel TRISB		

		movlw 0xF0					;get column
		movwf TRISB					;high 4 bits in, low 4 bits out
		
		banksel PORTB				
		
		movwf PORTB					;send out 0xF0 on portb to determine column
		movf PORTB,w				;put value on portb in w
		movwf keyboard_value		;save it in keyboard_value
		movlw	0xF0				
		subwf keyboard_value,w			
		btfsc STATUS,Z 				;check if keyboard_value is different from idle state
		goto main_loop		

		call delay					;delay to be sure the value read is correct and stable to prevent bounce effect

		movf PORTB,w				;read again				
		movwf keyboard_value		
		movlw	0xF0				
		subwf keyboard_value,w			
		btfsc STATUS,Z 				
		goto main_loop		

		banksel TRISB

		movlw 0x0F					;get row
		movwf TRISB					;high 4 bits out, low 4 bits in
		
		banksel PORTB

		movf keyboard_value,w						
		movwf PORTB					;put keyboard_value on portb to determine row
		movf PORTB,w
		movwf keyboard_value		;save combined row colum in keyboard_value
	

;special characters for start and stop

VB7		;#
		movlw 0xB7					
 		subwf keyboard_value,w
		btfss STATUS,Z				;is keyboard value = b7 = start_clock?
		goto VE7					;no, check if it is = stop_clock
		movlw .2					;yes, now check if a digit for the display has already been entered
		subwf main_counter,w
		btfss STATUS,Z
		goto prep_vb7_goto_invalid	;if so, then start_clock should not be entered as value for second digit, therefore error
		call start_clock			;if not, then it is ok to call start_clock
		incf main_counter,f			;since value for display has not been entered increment it because in main_loop_prep_end it will be decremented and it will remain
		goto main_loop_prep_end
		
prep_vb7_goto_invalid				;this increments main_counter so that in the invalid state when main_counter is 1 it is not decremented to 1 again before next loop
		incf main_counter,f
		goto invalid				
		
;allowed digits

VE7		;*							
		movlw 0xE7
 		subwf keyboard_value,w
		btfss STATUS,Z
		goto VEE
		movlw .2
		subwf main_counter,w
		btfss STATUS,Z
		goto prep_ve7_goto_invalid
		bsf PORTA,3					;kill noise
		call stop_clock
		incf main_counter,f
		goto main_loop_prep_end

prep_ve7_goto_invalid
		incf main_counter,f
		goto invalid

VEE		;1
		DECODE_DIGIT_JUMP	0xEE, VDE, 0x01, load_one_vee, load_ten_vee, main_loop_prep_end						

VDE		;2		
		DECODE_DIGIT_JUMP 0xDE, VBE, 0x02, load_one_vde, load_ten_vde, main_loop_prep_end

VBE		;3
		DECODE_DIGIT_JUMP 0xBE, VED, 0x03, load_one_vbe, load_ten_vbe, main_loop_prep_end

VED		;4
		DECODE_DIGIT_JUMP 0xED, VDD, 0x04, load_one_ved, load_ten_ved, main_loop_prep_end

VDD		;5
		DECODE_DIGIT_JUMP 0xDD, VBD, 0x05, load_one_vdd, load_ten_vdd, main_loop_prep_end 

VBD		;6
		DECODE_DIGIT_JUMP 0xBD, VEB, 0x06, load_one_vbd, load_ten_vbd, main_loop_prep_end

VEB		;7
		DECODE_DIGIT_JUMP 0xEB, VDB, 0x07, load_one_veb, load_ten_veb, main_loop_prep_end

VDB		;8
		DECODE_DIGIT_JUMP 0xDB, VBB, 0x08, load_one_vdb, load_ten_vdb, main_loop_prep_end

VBB		;9
		DECODE_DIGIT_JUMP 0xBB, VD7, 0x09, load_one_vbb, load_ten_vbb, main_loop_prep_end

VD7		;0
		DECODE_DIGIT_JUMP 0xD7, invalid, 0x00, load_one_vd7, load_ten_vd7, main_loop_prep_end



invalid							;end up here if invalid number value or start and stop buttons are pressed as second digit
		incf main_counter,f
		clrf one_minutes
		clrf ten_minutes
		
main_loop_prep_end
		call serial_output
		decfsz main_counter,f
		goto main_loop_end
		bsf clock_set,0
		movlw .2
		movwf main_counter

main_loop_end

key_release_loop					;waits on till keyboard key pressed is released
		movlw 0x0F
		movwf PORTB
		subwf PORTB,W
		btfss STATUS,Z
		goto key_release_loop


		goto main_loop
pheer
EF Sponsor
Inlägg: 1283
Blev medlem: 16 januari 2005, 18:05:21

Inlägg av pheer »

posta delay-koden, pucko!
Användarvisningsbild
Chribbe76
EF Sponsor
Inlägg: 1167
Blev medlem: 17 januari 2004, 22:43:17
Ort: Stockholm

Inlägg av Chribbe76 »

Jag vill se hela koden.

Fungerar det korrekt i simulatorn?

[EDIT] Välkommen till forumet pucko!
Användarvisningsbild
$tiff
Inlägg: 4941
Blev medlem: 31 maj 2003, 19:47:52
Ort: Göteborg
Kontakt:

Inlägg av $tiff »

pheer skrev:posta delay-koden, pucko!
:rofl :rofl :rofl
Användarvisningsbild
Zyxel615
EF Sponsor
Inlägg: 1839
Blev medlem: 9 november 2005, 21:20:43
Ort: Kiruna

Inlägg av Zyxel615 »

Välkommen till forumet!
pheer skrev:posta delay-koden, pucko!
Ja jag hajade till först och undrade "värst vad stickslig han var idag då" :lol: :lol:
Användarvisningsbild
Abra Hana
Inlägg: 94
Blev medlem: 12 maj 2005, 13:20:58

Inlägg av Abra Hana »

*

**** Mitt program fungerar inte som den ska när jag placerar delay subrutine strax förre go to main_Loop men den fungerar som den ska när jag placerar den efter main_loop .



Jag utgår ifrån att ditt program kompileras utan fel ! . och att delay subrutin är korrekt .

Om jag är dig skulle jag instinktivt försöka lösa problemet så här .

1) Det är många anropp av " goto " instruction i ditt program .
kolla om programmet hänger sig innan någon av dessa anropp så att
programmet når aldrig till delay subrutine som finns strax förre
sista "goto main_loop" .

2) Kolla om någon av de flera instruction " btfss btfsc" uppfyller dem
kraven som behövs .

3) Och sist inte minst . kolla watch dog timer ( WDT ) , det kan hända att
den slår om innan innan exekvering av delay subrutin som finns starx
förre " sista goto main_loop "
WDT slår om ==> PIC startar om ( gör en Reset ) .

*
pucko
Inlägg: 29
Blev medlem: 16 oktober 2006, 18:49:09

Inlägg av pucko »

Tack för svaren....

Har svårt att tro att WDT går igång då jag stängt av den i OPTION_REG i init. Om den hade varit på så hade jag inte kunna få programmet att fungera annars heller eftersom jag inte uppdaterar WDT någonstans.

Det där med gotos. Strax innan goto main_loop så finns det en key_release_loop som man vet att man är i eftersom så fort jag släpper upp knappen så springer timern iväg. Medan jag håller in knappen i key_release_loopen så går klockan/timern som den ska då jag hunnit enabla timer interrupt i det läget.

Så här ser delaykoden ut:

Kod: Markera allt


delay
               PUSH3
wait
                movlw 0x64
                movwf w_loop3

wait_loop3
                movlw 0x64
                movwf w_loop2

wait_loop2
                movlw 0x0A
                movwf w_loop1

wait_loop1
                decfsz w_loop1,f
                goto wait_loop1
                decfsz w_loop2,f
                goto wait_loop2
                decfsz w_loop3,f
                goto wait_loop3
                POP3
                return
pheer
EF Sponsor
Inlägg: 1283
Blev medlem: 16 januari 2005, 18:05:21

Inlägg av pheer »

Enklast är nog att debugga med hjälp av simulatorn i MPLAB eller i PIC Simulator IDE
Skriv svar