Sida 1 av 1

Subrutin återvänder till toppen, inte dit den anropades

Postat: 24 mars 2009, 11:47:14
av PopUnoNkoK
Jag har två subrutiner, en delay och en med ett Lysdiods mönster.
Anledningen till att lysdiods mönstret är i en subrutin är att jag har tänkt att ha flera olika mönster. (det ska bli en 9pixlars tavla)

När jag började hade jag Mönstret i huvudkoden, alltså inte i en subrutin och då fungerade det perfekt. När jag nu lagt den i en subrutin så körs den bara en gång och sedan stannar alla dioder i lysande läge.
När jag kör koden i MPLAB Sim så funkar allt fint till "return" instruktionen i monster_1 subrutinen. Då hoppar den tillbaka till toppen av koden, alldeles från början.

Någon som förstår vad jag menar?

Koden:

Kod: Markera allt

      	processor   16f628a
  	   	include      <p16f628a.inc>
		__config	_INTOSC_OSC_NOCLKOUT & _WDT_OFF & _PWRTE_ON & _LVP_OFF


	   	banksel 	TRISB			;select bank 1
	   	movlw 		b'00000000'		;set PortB all outputs
	   	movwf 		TRISB
		movwf		TRISA			;set PortA all outputs
		banksel 	PORTA			;select bank 0
		clrf		PORTA
		clrf		PORTB			;set all outputs low

		cblock		H'20'
					d1
					d2
					d3
		endc

Start
		goto		monster_1
        goto		Start

;-------- Subrutiner -------------------

monster_1
		movlw       b'11111111'
		movwf		PORTB
        call      	Delay
		movlw       b'11111110'
		movwf		PORTB
        call      	Delay
		movlw       b'11111100'
		movwf		PORTB
        call      	Delay
		movlw       b'11111000'
		movwf		PORTB
        call      	Delay
		movlw       b'11110000'
		movwf		PORTB
        call      	Delay
		movlw       b'11100000'
		movwf		PORTB
        call      	Delay
		movlw       b'11000000'
		movwf		PORTB
        call      	Delay

		nop
		return





Delay
; Delay = 0.5 seconds
; Clock frequency = 4 MHz

; Actual delay = 0.5 seconds = 500000 cycles
; Error = 0 %
;499994 cycles
	movlw	0x03
	movwf	d1
	movlw	0x18
	movwf	d2
	movlw	0x02
	movwf	d3
Delay_0
	decfsz	d1, f
	goto	$+2
	decfsz	d2, f
	goto	$+2
	decfsz	d3, f
	goto	Delay_0

			;6 cycles
	goto	$+1
	goto	$+1
	goto	$+1

	nop
	return


		nop
		end

Re: Subrutin återvänder till toppen, inte dit den anropades

Postat: 24 mars 2009, 11:50:44
av Icecap
En "goto" är INTE ett subrutin-kall, det är "call" som gör det!

Re: Subrutin återvänder till toppen, inte dit den anropades

Postat: 24 mars 2009, 11:53:48
av PopUnoNkoK
Åh vad jag blir trött på mig själv.

Tackar och bockar för det snabba svaret.

MVH Peter F

Re: Subrutin återvänder till toppen, inte dit den anropades

Postat: 24 mars 2009, 12:14:48
av bos
Om man som du gjorde, använde goto för att anropa en subrutin, så kommer anropsstacken, med returadresser, att vara tom eftersom goto till skillnad från call inte lägger någon återhoppsadress där. När return exekveras så fås adressen "00000000" från stacken (eftersom den är tom / nollställd), vilket gör att processorn hoppar till adress 0, vilket låter den köra om allt från början.

I det här lätta kodexemplet är det lätt att inse, men har du nästlade calls innan du gör din sista goto så blir det en ytterst hårig bugg att leta.

Re: Subrutin återvänder till toppen, inte dit den anropades

Postat: 24 mars 2009, 12:26:17
av Swech
Höj snäppet lite och labba lite med de inbyggda timers som finns.
Så slipper du ha mjukvarufördröjningar.. ryyyysss....

Swech

Re: Subrutin återvänder till toppen, inte dit den anropades

Postat: 24 mars 2009, 14:15:41
av PopUnoNkoK
Hehe...

Swech: Så du menar att mjukvarudelays som är genererade på en hemsida inte är det allra vassaste sättet. :D

Näe jag vet att det inte är så snyggt. Jag har läst Elmer 160, kapitel 13 (timer) idag men det gick lite segt. Men det kommer.

Jag ställer en liten fråga här får vi se om jag får nåt svar:
Jag har lyckats dimma en diod och kan i koden ställa den till vilken procentuella styrka jag vill. Nu vill jag kunna Dimmra den upp och ner Alltså att den pendlar mellan 0% och 100%.
Jag har detklart i huvudet men fastnar bla på att denna instruktion inte gör som jag vill:

Kod: Markera allt

		movlw       d'2'
		movwf		dim0_orgi

		movlw       dim0_orgi
		movwf		dim0
Den lägger förståss "2" i dim0_orgi men i dim0 lägger den "38".
dim0 är den tid som dioden är tänd, och så har jag tänkt använda dim0_orgi för att succesivt öka tiden som den är tänd.

MVh Peter

Re: Subrutin återvänder till toppen, inte dit den anropades

Postat: 24 mars 2009, 14:22:58
av PopUnoNkoK
MOVF ska de juh vara... Tacka vet jag databladet. =)

Tur att jag hant svara sjhälv innan någon annan

Re: Subrutin återvänder till toppen, inte dit den anropades

Postat: 24 mars 2009, 14:37:24
av sodjan
Du vill alltså ha samma värde i båda registren ?

movlw d'2'
movwf dim0_orgi
movwf dim0

Du behöver inte "ladda om" W mellan de två MOVWF...