Subrutiner - AVR

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
Användarvisningsbild
Limen
EF Sponsor
Inlägg: 1195
Blev medlem: 23 november 2006, 18:34:28
Ort: En bit utanför Karlstad

Subrutiner - AVR

Inlägg av Limen »

Hur använder man subrutiner i AVR (asm)?
Försöker med en liten testsnutt:

Kod: Markera allt

	RJMP	main

main:
	LDI	R16,0xFF
	OUT	DDRB,R16
loop:
	LDI	R16,0x00
	OUT	PORTB,R16
	RCALL	delay
	LDI	R16,0xFF
	OUT	PORTB,R16
	RCALL	delay
	RJMP	loop

delay:
	LDI	R17,0xFF
delay_2:
	SUBI	R17,0x01
	BRNE	delay_2
	RET
Men den återvänder inte från subrutinen utan hoppar istället tillbaka till "RJMP main". Vad har jag missat?
Användarvisningsbild
oJsan
EF Sponsor
Inlägg: 1541
Blev medlem: 11 november 2005, 21:36:51
Ort: Umeå
Kontakt:

Inlägg av oJsan »

Förmodligen så har du glömt att initiera stacken. Återhoppsadressen från subrutinen sparas nämligen där. Kan inte på rak arm svara på hur du initierar den men det finns nog i många färdiga asm/AVR-exempel

Edit:

Kod: Markera allt

*Följande kod placerar stackpekaren längst ner i RAM.
	.include "m16def.inc" //Eller motsvarande...
	ldi	r16,low(RAMEND)
	out	SPL,r16
	ldi	r16,high(RAMEND)
	out	SPH,r16
Senast redigerad av oJsan 6 februari 2007, 23:23:46, redigerad totalt 1 gång.
Användarvisningsbild
Limen
EF Sponsor
Inlägg: 1195
Blev medlem: 23 november 2006, 18:34:28
Ort: En bit utanför Karlstad

Inlägg av Limen »

Aha måste den initieras manuellt. Ska man dedikera ett register till detta är det tänkt?
Användarvisningsbild
Micke_s
EF Sponsor
Inlägg: 6741
Blev medlem: 15 december 2005, 21:31:34
Ort: Malmö

Inlägg av Micke_s »

Vid push och pop så flyttas den.
R16 används bara som temp lagring.
SPH och SPL är redan dedikerad i hårdvaran.
Användarvisningsbild
Limen
EF Sponsor
Inlägg: 1195
Blev medlem: 23 november 2006, 18:34:28
Ort: En bit utanför Karlstad

Inlägg av Limen »

Måste man ange R16 eller funkar det med vilket som? (16-31)
Användarvisningsbild
oJsan
EF Sponsor
Inlägg: 1541
Blev medlem: 11 november 2005, 21:36:51
Ort: Umeå
Kontakt:

Inlägg av oJsan »

Det fungerar med vilken register som helst av samma typ. Operationen är ungefär samma som när du gör:

Kod: Markera allt

   LDI   R16,0xFF
   OUT   DDRB,R16
Först lägger man data (0xFF) till ett dataregister och sedan skriver man registret till ett specifikt hårdvaruregister (SPL/SPH/PORTB/DDRB/etc.).
Användarvisningsbild
Limen
EF Sponsor
Inlägg: 1195
Blev medlem: 23 november 2006, 18:34:28
Ort: En bit utanför Karlstad

Inlägg av Limen »

Aha då förstår jag. Tack för hjälpen!
Skriv svar