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*16-bit=32-bit result (signed multiplication).

Status
Not open for further replies.

kasser

New Member
hi evry body:
iam a microcontroller beginner, and i stood AVR223:digital filter with AVR and AVR201:using the AVR hardware multiplier .
but now I don,t understand how can i singed numbers .
can anybody show me what is the mathematical algorithm (general algorithm) used to multipling
16-bit*16-bit=32-bit result where the numbers are signed.
pls another quistion :
how can i multipling the adc output (10-bit) by 16-bit
(signed multiplication).
the microcontroller used is atmega8.
 
You negate the negative numbers and keep track of the sign bits separately.
In pseudo code it would look something like,
Sign=false
if MultA<0 then Sign = not Sign: MultA = -MultA
if MultB<0 then Sign = not Sign: MultB = -MultB
Answer = MultA * MultB
If Sign then Answer = -Answer

To negate a value you complement it and add 1.

Unfortunately, I don't know AVR code so can't help with actual code.

HTH

Mike.
 
This is for Intel MCS51 based µC, all 8031 derivates

Code:
;----------------------------------------------------------------------------------------
;Function name: mul_16x16_signed
;Descprition..: Multiplies 2 signed 16-bit operands resulting in a signed 32-bit number.
;			Control flag MathLib_Res1Neg is set with negative result.
;
;
;Function name: mul_16x16_unsigned
;Descprition..: Multiplies 2 unsigned 16-bit operands resulting in a unsigned 32-bit number.
;
;
;Function name: mul_16x16_signed_op1
;Descprition..: Multiplies signed 16-bit operand (op1) by 
;				   unsigned 16-bit operand (op2) resulting in a signed 32-bit number.
;			Control flag MathLib_Res1Neg is set with negative result.
;
;
;Input....: Operand 1 HB = MathLib_Op1+0
;			    LB = MathLib_Op1+1
;
;		Operand 2 HB = MathLib_Op2+0
;			    LB = MathLib_Op2+1
;
;Output...:	Result HB = MathLib_Res1+0
;				MathLib_Res1+1
;				MathLib_Res1+2
;			 LB = MathLib_Res1+3
;
;		Negative result: MathLib_Res1Neg = 1
;------------------------------------------------------------------------------------	
;
mul_16x16_signed:		mov  MathLib_Flags,#0		;Clear control flags
				push b				;Save used registers by routine 
				mov  b,#16				;Initialize loop counter
				jmp  M16_signed_init


mul_16x16_unsigned:	mov  MathLib_Flags,#0		;Clear control flags
				push b				;Save used registers by routine 
				mov  b,#16				;Initialize loop counter
				jmp  M16_unsigned_init


mul_16x16_signed_op1:	mov  MathLib_Flags,#0		;Clear control flags
				push b				;Save used registers by routine 
				mov  b,#16				;Initialize loop counter
				jmp  M16_signed_op1_init

;----------------------------------------------------------------------------------------	
;Do Calculation
;
M16_signed_init:		mov  a,MathLib_Op2+0			;Is the signed operand 2 negative?
				rlc  a
				jnc  M16_000				;If not, skip complementing
				cpl  MathLib_NegateResult		;Toggle negate result flag
				xrl  MathLib_Op2+1,#0FFh		;Complement operand 2
				xrl  MathLib_Op2+0,#0FFh
				mov  a,MathLib_Op2+1			;Increment operand 2 LB
				add  a,#1
				mov  MathLib_Op2+1,a
				jnc  M16_000				;If carry also increment LB
				inc  MathLib_Op2+0			;Propagate carry into HB
M16_000:			
				
M16_signed_op1_init:	mov  a,MathLib_Op1+0			;Is the signed operand 1 negative?
				rlc  a
				jnc  M16_001				;If not, skip complementing
				cpl  MathLib_NegateResult		;Toggle negate result flag
				xrl  MathLib_Op1+1,#0FFh		;Complement operand 1
				xrl  MathLib_Op1+0,#0FFh
				mov  a,MathLib_Op1+1			;Increment operand 1 LB
				add  a,#1
				mov  MathLib_Op1+1,a
				jnc  M16_001				;If carry also increment LB
				inc  MathLib_Op1+0			;Propagate carry into HB
M16_001:			
				
M16_unsigned_init:							;Initialize result 'register'
				mov  MathLib_Res1+3,MathLib_Op2+1	;Put 16-bit multiplier in byte 3 of product/multiplier
				mov  MathLib_Res1+2,MathLib_Op2+0	;Put 16-bit multiplier in byte 2 of product/multiplier
				mov  MathLib_Res1+1,#0			;			  Clear byte 1 of product/multiplier
				mov  MathLib_Res1+0,#0			;			  Clear byte 0 of product/multiplier

M16_loop:			mov  a,MathLib_Res1+3			;Is low bit of multiplier set?
				rrc  a
				jnc  M16_DoShift
				
M16_DoAdd:			mov  a,MathLib_Res1+1			;Upper 16 bits of product/multiplier += multiplicand
				add  a,MathLib_Op1+1			;Add LSB of multiplicand
				mov  MathLib_Res1+1,a
				mov  a,MathLib_Res1+0
				addc a,MathLib_Op1+0			;Add MSB of multiplicand
				mov  MathLib_Res1+0,a

M16_DoShift:		mov  a,MathLib_Res1+0			;Shift entire product/multiplier right once
				rrc  a
				mov  MathLib_Res1+0,a
				mov  a,MathLib_Res1+1
				rrc  a
				mov  MathLib_Res1+1,a
				mov  a,MathLib_Res1+2
				rrc  a
				mov  MathLib_Res1+2,a
				mov  a,MathLib_Res1+3
				rrc  a
				mov  MathLib_Res1+3,a
				djnz b,M16_loop				;Check all loops done

M16_CalculationsDone:	pop  b					;Restore registers used by routine

M16_CheckNegateResult:	jnb  MathLib_NegateResult,M16_End	;Should the answer be negative?
				setb MathLib_Res1Neg			;Set bit negative result
				xrl  MathLib_Res1+3,#0FFh		;Yes, complement the answer
				xrl  MathLib_Res1+2,#0FFh
				xrl  MathLib_Res1+1,#0FFh
				xrl  MathLib_Res1+0,#0FFh
				mov  a,MathLib_Res1+3			;Increment result LB
				add  a,#1
				mov  MathLib_Res1+3,a
				jnc  M16_End				;No carry: we're done
				mov  a,MathLib_Res1+2			;Propagate carry into byte 2
				addc a,#0
				mov  MathLib_Res1+2,a
				jnc  M16_End				;No carry: we're done
				mov  a,MathLib_Res1+1			;Propagate carry into byte 1
				addc a,#0
				mov  MathLib_Res1+1,a
				jnc  M16_End				;No carry: we're done
				mov  a,MathLib_Res1+0			;Propagate carry into byte 0
				addc a,#0
				mov  MathLib_Res1+0,a
M16_End:			ret

Declarations
Code:
;----------------------------------------------------------------------------------------
; Definieren interne RAM BYTE-formaat
;
				RSEG	Math_RAM_Byte
MathLib_Op1:		ds 4
MathLib_Op2:		ds 4
MathLib_Res1:		ds 4
MathLib_Res2:		ds 4



;----------------------------------------------------------------------------------------
; Definiëren interne RAM BYTE-formaat bitaddressable
;
				RSEG	Math_RAM_ByteBit
MathLib_Flags:		ds 1

Be sure to make all these declarations public so that other routines can access them. Notice that Op1 and Op2 are 4 bytes wide, that's because I have add and sub 32 bit routines also to handle 32 bits results from multiply and divide routines.

Your last question: Multiply ADC 10 bit by 16bit
Put ADC HB in MathLib_Op1+0; ADC LB in MathLib_Op1+1
Put 16bit data HB in MathLib_Op2+0; 16bit data LB in MathLib_Op2+1
Call mul_16x16_signed
Get result from MathLib_Res1

Need more? Just ask :)
 
thank you for all :
but i work with the avr microcontroller.
so if you give me the general mathematical algorithm then i can use it for avr.
e.g:

A(16bit)*B(16bit)

AhAl
BhBl*

= Bl*Ah Bl*Bh
+ Bh*Ah Bh*Al

the result
 
kasser, you should check out Atmel's website. The Appnotes section has dozens of white papers for an AVR programmer that are as good as gold. AVR200 will do just fine for you. Contains multiplication and division routines both signed and unsigned for 8 or 16 bit numbers. There are two versions of each routine, a code optimized version and a speed optimized version. They work on ALL AVR's. You should find out if your particular AVR has a hardware multiplier in which case you can significantly simplify and speed up the entire process with AVR201 which explains how to use it. Both PDF's are linked bellow. I'd highly recommend spending some time on Atmel's website in the AVR appnote section, there are many documents that contain exceptionally useful information that make life a lot easier.


https://www.electro-tech-online.com/custompdfs/2007/04/doc0936.pdf

https://www.electro-tech-online.com/custompdfs/2007/04/doc1631.pdf
 
Status
Not open for further replies.

New Articles From Microcontroller Tips

Back
Top