Home     Contact     Projects     Experiments     Circuits     Theory     BLOG     PIC Tutorials     Time for Science     RSS     Terms of services     Privacy policy  
   
 Home      Projects     Experiments     Circuits     Theory     BLOG     PIC Tutorials     Time for Science   



All about PIC microcontrollers

Within these pages, you can find many useful pieces of code mostly in assembly for the Microchip PIC micro controller family. A lot of people have spend many hours trying to put the bits and bytes together. If the code is NOT written by a member of the PCB Heaven community, then a link will be added above the code with the original website that this code was found.
Because the code is copied to our servers, you should know that:

  • The responsible web master of the website that the code is taken, has been informed and he has agreed to copy the code
  • All emails from the above contact have been kept as records but due to personal privacy cannot be shown in public.
  • The author of the code is always clearly indicated above the code. In some cases the author is unknown. If you happen to be the author of the code or you know the person who wrote it, please inform us by email and it will be added ASAP.

We would personally like to send the credits to all the people that managed to write some very interesting code and publish it, and special thanx to the people that originally hosted those code snippets and gave us the permission to copy them.


View code
24bit X 24bit
Author: Fred Maher
This code was originally located @ http://www.piclist.com


Follow this link to go back

LIST P=16F628 ; 16F628 Runs at 20 MHz
INCLUDE "p16F628.inc"

__CONFIG _CP_OFF & _WDT_OFF & _HS_OSC & _PWRTE_ON & _LVP_OFF & _BODEN_OFF

ERRORLEVEL -224 ; suppress annoying message because of tris
ERRORLEVEL -302 ; suppress message because of page change

CBLOCK 20H

top1
top2
top3
top4
top5
top6
bot1
bot2
bot3
res1
res2
res3
res4
res5
res6
count
temp
c1
c2
ENDC

; Top and bottom registers are not symetrical. The bottom registers will never need to
; handle more than 24 bits. The top registers can, when the numbers are near the maximum,
; have to handle 48 bits due to left shifting. Now we can reuse registers but it makes
; following these "tutor" multiply routines harder to follow.

;There is no ORG, ISR, as this is a sub routine of a main program. However we
;want it to behave like a program to debug and emulate it running with real number inputs.
;When it is all working we remove ;the header and place the variables with the rest of
;the variables of the existing main ;program code.
;So we can start by putting values into the top and bottom, values that will not cause
;overflow in the result.

;Example numbers :top 00FFFF bot 000024 txb = 23FFDC(inside 24 bit limit)decimal = 2,359,260

Testnums:
movlw 0x0B
movwf top1
movlw 0x00
movwf top2
movlw 0x00
movwf top3
movlw 0x00
movwf top4
movlw 0x00
movwf top5
movlw 0x00
movwf top6

movlw 0xBA
movwf bot1
movlw 0xDC
movwf bot2
movlw 0xFE
movwf bot3
clrf res1
clrf res2
clrf res3
clrf res4
clrf res5
clrf res6

; In example top x bot = B044 F100
; we will use top as multiplicand and bot as the multiplier Note:- the smaller number is as we
; discussed in the multiplier, bottom.

; A word about the code we are going to write. The shifts and the checks produce a lot of trees
;making it easy to lose sight of the main actions. These are.
; THE MULTIPLY SEQUENCE
;----------------------

;Step 1. Use bot bit 0 to decide if we add tops to reses or to skip directly to 4.
;
;Step 2. Add the rotated left 3top to 3res if bot bit not 0, else skip add.
; Please note, the First Time as there is no shifting,
; add directly all the top bits to result. If the first ( rightmost digit of the
;bot.. multiplier ) had been zero and not four then we skip the add and move on
;to the next action. ( bot bit tells us when to skip the add)
;Step 2 actions:. The addition of res and top
; top1 add to res1, carry flag? yes, add 1 to res2 , clear carry flag
; top2 add to res2, carry flag? yes, add 1 to res3 , clear carry flag
; top3 add to res3 , carry flag? yes,
;
;Step 3. Rotate left the three top registers and check overflows in this sequence...
; top1 rotate left, carry flag? yes, add 1 to top2 , clear carry flag
; top2 rotate left, carry flag? yes, add 1 to top3 , clear carry flag
; top3 rotate left, carry flag? yes,
; not this time ---> "add 1 to top4, clear carry flag"<--
;
;Step 4. Bot,bit0( value 1 or 0 )decides if we add or don't add so we need to
; right shift the three bots or read a bit in the corresponding register
; using the loop counter count. This counter would loop from 1 to 24 and
;needs checks ;to move from bot1 reg to bot2 reg then to bot3 reg.
;This first attempt will use the same actions as 3. and 4. So we have after 1st read
;bot1 rotate right, Carry flag? yes , clear carry flag
;bot2 rotate right, Carry flag? yes add b'1000000' = hex80 to bot1 , clear carry flag
;bot3 rotate right, Carry flag? yes add b'1000000' = hex80 to bot2 , clear carry flag

; These are the four steps explained in words....

; The execution time of the multiplication can be quickened considerably if
; we know when the multiplier has finished.
; e.g. look at bot3, bot2, bot1 00 00 24 = 00000000 00000000 0010 0100
; now after five shifts right what remains are zeros.
; So calculation finished at count 6, in 243 cycles; yet we continue
; until we reach count 24, which takes 836 cycles
; What we need to add is a top bottom swap, and detect bot_first_1 for count needed
; routine, to optimize the 24x24 multiply a little more.

;-----------------------------------------------------------------------
; Mult24 is the main mult routine start point
;------------------------------------------------------------------------

Mult24: ;

bcf STATUS,DC
call Regcomp ; Puts smaller number into multiplier and finds count minimum.
nop
incf count,f
clrf res1 ; may have been used for storage in swap
clrf res2
clrf res3
call X24 ; main 24 x 24 mult


Mult24end: ; here back to principal program
goto Mult24end ; dummy loop for testing
; return ; back to main program
;--------------------------------------------------------------------------
; End of multiply 24 x 24 ; out 48, routine
;--------------------------------------------------------------------------

Regcomp: ; compare top and bot regs 3 2 1 to decide if we need to swap.

bcf STATUS,2
bcf STATUS,1
bcf STATUS,0

; These blocks test for:- "0 "... "="... ">" ... using STATUS flags

Test33:
movf bot3,w
subwf top3,w
btfsc STATUS,C ;
goto $+ 3 ; top is equal or bigger
call Swap
goto Leftbit ; find leftmost 1 for count.
; end case top>bot

; Think carefully about this bit. We get here because bot is
; equal or less than top. So we test top for zero, then if zero
; bot is also zero because we have no negative numbers
; (e.g. bot can't be -7)
; if STATUS not zero bot is less than top, then find
; leftmost "1" for count.

clrw ; test top=0 (if top=0 then bot=0 (can't be minus))
xorwf top3,w
btfsc STATUS,Z
goto Test22 ; both zero, continue test with top2,bot2
goto Leftbit
Test22:
movf bot2,w
subwf top2,w
btfsc STATUS,C ;
goto $+ 3 ; top is equal or bigger
call Swap
goto Leftbit ; find leftmost 1 for count.
; end case top>bot
clrw ; test top=0 (if top=0 then bot=0 (can't be minus))
xorwf top2,w
btfsc STATUS,Z
goto Test11 ; both zero, continue test with top2,bot2
goto Leftbit
Test11:
movf bot1,w
subwf top1,w
btfsc STATUS,C ;
goto $+ 3 ; top is equal or bigger
call Swap
goto Leftbit ; find leftmost 1 for count.
; end case top>bot
clrw ; test top=0 (if top=0 then bot=0 (can't be minus))
xorwf top1,w
btfsc STATUS,Z
goto Test11 ; both zero, continue test with top2,bot2
movf bot1,w ;put bot in temp
movwf temp
movlw d'08' ; bot is smaller so set count to 24
movwf count ; do Leftbit
goto Leftbit
Swap:
movf top3,w
movwf res3
movf bot3,w
movwf top3
movf res3,w
movwf bot3
movf top2,w
movwf res2
movf bot2,w
movwf top2
movf res2,w
movwf bot2
movf top1,w
movwf res1
movf bot1,w
movwf top1
movf res1,w
movwf bot1
return

Leftbit:
;Now find in bot3,2,1 that which is not zero, find leftmost ONE
; We leave the routine with count holding the minimum necessary number
;for the multiplier adds and with multiplier as bot, the smaller number
clrw
xorwf bot3,w
btfsc STATUS, Z
goto $+6
movf bot3,w
movwf temp
movlw d'24'
movwf count
goto Oneloop

clrw
xorwf bot2,w
btfsc STATUS, Z
goto $+6
movf bot2,w
movwf temp
movlw d'16'
movwf count
goto Oneloop

clrw
xorwf bot1,w
btfsc STATUS, Z
goto $+4
movf bot1,w
movwf temp
movlw d'08'
movwf count
goto Oneloop

Oneloop: ; We move through the 8 bits of temp from 8 to 1
btfsc temp,7
return
decf count,f
rlf temp,f
goto Oneloop
return ; to main mult


;----------------------------------------------------------------
; End of the compare / count routine
;----------------------------------------------------------------


X24: ; mult loop proper starts here with entered values

Step1: ; To add or not to add? that is the question.

btfss bot1,0
goto Step3 ; 0... don't add top to res
goto Step2 ; 1... add top to res

Step2: ; Adding top to res

movfw top1
addwf res1,f

movfw top2
skpnc
incfsz top2,w
addwf res2,f

movfw top3
skpnc
incfsz top3,w
addwf res3,f

movfw top4
skpnc
incfsz top4,w
addwf res4,f

movfw top5
skpnc
incfsz top5,w
addwf res5,f

movfw top6
skpnc
incfsz top6,w
addwf res6,f

Step3: ; Left shifting top
; This looks the same as an add but it is different, when we shift
; we never sum, but rather drop the carried 1 into a space vacated
; So we start with top6, check C,; top5 check C,.....; top1 check C


bcf STATUS,C
rlf top6,f
btfsc STATUS,C
nop ;incf top4,f

bcf STATUS,C
rlf top5,f
btfsc STATUS,C
incf top6,f

bcf STATUS,C
rlf top4,f
btfsc STATUS,C
incf top5,f

bcf STATUS,C
rlf top3,f
btfsc STATUS,C
incf top4,f

bcf STATUS,C
rlf top2,f
btfsc STATUS,C
incf top3,f

bcf STATUS,C
rlf top1,f
btfsc STATUS,C
incf top2,f
bcf STATUS,C
Stepend:
nop

Step4: ;Right shifting bottom and terminate loop for count = MAX, here 24.

decf count,f ; we start with count =24 OR speeded up count

clrw
xorwf count,w
btfsc STATUS,Z
RETURN ; count finished
; count not finished, continue Step4

rrf bot1,f
bcf STATUS,C

rrf bot2,f
btfss STATUS,C
goto $ + 4 ; there was no carry, jump forward 4
movlw 0x80
addwf bot1,f
bcf STATUS,C

rrf bot3,f
btfss STATUS,C
goto $ + 4 ; there was no carry, jump forward 4
movlw 0x80
addwf bot2,f
bcf STATUS,C

goto Step1
;---------------------------------------------------------------------
; End of reg multiplication
;---------------------------------------------------------------------




end ;not used when this is a subroutine
;------------------------------------------------------------------
; End Mult 24 x 24
;------------------------------------------------------------------

Follow this link to go back






delicious
digg
reddit this Reddit this
Faves



 HOT in heaven!