Sida 1 av 2

MPLAB assembler: Lyckas inte "reservera" ett word.

Postat: 23 oktober 2010, 15:03:11
av JimmyAndersson
(Orkar ni inte läsa så kan ni hoppa ner till första kodexemplet. :) )

Lite bakgrund:
Jag har en PIC16F688 med en pot ansluten till en analog ingång.
ADC'n är ju 10 bitar, fördelade på två bytes. Jag sparar dessa i pot_lo och pot_hi.

Nu är det så att jag bara behöver ett resultat mellan 0 - 255 när man vrider på poten.
Att bara använda pot_lo eller pot_hi skulle ju resultera i ett lite annorlunda resultat:
(pot_lo : Tja.. den börjar ju om på 0 när man har vridit poten halvvägs.
pot_hi : man får bara nytta av halva poten.)

Min tanke var då att slå ihop pot_lo och pot_hi till ett word
och t.ex dela (shifta åt höger) för att nå till mitt önskade intervall.
Såg förresten att samma sak diskuteras här.


Men mitt problem är helt enkelt att jag inte lyckas få några bitar i den höga delen av mitt word.

Kodexempel:

Kod: Markera allt

test_vars		UDATA_SHR
test_word		RES 2

sub_rutiner		CODE

convert_test
	movlw		b'00010000'		;En bit som test...
	movwf		test_word

	;Shifta 8 steg åt vänster. (Resultatet ser ni i kolumnen längst till höger.
   ;                          Det är kopierat från Watch-fönstret i MPLAB.)
	rlf			test_word, f	;00000000 00010000
	rlf			test_word, f	;00000000 00100000
	rlf			test_word, f	;00000000 01000000
	rlf			test_word, f	;00000000 10000000
	rlf			test_word, f	;00000000 00000000
	rlf			test_word, f	;00000000 00000001
	rlf			test_word, f	;00000000 00000010
	rlf			test_word, f	;00000000 00000100
Den lilla biten åker alltså ut till vänster, genom carry och tillbaka in från höger igen.

Jag har även testat andra sätt för att överhuvudtaget få in något på de översta (vänstra) bitarna i test_word.
Bl.a genom att helt enkelt lägga till 255 till test_word istället för att shifta. Dvs såhär:

Kod: Markera allt

	movlw		b'00010000'	
	movwf		test_word
	movlw		d'255'	
	addwf		test_word, f
Men resultatet blir även där att det "slår runt" som om test_word vore en byte.

Ligger felet i test_word RES 2 ?
Jag har försökt hitta ledtrådar bl.a här men har inte sett något som visar att man ska göra på ett annat sätt.
Nu undrar jag förstås hur jag ska göra istället och det är där ni kommer in i bilden. Upplys mig med kunskap. :)

Re: MPLAB assembler: Lyckas inte "reservera" ett word.

Postat: 23 oktober 2010, 15:10:22
av bearing
Det går att ställa om AD-omvandlaren så att den vänsterjusterar resultatet. Den höga byten innehåller då resultatet i åtta bitar.

Re: MPLAB assembler: Lyckas inte "reservera" ett word.

Postat: 23 oktober 2010, 15:15:28
av ToPNoTCH
Så här gör jag, hoppas det kan vara till hjälp.

Kod: Markera allt

sample:
	banksel		ADCON0
	bsf			ADCON0,1		; Start conversion
	btfsc		ADCON0,1		; Is conversion done?
	goto		$-1				; No, test again
	banksel		ADRESH
	movfw		ADRESH			; Read upper 2 bits
	movwf		hi				; store in GPR space
	banksel		ADRESL
	movfw		ADRESL			; Read lower 8 bits
	bcf			STATUS,RP0		; address Register Page 0
	bcf			STATUS,RP1
	movwf		lo
	bcf			STATUS,C
	btfsc		hi,0
	bsf			STATUS,C
	rrf			lo,1
	bcf			STATUS,C
	btfsc		hi,1
	bsf			STATUS,C
	rrf			lo,1
	incf		lo,1
	movfw		lo				; Rotate down to 0-255 and store in W
	return

Re: MPLAB assembler: Lyckas inte "reservera" ett word.

Postat: 23 oktober 2010, 15:16:29
av makan1975
Du borde ju kunna göra på samma sätt som i den andra tråden

'Ta råvärdet, multiplicera med 100 och dela med 1023.'
Fast du multiplicerar inte med 100 utan 255 istället.
Sedan kan jag inte visa hur det skall se ut i kod ännu (har inte kommit så långt i min utbildning ännu)..

Re: MPLAB assembler: Lyckas inte "reservera" ett word.

Postat: 23 oktober 2010, 15:25:47
av sodjan
Behövs inga beräkningar. Med rätt vänster/höger justering så är det bara
att ta den ena (höga) byten, de två lägsta bitarna vill du ju inte ha ändå.
ADFM=0 är det nog du ska ha och använd enbart ADRESH.

Re: MPLAB assembler: Lyckas inte "reservera" ett word.

Postat: 23 oktober 2010, 15:29:38
av makan1975
Smart :D

Re: MPLAB assembler: Lyckas inte "reservera" ett word.

Postat: 23 oktober 2010, 15:33:39
av JimmyAndersson
Bearing & Sodjan: Ah, så enkelt. :idea:

Men jag måste säga att ToPNoTCH's lösning var snygg. :)

Makan1975:
Tyvärr går inte det tricket att göra sådär enkelt
eftersom resultatet av multipliceringen inte skulle få plats i en byte.

Re: MPLAB assembler: Lyckas inte "reservera" ett word.

Postat: 23 oktober 2010, 15:37:16
av sodjan
Tja, det var ju samma sak som bearing redan sa... :-)

> test_word RES 2

Det där allokerar alltså två bytes RAM (efter varandra).
Symbolen "test_word" innehåller adressen till det första av dom.

Det är inte helt klart, men det verkar som att du tror att du kan
hantera detta som om du hade tillgång till en 16-bitars variabel !?
Det har du alltså inte, du har två 8-bitars variabler, en på adress
"test_word" och en på adress "test_word+1".

Du kan t.ex inte shifta data direkt mellan de två !

Re: MPLAB assembler: Lyckas inte "reservera" ett word.

Postat: 23 oktober 2010, 16:04:05
av JimmyAndersson
"det verkar som att du tror att du kan hantera detta som om du hade tillgång till en 16-bitars variabel !?"

Det var precis vad jag trodde. :)
Jag vet att jag sitter med en 8 bitars PIC och förstod att "RES 2" allokerar två bytes.

Däremot förstår jag nu att jag hade fel när jag trodde att man genom denna allokering kunde nå
dessa två bytes (som ett word) genom symbolen "test_word" och att bitarna shiftades till den andra byten genom carry.

Jag antar att detta var en villfarelse som kommer från min tid med högnivåspråk. :)

Re: MPLAB assembler: Lyckas inte "reservera" ett word.

Postat: 23 oktober 2010, 16:08:03
av Icecap
Om du shifter LSB'n först och sedan MSB'n får du det så.

Och "...villfarelse som kommer från min tid med högnivåspråk..."
Jupp, = orsaken till att ASM ger bäst förståelse för hårdvarunära programmering...

Re: MPLAB assembler: Lyckas inte "reservera" ett word.

Postat: 23 oktober 2010, 16:11:23
av sodjan
Korrekt, "RES 2" allokerar 2 st 8-bitars variabler... :-)

Dock ligger de alltid tillsammans så det är enkelt att t.ex göra
"my_array RES 20" för att få en 20 positionerns array/lista/buffert
som sedan kan loopas igenom med indexregistren eller liknande.
Startadressen till arraynen är då "my_array".

> Om du shifter LSB'n först och sedan MSB'n får du det så.

Exakt, och det är ju just därför som C-flaggan alls är med i shiften.

Re: MPLAB assembler: Lyckas inte "reservera" ett word.

Postat: 23 oktober 2010, 18:14:40
av stekern
Om man bortser från att problemet är löst skulle en generell metod vara:
skifta lo två steg åt höger
skifta hi sex steg åt vänster
result = hi or lo

EDIT: or ska det givetvis vara inte and

Re: MPLAB assembler: Lyckas inte "reservera" ett word.

Postat: 24 oktober 2010, 00:03:08
av sodjan
En generell motod för att göra vadå ?

Re: MPLAB assembler: Lyckas inte "reservera" ett word.

Postat: 24 oktober 2010, 04:35:34
av stekern
>En generell motod för att göra vadå ?
Lösa problemet som presenterades i den första posten, såklart...

Re: MPLAB assembler: Lyckas inte "reservera" ett word.

Postat: 24 oktober 2010, 12:51:55
av bearing
PIC16-kretsar har inte någon barrel shifter, så dom där 6 shiftningarna kommer ta tid. Visserligen kan man använda instruktionen som byter plats på nibbles för att snabbt shifta 4 steg, men det lämnar ändå två skiftningar att göra utöver det. Jag är säker på att det går snabbare att rotera två steg åt höger bara.

Kod: Markera allt

convert10to8:     //Make 10-bit result 8-bit
   rrf ADRESH, f  //Don't worry about stuff being shifted into ADRESH
   rrf ADRESL, f
   rrf ADRESH, f
   rrf ADRESL, w
   return //Return with result in w