Sida 2 av 2

Re: Multiplikation med en decimalkonstant i 8bit-assembler

Postat: 28 februari 2011, 08:28:04
av SeniorLemuren
victor_passe skrev:Nej, att multiplicera heter gångra och dra roten ur heter rotera...
Du glömde divra :D

Re: Multiplikation med en decimalkonstant i 8bit-assembler

Postat: 28 februari 2011, 09:18:34
av bearing
När den höga delen av multiplikationens resultat används som det egentliga resultatet blir det som att dividera det totala resultatet med 256. Det vi gör är alltså Spänning*10 = 120 * AD / 256. Kvoten AD/256 kommer variera mellan 0 och 1 (eller egentligen mellan 0 och 255/256), vilket gör att Spänning*10 kommer variera mellan 0 och 120.

Ifall de olika metoderna ger olika resultat beror det nog på någon liten bugg. Jag såg i koden du postade tidigare att Carry inte nollställdes innan första roteringen, vilket gör att en etta kommer roteras in ibland.

Jag har också, likt nog de flesta, börjat med de överskådliga lösningarna, för att sedan, när det behövts, försökt krympa koden på olika sätt. Min första PIC-processor hade 1k-minne, vilket gjorde att det var mer regel än undantag att koden behövde förminskas för att få plats. Jag minns hur programmen kunde ta upp exakt 1024 words, och använda nästan hela SRAM. Det är antagligen efter den tiden som jag snabbt ser "genvägarna". Fast det är inte helt positivt, tycker jag, för jag ser mig ofta sitta och fundera över sätt att göra mer kompakt kod, än skriva klart programmet.


Prova den här koden:

Kod: Markera allt

		; Load the test case
		movlw   .111
		movwf   ADC_VALUE

		;  Integer part
		;
		; Mul 12
		;First mul 3
		movwf	BYTE_L
		clrf	BYTE_H
		addwf	BYTE_L
		btfsc	STATUS, C
			incf  BYTE_H
		addwf	BYTE_L
		btfsc	STATUS, C
			incf  BYTE_H
		;Then mul 4
		bcf		STATUS, C
		rlf		BYTE_L
		rlf		BYTE_H
		rlf		BYTE_L
		rlf		BYTE_H, W
		;Save
		movwf	TENS

		
		;  Decimal part
		;
		; Mul 10
		;First mul 5
		movfw	BYTE_L
		clrf	BYTE_H
		;bcf		STATUS, C ;not needed here
		rlf		BYTE_L
		rlf		BYTE_H
		rlf		BYTE_L
		rlf		BYTE_H
		addwf	BYTE_L
		btfsc	STATUS, C
			incf  BYTE_H
		;Then mul 2
		bcf		STATUS, C
		rlf		BYTE_L
		rlf		BYTE_H, W
		;Save
		movwf	ONES
EDIT:
På tal om kompakt kod, kolla in den här 8)
Den ger spänning*10.

Kod: Markera allt

		; Load the test case
		movlw   .111
		movwf   ADC_VALUE
		
		movwf	VOLTAGE10
		bcf  	STATUS, C
		rrf  	VOLTAGE10
		swapf	VOLTAGE10, W
		andlw	0x0F
		subwf	VOLTAGE10
Koden delar ADC-värdet med 2, och drar sedan bort 1/32, vilket är detsamma som att multiplicera med 15 och dividera med 32.

En kombination av den här koden och din loop för division med 10 borde ge liten kodstorlek i förhållande till Mul12+Mul10 ovan.

Re: Multiplikation med en decimalkonstant i 8bit-assembler

Postat: 28 februari 2011, 23:06:35
av exile
Eller så kan man ta (ADC*256 - ADC*16) >> 1

Kod: Markera allt

	movlw	.16 ;in

	movwf	resultat
	btfss		STATUS, Z
	decf		resultat,W
	movwf	temp
	swapf		temp, W
	andlw		0x0F
	subwf		resultat,f
	bcf		STATUS, C
	RRF		resultat,f
och om man inte är så noga på avrundningen

Kod: Markera allt

	movlw	.16 ;in

	movwf	resultat
	btfss		STATUS, Z
	swapf	resultat, W
	andlw		0x0F
	subwf		resultat,f
	bcf		STATUS, C
	RRF		resultat,f
...

Re: Multiplikation med en decimalkonstant i 8bit-assembler

Postat: 21 mars 2012, 11:10:25
av bos
exile: Jag har nu, över ett år efteråt, fortfarande inte förstått hur du fick fram (ADC*256 - ADC*16) >> 1.

Orkar du berätta? Den fungerar väldigt bra.

Re: Multiplikation med en decimalkonstant i 8bit-assembler

Postat: 21 mars 2012, 11:37:30
av sodjan
(ADC*256 - ADC*16) >> 1.

ADC * (256-16) / 2

ADC * 240 / 2

ADC * 120

vilket var det du ville ha.

Grejen är ju att det är snabbt att göra *256, *16 och /2...

Re: Multiplikation med en decimalkonstant i 8bit-assembler

Postat: 25 mars 2012, 05:49:20
av PW2000
På den här länken så får man kod för * och / genererat.

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