Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

16-bit value multiplied by 128

Status
Not open for further replies.

atferrari

Well-Known Member
Most Helpful Member
PIC 18F family.

Three registers ACC_U, ACC_H, ACC_L

To multiply the 16-bit value stored in ACC_H, ACC_L by 128, I am currently repeating the snipet below, 7 times

Code:
BCF STATUS,C               ;ensure that LSB will get a 0 into b0
RLCF ACC_L,F                ;rotate to left and retain new value.
RLCF ACC_H,F                ;rotate to left and retain new value.
RLCF ACC_U,F                ;rotate to left and retain new value.

which, no surprise, takes 28 lines of code.

Do you know of any trick to do it faster?
 
It would be quicker to rotate right once, which divides by 2, and then multiply by 256 by moving the contents of each register to the next one.

Code:
RRCF ACC_U,F                ;rotate right to divide by 2
                                   ;although there is only one bit we are interested in
                                   ;and that goes into the carry bit
RRCF ACC_H, W              ;rotate right into W, bringing in the carry bit
MOVWF  ACC_U              ;move into ACC_U, which multiplies by 256

RRCF ACC_L, W              ;rotate right into W, bringing in a carry bit
MOVWF  ACC_H              ;mov into ACC_H, which multiplies by 256
CLR  ACC_L
RRCF ACC_L, F               ;bring in final carry bit

Well that is 7 lines, so 4 times smaller.
 
The multiplier would work, but it is only multiplies 8 bits by 8 bits, so to multiply by 128 would need three multiplies, and loads of additions. You could ignore carries in this case. The results are always in PRODH:pRODL so those would need to be moved several times.

I can't see it being done in 7 lines or less.
 
Thanks Diver. Simpler really.
 
It would be quicker to rotate right once, which divides by 2, and then multiply by 256 by moving the contents of each register to the next one.
Well that is 7 lines, so 4 times smaller.
...

A minor nitpick, you should do the multiply first, then the divide by 2, so you don't lose data.
 
My apologies Diver300, I only looked at your method ie; div->mult and didn't analyse your code sample. You code does preserve the lowest bit in the carry bit and restores it at the end.

My preferred code probably would have been;
Code:
MOVF   ACC_H   ; multiply 16bit by 256 into a 24bit result
MOVWF  ACC_U
MOVF   ACC_L
MOVWF  ACC_H
CLRF   ACC_L   
CLRC     ; 24bit divide by 2 
RRCF ACC_U,F   
RRCF ACC_H,F 
RRCF ACC_L,F

Which is easier to understand but is inferior to your code as it is 2 instructions longer and only handles a 16bit input where yours handles a 17bit input. :)
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top