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.

ADC result in Three Decimal point

Status
Not open for further replies.
I said: "average of six 12 bit samples (using 10 bit ADC) you'll need to take 96 samples, add them, and then divide by 24".
You also said "If you take 24 consecutive samples and divide by 6, you'll practically get an average of six 11 bit samples multiplied by two (or 4 averaged 10 bit results added together, which increases the resolution by 1 bit)." First, the 24x O/S satisfies the minimum O/S requirement of 4^2 for 2 extra bits. The /6 removes the superfluous bits. Secondly, "the average of six 11 bit samples multiplied by two" done in the manner of 24x O/S then /6 also satifies the minimum O/S requirement of 4x per extra bit. i.e. the 6x oversampling of the 11-bit value allows for the 12-bits of information. The "multiplied by two" allows the extra bit to be moved out of the fractional part of the number before it is truncated to an integer.

Perhaps the paper is misleading.. shifting right by 2 bits is exactly equivalent to integer division by 4; the author doesn't seem to know the difference between dividing and dividing.
 
I have taken Nigel's tutorial 11 and included the "ADC*5000/1024" ( As a tribute to RB:D:D:D).

It works very well.... 5v comes out at 4.995v

Code:
;Tutorial 11_1
;Reading an analogue input, and displaying it on the LCD
;Nigel Goodwin 2004... (Mods) Ian Rogers 2013..
; Device 16F876

	LIST	p=16F876, W=2, X=ON, R=DEC	;tell assembler what chip we are using
	include "P16F876.inc"			;include the defaults for the chip
	ERRORLEVEL	0,	-302		;suppress bank selection messages
	__CONFIG    0x393A			;sets the configuration settings (oscillator type etc.)


		cblock	0x20			;start of general purpose registers
			count
			count1	
			counta	
			countb	
			LoX		
			Bit_Cntr	
			Timer_H		
			Flags		
			Flags2	
			a1			; mulpiliers
			a2
			b1
			b2
			res1			; long result
			res2
			res3
			res4	
			tmp1		
			tmp2		
			tmp3			
			TenK		
			Thou	
			Hund	
			Tens			
			Ones		
			templcd	
			templcd2	
			Acc1L			;16 bit maths register 1
			Acc1H
			Point			;position of decimal point
		endc

LCD_PORT	Equ	PORTB
LCD_TRIS	Equ	TRISB
LCD_RS		Equ	0x04			;LCD handshake lines
LCD_RW		Equ	0x06
LCD_E		Equ	0x07

LEADZ         	Equ   	0x00   			;set to display leading zeros

;start of program

		ORG	0x0000
		NOP
		BCF	PCLATH,	3
		BCF	PCLATH,	4
		GOTO	Initialise

		ORG	0x0004
		RETURN
		ORG	0x0005

Initialise	clrf	count
		clrf	PORTA
		clrf	PORTB
		clrf	PORTC
		clrf	Flags
		BANKSEL ADCON1			;disable A2D
    		movlw   0x06
    		movwf   ADCON1
    		BANKSEL PORTA	
						;variables for decimal numbers display
		bsf	Flags, LEADZ		;Don't show leading zeros
		movlw	0x03			;set decimal point position to Three
		movwf	Point

SetPorts	bsf 	STATUS,	RP0		;select bank 1
		movlw	0x00			;make all LCD pins outputs
		movwf	LCD_TRIS
		bcf 	STATUS,	RP0		;select bank 0
		call	LCD_Init		;setup LCD module
		call	LCD_CurOff		;turn cursor off
		call	Init_ADC		;initialise analogue input
		movlw	0x13
		movwf	b2
		movlw	0x88
		movwf	b1	
Main
		call	LCD_Line1		;set to first line
		call	String1			;display title string
		call	LCD_Line2
		call	Read_ADC		;read analogue input
		call	MULTI			; ADC * 5000 / 1024
		call	LCD_Decimal		;and display on LCD (in decimal)
		movlw	' '
		call	LCD_Char		;display a space
		movf	a2, W
		;call	LCD_HEX			;and display in hexadecimal
		movf	a1, W
		;call	LCD_HEX
		call	Delay100		;delay to give 10 readings per second
		goto	Main			;loop for ever

Init_ADC
; Set ADCON0
    		movlw   b'10000001'
    		movwf   ADCON0
; Set ADCON1
    		BANKSEL ADCON1
    		movlw   b'10000101'
    		movwf   ADCON1
    		BANKSEL ADCON0
		return

Read_ADC
    		bsf	ADCON0, GO_DONE		;initiate conversion
    		btfsc   ADCON0, GO_DONE
    		goto    $-1			;wait for ADC to finish

    		movf    ADRESH,W
    		andlw   0x03
    		movwf   a2
    		BANKSEL ADRESL
    		movf    ADRESL,W
    		BANKSEL	ADRESH
		movwf	a1			;
		return

;TABLES
HEX_Table  	addwf   PCL       , f
            	retlw   0x30
            	retlw   0x31
            	retlw   0x32
            	retlw   0x33
            	retlw   0x34
            	retlw   0x35
            	retlw   0x36
            	retlw   0x37
            	retlw   0x38
            	retlw   0x39
            	retlw   0x41
            	retlw   0x42
            	retlw   0x43
            	retlw   0x44
            	retlw   0x45
            	retlw   0x46

Xtext		addwf	PCL, f
		retlw	'T'
		retlw	'u'
		retlw	't'
		retlw	'o'
		retlw	'r'
		retlw	'i'
		retlw	'a'
		retlw	'l'
		retlw	' '
		retlw	'1'
		retlw	'1'
		retlw	'.'
		retlw	'1'
		retlw	0x00

;end of tables



String1		clrf	count			;set counter register to zero
Mess1		movf	count, w		;put counter value in W
		call	Xtext			;get a character from the text table
		xorlw	0x00			;is it a zero?
		btfsc	STATUS, Z
		retlw	0x00			;return when finished
		call	LCD_Char
		incf	count, f
		goto	Mess1

;math

MULTI		clrf    res4
		clrf	res3
		clrf    res2
		movlw	0x80
		movwf	res1		

nextbit
		rrf	a2,f
		rrf	a1,f

		btfss	STATUS,C
		goto	nobit_l
		movf	b1,w
		addwf	res2,f

		movf	b2, w
		btfsc	STATUS,C
		incfsz	b2, w	
		addwf	res3, f	
		btfsc	STATUS,C
		incf	res4, f
		bcf	STATUS,C	
nobit_l	
		btfss	a1, 7
		goto	nobit_h
		movf	b1,w
		addwf	res3,f
		movf	b2, w
		btfsc	STATUS,C
		incfsz	b2, w
		addwf	res4, f	

nobit_h
		rrf	res4,f
		rrf	res3,f
		rrf	res2,f
		rrf	res1,f

		btfss	STATUS,C
		goto	nextbit

DIVSI		movf	res2,w		; ditch res0 (8)
		movwf	res1
		movf	res3,w		; 
		movwf	res2
		movf	res4,w
		movwf	res3
		rrf	res3,f		; shift right twice (9 & 10)
		rrf	res2,f
		rrf	res1,f
		bcf	STATUS,C
		rrf	res3,f
		rrf	res2,f
		rrf	res1,f
		movf	res1,w
		movwf	a1
		movf	res2,w
		movwf	a2
		return

; end math
;LCD routines

;Initialise LCD
LCD_Init	
		clrf	PORTB
		call	Delay255

		movlw	0x3			;Set 4 bit mode
		movwf	LCD_PORT
		call	Pulse_e
		call	Delay5
		call	Pulse_e
		call	Delay5
		call	Pulse_e
		call	Delay5
		movlw	0x2			;Set 4 bit mode
		movwf	LCD_PORT
		call	Pulse_e
		call 	Delay20
		movlw	0x28			;Set display shift
		call	LCD_Cmd

		movlw	0x06			;Set display character mode
		call	LCD_Cmd

		movlw	0x0c			;Set display on/off and cursor command
		call	LCD_Cmd			;Set cursor off

		call	LCD_Clr			;clear display

		retlw	0x00

; command set routine
LCD_Cmd		movwf	templcd
		swapf	templcd,	w	;send upper nibble
		andlw	0x0f			;clear upper 4 bits of W
		movwf	LCD_PORT
		bcf	LCD_PORT, LCD_RS	;RS line to 1
		call	Pulse_e			;Pulse the E line high

		movf	templcd,	w	;send lower nibble
		andlw	0x0f			;clear upper 4 bits of W
		movwf	LCD_PORT
		bcf	LCD_PORT, LCD_RS	;RS line to 1
		call	Pulse_e			;Pulse the E line high
		call 	LCD_Busy
		retlw	0x00

LCD_CharD	addlw	0x30			;add 0x30 to convert to ASCII
LCD_Char	movwf	templcd
		swapf	templcd,	w	;send upper nibble
		andlw	0x0f			;clear upper 4 bits of W
		movwf	LCD_PORT
		bsf	LCD_PORT, LCD_RS	;RS line to 1
		call	Pulse_e			;Pulse the E line high

		movf	templcd,	w	;send lower nibble
		andlw	0x0f			;clear upper 4 bits of W
		movwf	LCD_PORT
		bsf	LCD_PORT, LCD_RS	;RS line to 1
		call	Pulse_e			;Pulse the E line high
		call 	LCD_Busy
		retlw	0x00

LCD_Line1	movlw	0x80			;move to 1st row, first column
		call	LCD_Cmd
		retlw	0x00

LCD_Line2	movlw	0xc0			;move to 2nd row, first column
		call	LCD_Cmd
		retlw	0x00

LCD_Line1W	addlw	0x80			;move to 1st row, column W
		call	LCD_Cmd
		retlw	0x00

LCD_Line2W	addlw	0xc0			;move to 2nd row, column W
		call	LCD_Cmd
		retlw	0x00

LCD_CurOn	movlw	0x0d			;Set display on/off and cursor command
		call	LCD_Cmd
		retlw	0x00

LCD_CurOff	movlw	0x0c			;Set display on/off and cursor command
		call	LCD_Cmd
		retlw	0x00

LCD_Clr		movlw	0x01			;Clear display
		call	LCD_Cmd
		retlw	0x00

LCD_HEX		movwf	tmp1
		swapf	tmp1,	w
		andlw	0x0f
		call	HEX_Table
		call	LCD_Char
		movf	tmp1, w
		andlw	0x0f
		call	HEX_Table
		call	LCD_Char
		retlw	0x00

Pulse_e		bsf	LCD_PORT, LCD_E
		nop
		bcf	LCD_PORT, LCD_E
		retlw	0x00

LCD_Busy
		bsf	STATUS,	RP0		;set bank 1
		movlw	0x0f			;set Port for input
		movwf	LCD_TRIS
		bcf	STATUS,	RP0		;set bank 0
		bcf	LCD_PORT, LCD_RS	;set LCD for command mode
		bsf	LCD_PORT, LCD_RW	;setup to read busy flag
		bsf	LCD_PORT, LCD_E
		swapf	LCD_PORT, w		;read upper nibble (busy flag)
		bcf	LCD_PORT, LCD_E		
		movwf	templcd2 
		bsf	LCD_PORT, LCD_E		;dummy read of lower nibble
		bcf	LCD_PORT, LCD_E
		btfsc	templcd2, 7		;check busy flag, high = busy
		goto	LCD_Busy		;if busy check again
		bcf	LCD_PORT, LCD_RW
		bsf	STATUS,	RP0		;set bank 1
		movlw	0x00			;set Port for output
		movwf	LCD_TRIS
		bcf	STATUS,	RP0		;set bank 0
		return

LCD_Decimal
		call    Convert
		btfsc   Flags, LEADZ
		goto    LCD_TENK
		movf    TenK, w
		btfss   STATUS, Z
		goto    LCD_TENK
		movf    Thou, w
		btfss   STATUS, Z
		goto    LCD_THOU
		movf    Hund, w
		btfss   STATUS, Z
		goto    LCD_HUND
		movf    Tens, w
		btfss   STATUS, Z
		goto    LCD_TENS
		goto    LCD_ONES
LCD_TENK
		movlw	0x05			;test if decimal point 5
		subwf   Point, w
		btfss   STATUS    , Z
		goto	NO_DP5
		movlw	'.'
		call	LCD_Char		;display decimal point
NO_DP5		movf    TenK, w
		call    LCD_CharD
		movlw	0x04			;test if decimal point 4
		subwf   Point, w
		btfss   STATUS    , Z
		goto	LCD_THOU
		movlw	'.'
		call	LCD_Char		;display decimal point
LCD_THOU
		movf    Thou, w
		call    LCD_CharD
		movlw	0x03			;test if decimal point 3
		subwf   Point, w
		btfss   STATUS    , Z
		goto	LCD_HUND
		movlw	'.'
		call	LCD_Char		;display decimal point
LCD_HUND
		movf    Hund, w
		call    LCD_CharD
		movlw	0x02			;test if decimal point 2
		subwf   Point, w
		btfss   STATUS    , Z
		goto	LCD_TENS
		movlw	'.'
		call	LCD_Char		;display decimal point
LCD_TENS
		movf    Tens, w
		call    LCD_CharD
		movlw	0x01			;test if decimal point 1
		subwf   Point, w
		btfss   STATUS    , Z
		goto	LCD_ONES
		movlw	'.'
		call	LCD_Char		;display decimal point
LCD_ONES
		movf     Ones, w
		call     LCD_CharD
		return


;end of LCD routines


;Delay routines

Delay255	movlw	0xff		;delay 255 mS
		goto	d0
Delay100	movlw	d'100'		;delay 100mS
		goto	d0
Delay50		movlw	d'50'		;delay 50mS
		goto	d0
Delay20		movlw	d'20'		;delay 20mS
		goto	d0
Delay5		movlw	0x05		;delay 5.000 ms (20 MHz clock)
d0		movwf	count1
d1		movlw	0xE7
		movwf	counta
		movlw	0x04
		movwf	countb
Delay_0		decfsz	counta, f
		goto	$+2
		decfsz	countb, f
		goto	Delay_0

		decfsz	count1	,f
		goto	d1
		retlw	0x00

;end of Delay routines

;This routine downloaded from http://www.piclist.com
Convert:                        ; Takes number in a2:a1
                                ; Returns decimal in
                                ; TenK:Thou:Hund:Tens:Ones
        swapf   a2, w
	iorlw	B'11110000'
        movwf   Thou
        addwf   Thou,f
        addlw   0XE2
        movwf   Hund
        addlw   0X32
        movwf   Ones

        movf    a2,w
        andlw   0X0F
        addwf   Hund,f
        addwf   Hund,f
        addwf   Ones,f
        addlw   0XE9
        movwf   Tens
        addwf   Tens,f
        addwf   Tens,f

        swapf   a1,w
        andlw   0X0F
        addwf   Tens,f
        addwf   Ones,f

        rlf     Tens,f
        rlf     Ones,f
        comf    Ones,f
        rlf     Ones,f

        movf    a1,w
        andlw   0X0F
        addwf   Ones,f
        rlf     Thou,f

        movlw   0X07
        movwf   TenK

                    ; At this point, the original number is
                    ; equal to
                    ; TenK*10000+Thou*1000+Hund*100+Tens*10+Ones
                    ; if those entities are regarded as two's
                    ; complement binary.  To be precise, all of
                    ; them are negative except TenK.  Now the number
                    ; needs to be normalized, but this can all be
                    ; done with simple byte arithmetic.

        movlw   0X0A                             ; Ten
Lb1:
        addwf   Ones,f
        decf    Tens,f
        btfss   3,0
        goto   Lb1
Lb2:
        addwf   Tens,f
        decf    Hund,f
        btfss   3,0
        goto   Lb2
Lb3:
        addwf   Hund,f
        decf    Thou,f
        btfss   3,0
        goto   Lb3
Lb4:
        addwf   Thou,f
        decf    TenK,f
        btfss   3,0
        goto   Lb4

        retlw	0x00


		end

There is leading zeros but you can see whats been done....

Good luck..
 
Dear Rogers,
Thank you very much for the reply

It is so hard to understand whole think together
Therefore I captured the converter part to study step by step

Code:
numL	equ	0X20
 	numH	equ	0x21
 	tenk	equ	0x22
 	thou	equ	0x23
 	hund	equ	0x24
 	tens	equ	0x25
 	ones	equ	0x26
 	del		equ	0x27
 	
ll 	movlw	b'00000011'
 	movwf	numL
 	movlw	b'00000011'		;771 
 	movwf	numH
 	
 	
 		
 		swapf	numH,w
 		iorlw	b'11110000'
 		movwf	thou
 		addwf	thou,f
 		addlw	0xe2
 		movwf	hund
 		addlw	0x32
 		movwf	ones
 		
 		movf	numH,w
 		andlw	0x0f
 		addwf	hund,f
 		addwf	hund,f
 		addwf	ones,f
 		addlw	0xe9
 		movwf	tens
 		addwf	tens,f
 		addwf	tens,f
 		
 		swapf	numL,w
 		andlw	0x0f
 		addwf	tens,f
 		addwf	tens,f
 		
 		rlf		tens,f
 		rlf		ones,f
 		comf	ones,f
 		rlf		ones,f
 		
 		movf	numL,w
 		andlw	0x0f
 		addwf	ones,f
 		rlf		thou,f
 		
 		movlw	0x07
 		movwf	tenk
 		
 		movlw	0x0a
 lb1	
 		addwf	ones,f
 		decf	tens,f
 		btfss	3,0
 		goto	lb1
 lb2	
 		addwf	tens,f
 		decf	hund,f
 		btfss	3,0
 		goto	lb2
 lb3	
 		addwf	hund,f
 		decf	thou,f
 		btfss	3,0
 		goto	lb3
 lb4	
 		addwf	thou,f
 		decf	tenk,f
 		btfss	3,0
 		goto	lb4
 		
 		clrw	
 		decfsz	del,f
 		goto	$-1
 		clrw
 		goto	ll
 		
 		
 	
    	end

Can you please advice me how may I understand this program step by step
Thanks again and again
 
Where did you get that code from.... Why don't you stick to the code I sent you... Its for a 32 bit number... If I show you 4x8 multiplication so you can see why it works... It should help you

lets take 4 x 5 = 20:-

Multiplicand = 0100 (4)
Multiplier = 0101 (5)

Register = 00000 (0)

First we check the lsb of the multiplier (5)
We see that it is a 1. ( An add condition ).. So we put the multiplicand (4) into a register

Register = 4..

Secondly, we shift the multiplier right >> one position WHILE we shift the multiplicand left << one position.

Multiplicand = 01000 (8)
Multiplier = 0010 (2)

Register still =4

We now test the lsb again and see a 0. (A no add condition)
But we still shift..

Multiplicand 010000 (16)
Multiplier 0001 (1)

Now we test again.. The lbs is 1 (An add condition ). Add the now 16 to the original 4. so:- Register = 20

Shift for the last time..

Multiplicand = 010000 (32)
Multiplier = 0000 (0)

Register = 010100 (20)

All four shifted 4 x 5 = 20 Its the same code as you have but yours is bigger... Then the code I posted is twice as big...
 
the author doesn't seem to know the difference between dividing and dividing.

You don't seem to know the difference between oversampling and averaging. With your logic I could just add four 10 bit samples and expect the result to be 12 bit.. it just does not work that way.

If I add six 10 bit samples and divide by 6, I'll get a 10 bit result. If I repeat this four times and add the averaged results, I have added four 10 bit results together.. therefore increasing the resolution by 1 bit. At the end I have a sum of 24 results divided by 6. And the effective resolution has increased by 1 bit. The result may look like a 12 bit result, but the LSB should be considered as noise.
 
The result may look like a 12 bit result, but the LSB should be considered as noise.

Of course it is..... When working on paper 6 samples that read 245 = 1470... Where as in reality.. The six samples would be from 243 to 257 depending on the noise and weather... This is how we get our precision.

As I said in theory t's all good.... Then you have to take it into the world.... Not quite the same...
 
Dear Roger,
Thanks for the reply
I git it from Nigel tutorials
This routine downloaded from http://www.piclist.com in the Nigel Tutorials

First we check the lsb of the multiplier (5)
We see that it is a 1. ( An add condition ).. So we put the multiplicand (4) into a register

Can you please give me a link study above which is how may i decided if lsb is one, as a an add condition

Please advice




You don't seem to know the difference between oversampling and averaging
.

Dear Mister T, I did got get the above. Can you please explain
 
The routine I used rotates the result instead of the multiplicand... Same difference!!!

Code:
MULTI	clrf    res4		;
	clrf	res3		;
	clrf    res2		; Ready the Reult
	movlw	0x80		; Set finish flag ( there will be 24 bits )
	movwf	res1		
 
nextbit
	rrf	a2,f		; Shift Multiplier >> once
	rrf	a1,f		;
 
	btfss	STATUS,C	; Was the LSBit a one?
	goto	nobit_l		; No it wasn't!! Go to no bit
	movf	b1,w		; Yes it was!! 
	addwf	res2,f		; Add Multiplicand B to Result
 
	movf	b2, w		;
	btfsc	STATUS,C	; Standard Interger add
	incfsz	b2, w		;
	addwf	res3, f		; Routine
	btfsc	STATUS,C	;
	incf	res4, f		;
	bcf	STATUS,C	;	
nobit_l	
	btfss	a1, 7		; Test if the b2 carried
	goto	nobit_h		; Nope!!
	movf	b1,w
	addwf	res3,f		; Add Multiplicand to Result
	movf	b2, w		; 
	btfsc	STATUS,C	; 
	incfsz	b2, w		;
	addwf	res4, f		;
 
nobit_h
	rrf	res4,f		; Rotate
	rrf	res3,f		; Result
	rrf	res2,f		;
	rrf	res1,f		;
 
	btfss	STATUS,C	; wait for Finish flag
	goto	nextbit		; continue with next bit

The difference between the two techniques are not a problem.
 
Dear Rogers,

Thank you so much for reply
Now I need to start from the ground
Therefore before go to the advance, I would like to start 4x4 maths

Can you please advice from this location


I found this from pic list

Code:
; 4x4 bit multiply
; by Ray Gardiner
       ;  X*Y ; result left in W
       ;  X and Y are 4 bits
       ;
       ;
       CLRW            ; Clear Result
       CLRC            ; Clear Carry for RLF later                     ;
       BTFSC   Y,0     ; ?*1
       ADDWF   X,W     ; W = ?X
       RLF     X,F     ; X = 2X
                       ;
       BTFSC   Y,1     ; ?*2
       ADDWF   X,W     ; W = ?X + ?2X
       RLF     X,F     ; W = 4X

       BTFSC   Y,2     ; ?*4
       ADDWF   X,W     ; W = ?X + ?2X + ?4X
       RLF     X,F     ; W = 8X

       BTFSC   Y,3     ; ?*8
       ADDWF   X,W     ; ?X + ?2X + ?4X + ?8X
       ;;;;;;;;;;;;;;;;;;;;;;;;;

       13 cycles result in W  13 bytes of code space

In the actual scenario

0011 ; decimal 3
0011 ; decimal 3

0011
0011
----------
1001

So what I need is what is the relation ship ADDWF and RLF in the above program to achieve the result

Please advice
Thanks in advance
 
No... Please stop changing code.... The reason this is different is because he is testing bit by bit ... Its the same as before but because there are only four bits he isn't rotating the multiplier.

I'll do the sum above bit by bit.

first bit
0011
0011 --> lsb is high

0011 into result

second bit
0110
0011

....|____ second bit is high so add 0110

add 0110 to 0011 in result

result = 1001

third bit
1100
0011

..|____ Third bit is low so no add..

Fourth bit

1000
0011

|_____ Fourth bit is low so no add

1001 is the result....
 
Dear Rogers,
Thanks for the reply

I can understand you explanation, Still my doubt is , why ADD and why RLF, What is the reason

It would be much appreciated, if you can explain it
Thanks in advance
 
Last edited:
MPU's mainly cannot multiply ( at least not 16 or 32 bit ) In binary the shift (rlf... rotate right though carry) and add commands can multiply large numbers ie.. 16. 24 and 32 bits quite easily.

Yes It is correct agreed

So what I need to clearly understand is The relation ship amoung


----11
----11
-----------
--11
-11
----------
1001
=====

can you please explain ADD and RLF how use for above in the micro controller

I think you will understand what I need is
Thanks in advance
 
I don't understand what you don't understand.... I must be expressing it incorrectly...

here is a binary number in the sum register ... Lets say 0xAA

10101010 The carry is zero....... so " RLF sum,f " sum will now contain 01010100.. and the 7th bit that disappeared will now be in the carry... a 1

RRF does the opposite

10101010 The carry is zero....... so " RRF sum,f " sum will now contain 01010101.. and the 1st bit that disappeared will now be in the carry...a 0

rlf is the same as * by two....

We use that function to multiply in the examples....Google binary maths for some examples
 
Dear Rogers,
Thank you so much for the help and advice

I followed following multiplication method which is 4 bit and now I can develop it up to 8bit multiplication
I practiced it using MACRO TOO

Can you please advice me what are the other methods that I need to follow for multiplication
Can I have first multification 4 bit method
Thanks in advance

Codes I practiced

Code:
 4x4 bit multiply
; by Ray Gardiner
       ;  X*Y ; result left in W
       ;  X and Y are 4 bits
       ;
       ;
       CLRW            ; Clear Result
       CLRC            ; Clear Carry for RLF later                     ;
       BTFSC   Y,0     ; ?*1
       ADDWF   X,W     ; W = ?X
       RLF     X,F     ; X = 2X
                       ;
       BTFSC   Y,1     ; ?*2
       ADDWF   X,W     ; W = ?X + ?2X
       RLF     X,F     ; W = 4X
 
       BTFSC   Y,2     ; ?*4
       ADDWF   X,W     ; W = ?X + ?2X + ?4X
       RLF     X,F     ; W = 8X
 
       BTFSC   Y,3     ; ?*8
       ADDWF   X,W     ; ?X + ?2X + ?4X + ?8X
       ;;;;;;;;;;;;;;;;;;;;;;;;;
 
       13 cycles result in W  13 bytes of code space
 
MPU's mainly cannot multiply ( at least not 16 or 32 bit ) In binary the shift (rlf... rotate right though carry) and add commands can multiply large numbers ie.. 16. 24 and 32 bits quite easily.

Dear Rogers,

You mean, it does not have any hardware for multiplication
 
Exactly, most CPU's don't.

Dear Nigel thanks for the reply,

Most MCU mean, like 16f877a really don't have
But I heard some MCU have But it is not real multiplication, it is doing internally rotate and add ( I am not sure )

Please advice
thanks in advance
 
You don't seem to know the difference between oversampling and averaging. With your logic I could just add four 10 bit samples and expect the result to be 12 bit.. it just does not work that way.
You're a bit off there and you've obviously misread the meaning of my posts? Adding four 10 bit samples gives you 11 bits of information taking up at most 12 bits of space. Divide by two for the 11 bits. Divide by 4 for 10 bits. The latter is the sample average (biased downwards).

If I add six 10 bit samples and divide by 6, I'll get a 10 bit result. If I repeat this four times and add the averaged results, I have added four 10 bit results together.. therefore increasing the resolution by 1 bit. At the end I have a sum of 24 results divided by 6. And the effective resolution has increased by 1 bit. The result may look like a 12 bit result, but the LSB should be considered as noise.
Your logic is wrong. There is a difference between performing the integer math 6 * 10bit / 6 * 4 (what you've described at the start of the quote) and 24 * 10bit / 6 (what you've described after). If your math is not integer, i.e. real, then both give the same result.
 
Dear Nigel thanks for the reply,

Most MCU mean, like 16f877a really don't have
But I heard some MCU have But it is not real multiplication, it is doing internally rotate and add ( I am not sure )

Please advice
thanks in advance

The pic18 series have hardware 8x8 multiply... The 8051 has 8x8 hardware multiply... But if you want 16x16 you would have to mess about with the hardware multiply to get your results... It would be easier to just use the routine that I posted.... I have tested it, It does work...

The division is supposed to be rlf 10 times this is a divide by 1024... However.. Rlf twice and forget the LSByte is the same thing....

The hitchi 500 and 300 series of MPU have hadware 32 bit multiply and divide... But that's a 16 bit chip...
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top