PIC, ASM. Frågetecken kring delayrutiner

PIC, AVR, Arduino, Raspberry Pi, Basic Stamp, PLC mm.
Användarvisningsbild
JimmyAndersson
Inlägg: 26586
Blev medlem: 6 augusti 2005, 21:23:33
Ort: Oskarshamn (En bit utanför)
Kontakt:

PIC, ASM. Frågetecken kring delayrutiner

Inlägg av JimmyAndersson »

Det gäller inte specifikt delayrutiner, men jag brukar få felet där.

Jag får följande meddelande:

"MPLINK 4.11, Linker
Copyright (c) 2007 Microchip Technology Inc.
Error - file 'G:\PIC\ASM\PIC18LF1320\UV-box\uvbox.o', section 'DLY_CODE', Symbol '_DLY_CODE_0036' is not word-aligned.
It can not be used as the target of a call or goto instruction.
Errors : 1"



En titt på delay-koden:

Kod: Markera allt

;Delay-rutiner

DLY_VARS	UDATA_ACS
d1			RES 1
d2			RES 1
d3			RES 1

DLY_CODE	CODE

;Delay 1 sek.
Delay_1s
	movlw	0x5A
	movwf	d1
	movlw	0xCD
	movwf	d2
	movlw	0x16
	movwf	d3
Delay_1s_0
	decfsz	d1, f
	goto	$+2
	decfsz	d2, f
	goto	$+2
	decfsz	d3, f
	goto	Delay_1s_0
	nop
	return


; Delay 5 ms.
Delay_5ms
	movlw	0x0E
	movwf	d1
	movlw	0x28
	movwf	d2
Delay_5ms_0
	decfsz	d1, f
	goto	$+2
	decfsz	d2, f
	goto	Delay_5ms_0
	goto	$+1
	nop
	return


; Delay 1 us.
Delay_1us
	movlw	0xC6
	movwf	d1
	movlw	0x01
	movwf	d2
Delay_1us_0
	decfsz	d1, f
	goto	$+2
	decfsz	d2, f
	goto	Delay_1us_0
	goto	$+1
	nop
	return
(Tabbarna blev lite skeva när jag klistrade in koden..)


Jag har testat att byta "goto" till "bra". Har även testat att allokera variablerna till olika delar av minnet, men inget av det har löst problemet.


Men på den här sajten så hittade jag detta:

"For PIC18, this delay routine will need a little modification to work properly.. the goto $+1 within the delay loops that sometimes appears needs to be changed to goto $+6, since each program word is 2 bytes, and goto is a 4 byte instruction. Also, at the end sometimes goto $+1 is used as a 2 cycle delay, need to use goto $+4 to skip over the whole goto."


Jag får inte ihop matten där riktigt, varför $+1 ska ändras till $+6 och $+1 ska ändras till $+4.
Det fungerar när jag ändrar, men känns just nu lite för osäkert att bara ändra utan att till 100% hänga med på varför just $+6 och $+4 fungerar.


Någon som kan räta ut min rynkade panna? :)


edit: Hoppsan.. 02:40.. Skulle ha lagt mig för tre timmar sedan, men det är lätt att fastna när man har kul. :)
bearing
Inlägg: 11676
Blev medlem: 2 mars 2006, 01:01:45
Ort: Ängelholm

Re: PIC, ASM. Frågetecken kring delayrutiner

Inlägg av bearing »

Varje instruktion är minst 1 word / 2 bytes stor vilket gör att programhopp måste ske i steg av 2. Antagligen kan programräknaren i PIC18 adressera minnet på byte-nivå, vilket gör att goto $+1 (om möjligt) flyttar programpekaren till "mitt i" GOTO-instruktionen. Om det skulle fungera kommer nästa instruktion bli det som ligger i mitten av GOTO-blocket, vilket antagligen är skräp (blir NOP?), men skulle kunna vara en tillåten instruktion.

GOTO-instruktionen är 2 words / 4 bytes, vilket gör att adressen för nästa instruktion ligger 4 bytes bort. Jag förstår dock inte varför $+1 ska ersättas med $+6, så jag gissar att det är en felskrivning; $+4 ska det vara. $+2 ska sannolikt ersättas med $+6 dock (om instruktionen efter GOTO är 2-bytes stor).
Användarvisningsbild
Swech
EF Sponsor
Inlägg: 4750
Blev medlem: 6 november 2006, 21:43:35
Ort: Munkedal, Sverige (Sweden)
Kontakt:

Re: PIC, ASM. Frågetecken kring delayrutiner

Inlägg av Swech »

Är det inte bättre att använda riktiga labels istället för massa $+x?
Då blir det inte beroende på processormodell low-mid range osv,

Det blir lättare att läsa programmet också

P.s. sen bör man snart ta fram en lag inom EU att mjukvarufördröjningar förbjuds :wink:
Allvarligt, sluta lära ut detta som en metod att få processorer att vänta en stund,
Det är ok upp till ett par ms men inte mer. Vid längre tider bör (läs SKA) de inbyggda timers användas

Swech
Användarvisningsbild
vfr
EF Sponsor
Inlägg: 3515
Blev medlem: 31 mars 2005, 17:55:45
Ort: Kungsbacka

Re: PIC, ASM. Frågetecken kring delayrutiner

Inlägg av vfr »

Det är ok upp till ett par ms men inte mer. Vid längre tider bör (läs SKA) de inbyggda timers användas


Absolut!

Helt klart också att dessa $+x är en styggelse. Tyvärr drar man på sig massor av problem med såna lösningar. Lablar är en mycket renare lösning som funkar i alla lägen.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: PIC, ASM. Frågetecken kring delayrutiner

Inlägg av sodjan »

En PIC16 (som koden var generad till) adresserar flash i 14-bitars "bitar".
D.v.s att $+1 stegar fram 14-bitar (eller ett "word"). Det finns inget
sett att direkt adressera delar av ett word.

En PIC18 har en programräknare som räknar *BYTES*. Normalt hålls
alltid bit0 = "0" så att adresseringen sker i hela words. Däremot t.ex
indexregister och adressregister för direkt flash-läsning kan adressera
bytes, vilket gör flash-tabeller effektivare (kompaktare) på en PIC18
(alla 16-bitar används) än på en PIC16 (8 bitar av 14 används). Det
gör också att man behöver $+2 för att stega ett word framåt.

En anledning till att använda $+n i delay rutinerna är att man kan
automatgenerera två (eller flera) och använda dom direkt utan att få
"multiple defined label"... :-)
Användarvisningsbild
vfr
EF Sponsor
Inlägg: 3515
Blev medlem: 31 mars 2005, 17:55:45
Ort: Kungsbacka

Re: PIC, ASM. Frågetecken kring delayrutiner

Inlägg av vfr »

Jag är helt med på användningen i t.ex makron och liknande. Dom flesta verktyg brukar ha något sätt att lösa även detta. T.ex någon form av temporära lablar. Nu har jag inte kollat vad just MPAsm klarar av, men jag tycker det vore konstigt om den inte kan lösa det. Det är en rätt vanlig funktion i en modern assembler. Och, som sagt, så ger det en massa fördelar att slippa dessa PC-relativa destinationer.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: PIC, ASM. Frågetecken kring delayrutiner

Inlägg av sodjan »

Nu så var detta inte macron, men i macron kan man ha "local" symboler så
att samma symbol kan användas i flera expansioner av macrot (och en
gång utanför macrot).

Se "4.44 local - DECLARE LOCAL MACRO VARIABLE" i MPASM manualen.

Utanför/utan macron kan man få samma effekt genom att placera koden
i olika moduler (ASM filer) vilka alla har ett eget lokalt name-space (förrutom
de symboler som hanteras via global/extern direktiven).

Man måste komma ihåg att dessa delay rutiner (automatgenererade av en
lite gammal rutin på piclist.com) är väldigt enkla och använder inte alla
finesser i MPASM (vilka kanske inte ens fanns då rutinen konstruerades).
Så döm inte dagens MPASM efter hur dessa delayrutiner är gjorda... :-)
Användarvisningsbild
vfr
EF Sponsor
Inlägg: 3515
Blev medlem: 31 mars 2005, 17:55:45
Ort: Kungsbacka

Re: PIC, ASM. Frågetecken kring delayrutiner

Inlägg av vfr »

Vad syftade du på för automatgenerering av kod? Som får problemet med lika labelnamn. Det mest uppenbara är väl makron, så därför tog jag det som exempel. Och det är ju bra att den varianten verkar stödjas.
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: PIC, ASM. Frågetecken kring delayrutiner

Inlägg av sodjan »

Användarvisningsbild
JimmyAndersson
Inlägg: 26586
Blev medlem: 6 augusti 2005, 21:23:33
Ort: Oskarshamn (En bit utanför)
Kontakt:

Re: PIC, ASM. Frågetecken kring delayrutiner

Inlägg av JimmyAndersson »

Tack! Nu förstår jag precis. :tumupp:

Just den här kodgeneratorn är som sagt lite gammal, men jag tycker ändå att den är väldigt användbar.
Timers är kanske lite mer "säkert", men i många projekt räcker det att låta PIC-kretsen snurra runt och
räkna en stund för att få en lagom fördröjning.



Swech:
"P.s. sen bör man snart ta fram en lag inom EU att mjukvarufördröjningar förbjuds"

Är dem inte trevliga? Små räknerutiner som gör att gamla DOS-spel går galet fort på moderna datorer.. :D
"FOR t=1 to 1000;next t" gav ungefär en sekunds fördröjning på en Vic20. Samma kod skulle ge en nästan omärkbar
fördröjning i en modern PC, eller för den delen en modern PIC. Utvecklingen går framåt. :)
Användarvisningsbild
vfr
EF Sponsor
Inlägg: 3515
Blev medlem: 31 mars 2005, 17:55:45
Ort: Kungsbacka

Re: PIC, ASM. Frågetecken kring delayrutiner

Inlägg av vfr »

http://www.piclist.com/techref/piclist/ ... /delay.htm


Ok. Alltså något som ligger helt utanför verktygen i MPLab. Då är jag med.

Å andra sidan så genererar ju den typen av externt verktyg kod som är avsedd att sedan stoppa in i egen källkod. Då lär man ju knappast kunna påverka hur hoppen sker i vilket fall i verktyget. Fast det är ju heller inte speciellt svårt att byta ut mot lablar när man stoppar in det i egen kod. Har man koden framför sig, så ger det sig ganska fort vart den borde hoppa och var man skall stoppa in hopplablarna för att få en mer generisk kod. Det är ju dessutom ganska enkelt att testa att den verkligen genererar samma kod när man stoppat dit lablar istället.
Användarvisningsbild
jesse
Inlägg: 9240
Blev medlem: 10 september 2007, 12:03:55
Ort: Alingsås

Re: PIC, ASM. Frågetecken kring delayrutiner

Inlägg av jesse »

om man absolut vill använda $+n så börja först att skriva dit lablar (swengelska, vad säger man? labels, etiketter, läjblar?) och skriva goto labelnamn, sedan kompilera (assemblera) och kolla i den färdiga koden vilket nummer du fått fram efter goto, om det finns en disassembler som skriver ut koden får du det i klartext goto $+6 eller vad det nu blir. skriv dit siffran i originalkoden och gör om lablarna till kommentarer så vet du vart du hoppar.

men jag skulle nog rekommendera att man undviker $+n helt och hållet och ska en kod upprepas så finns det ju nåt som heter macro.
v-g
EF Sponsor
Inlägg: 7875
Blev medlem: 25 november 2005, 23:47:53
Ort: Kramforce

Re: PIC, ASM. Frågetecken kring delayrutiner

Inlägg av v-g »

Hur man än gör så står ju PICen på nåt ställe och snurrar ;)

En del fördelar med att köra i interupt är att man kan göra lite annat medan man väntar på en sak. Man kan även köra SLEEP om strömförbrukning är viktigt, håller dock med om att för det mesta är det krångligare än att bara skriva CALL XX_ms_Delay.

I nåt projekt minns jag att jag saktade ner PIC:en till lägsta INTOSC under delayen för att spara mesta möjliga och det fungerade faktist. För fast ansluta prylar struntar jag i SLEEP och strömspar det ger ju ändå liksom inget i sammanhanget :roll:

Jag har själv en rutin där jag bara skickar in WREG och kan på det sättet justera delayen för massor av olika tillfällen, själva "literalen" som jag skickar in mäter jag upp med MPSIM och sparar i min includefil.

Kod: Markera allt

Delay20uSecs	EQU	0x3
Delay40uSecs	EQU	0x6
Delay100uSecs	EQU	0xE
Sen i koden:

Kod: Markera allt

	MOVLW Delay40uSecs		;Wait a while to get pin HIGH or LOW
	CALL Delay_Short
Hoppas det tillför något.
Användarvisningsbild
JimmyAndersson
Inlägg: 26586
Blev medlem: 6 augusti 2005, 21:23:33
Ort: Oskarshamn (En bit utanför)
Kontakt:

Re: PIC, ASM. Frågetecken kring delayrutiner

Inlägg av JimmyAndersson »

Det var ju ingen dum idé! Enkelt och bra. :)


Jag testade att ändra $+x till labels:

Kod: Markera allt

Delay_5msb
	movlw	0x0E
	movwf	d1
	movlw	0x28
	movwf	d2
Delay_5msb_0
	decfsz	d1, f
	goto	Delay_5msb_1
Delay_5msb_1
	decfsz	d2, f
	goto	Delay_5msb_0
	goto	Delay_5msb_2
	nop
Delay_5msb_2
	return
I MPSIM tar den koden 24,8µs att köra, och inte 5ms som jag förväntade mig. Men:
Den genererade orginalkoden tar precis lika lång tid, så det verkar fungera att göra såhär.
(5msb = 5ms, version b :) )

edit: Hm.. går inte den första och sista goto'n byta mot nop? Måste prova.

edit 2:

Kod: Markera allt

Delay_5msb
	movlw	0x0E
	movwf	d1
	movlw	0x28
	movwf	d2
Delay_5msb_0
	decfsz	d1, f
	nop
	nop
	decfsz	d2, f
	goto	Delay_5msb_0
	nop
	nop
	return
Gick fint. Mycket renare och snyggare dessutom. :)
sodjan
EF Sponsor
Inlägg: 43251
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping

Re: PIC, ASM. Frågetecken kring delayrutiner

Inlägg av sodjan »

Notera att "goto $+1" är det samma (tidsmässigt) som "nop, nop",
men tar bara en instruktion istället för två. En smart men kanske
inte så uppenbar optimering. Så "goto $+1, nop" ska bytas till
"nop, nop, nop" för att det ska bli samma exekveringstid.
Skriv svar