Du glömde divravictor_passe skrev:Nej, att multiplicera heter gångra och dra roten ur heter rotera...
Multiplikation med en decimalkonstant i 8bit-assembler
- SeniorLemuren
- Inlägg: 8653
- Blev medlem: 26 maj 2009, 12:20:37
- Ort: Kristinehamn
Re: Multiplikation med en decimalkonstant i 8bit-assembler
Re: Multiplikation med en decimalkonstant i 8bit-assembler
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:
EDIT:
På tal om kompakt kod, kolla in den här
Den ger spänning*10.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.
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
På tal om kompakt kod, kolla in den här
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
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
Eller så kan man ta (ADC*256 - ADC*16) >> 1
och om man inte är så noga på avrundningen
...
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,fKod: Markera allt
movlw .16 ;in
movwf resultat
btfss STATUS, Z
swapf resultat, W
andlw 0x0F
subwf resultat,f
bcf STATUS, C
RRF resultat,fRe: Multiplikation med en decimalkonstant i 8bit-assembler
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.
Orkar du berätta? Den fungerar väldigt bra.
Re: Multiplikation med en decimalkonstant i 8bit-assembler
(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...
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
På den här länken så får man kod för * och / genererat.
http://www.piclist.com/techref/piclist/ ... divmul.htm
http://www.piclist.com/techref/piclist/ ... divmul.htm
